ActivityManagerService.java revision 41aa48beacc93a1511a290e91293402eeb787165
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;
27import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
28
29import android.app.AppOpsManager;
30import android.app.IActivityContainer;
31import android.app.IActivityContainerCallback;
32import android.appwidget.AppWidgetManager;
33import android.graphics.Rect;
34import android.util.ArrayMap;
35
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.os.Zygote;
46import com.android.internal.util.FastPrintWriter;
47import com.android.internal.util.FastXmlSerializer;
48import com.android.internal.util.MemInfoReader;
49import com.android.internal.util.Preconditions;
50import com.android.server.AppOpsService;
51import com.android.server.AttributeCache;
52import com.android.server.IntentResolver;
53import com.android.server.LocalServices;
54import com.android.server.ServiceThread;
55import com.android.server.SystemService;
56import com.android.server.Watchdog;
57import com.android.server.am.ActivityStack.ActivityState;
58import com.android.server.firewall.IntentFirewall;
59import com.android.server.pm.UserManagerService;
60import com.android.server.wm.AppTransition;
61import com.android.server.wm.WindowManagerService;
62import com.google.android.collect.Lists;
63import com.google.android.collect.Maps;
64
65import libcore.io.IoUtils;
66
67import org.xmlpull.v1.XmlPullParser;
68import org.xmlpull.v1.XmlPullParserException;
69import org.xmlpull.v1.XmlSerializer;
70
71import android.app.Activity;
72import android.app.ActivityManager;
73import android.app.ActivityManager.RunningTaskInfo;
74import android.app.ActivityManager.StackInfo;
75import android.app.ActivityManagerInternal;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.ApplicationErrorReport;
82import android.app.Dialog;
83import android.app.IActivityController;
84import android.app.IApplicationThread;
85import android.app.IInstrumentationWatcher;
86import android.app.INotificationManager;
87import android.app.IProcessObserver;
88import android.app.IServiceConnection;
89import android.app.IStopUserCallback;
90import android.app.IThumbnailReceiver;
91import android.app.IUiAutomationConnection;
92import android.app.IUserSwitchObserver;
93import android.app.Instrumentation;
94import android.app.Notification;
95import android.app.NotificationManager;
96import android.app.PendingIntent;
97import android.app.backup.IBackupManager;
98import android.content.ActivityNotFoundException;
99import android.content.BroadcastReceiver;
100import android.content.ClipData;
101import android.content.ComponentCallbacks2;
102import android.content.ComponentName;
103import android.content.ContentProvider;
104import android.content.ContentResolver;
105import android.content.Context;
106import android.content.DialogInterface;
107import android.content.IContentProvider;
108import android.content.IIntentReceiver;
109import android.content.IIntentSender;
110import android.content.Intent;
111import android.content.IntentFilter;
112import android.content.IntentSender;
113import android.content.pm.ActivityInfo;
114import android.content.pm.ApplicationInfo;
115import android.content.pm.ConfigurationInfo;
116import android.content.pm.IPackageDataObserver;
117import android.content.pm.IPackageManager;
118import android.content.pm.InstrumentationInfo;
119import android.content.pm.PackageInfo;
120import android.content.pm.PackageManager;
121import android.content.pm.ParceledListSlice;
122import android.content.pm.UserInfo;
123import android.content.pm.PackageManager.NameNotFoundException;
124import android.content.pm.PathPermission;
125import android.content.pm.ProviderInfo;
126import android.content.pm.ResolveInfo;
127import android.content.pm.ServiceInfo;
128import android.content.res.CompatibilityInfo;
129import android.content.res.Configuration;
130import android.graphics.Bitmap;
131import android.net.Proxy;
132import android.net.ProxyProperties;
133import android.net.Uri;
134import android.os.Binder;
135import android.os.Build;
136import android.os.Bundle;
137import android.os.Debug;
138import android.os.DropBoxManager;
139import android.os.Environment;
140import android.os.FactoryTest;
141import android.os.FileObserver;
142import android.os.FileUtils;
143import android.os.Handler;
144import android.os.IBinder;
145import android.os.IPermissionController;
146import android.os.IRemoteCallback;
147import android.os.IUserManager;
148import android.os.Looper;
149import android.os.Message;
150import android.os.Parcel;
151import android.os.ParcelFileDescriptor;
152import android.os.Process;
153import android.os.RemoteCallbackList;
154import android.os.RemoteException;
155import android.os.SELinux;
156import android.os.ServiceManager;
157import android.os.StrictMode;
158import android.os.SystemClock;
159import android.os.SystemProperties;
160import android.os.UpdateLock;
161import android.os.UserHandle;
162import android.provider.Settings;
163import android.text.format.DateUtils;
164import android.text.format.Time;
165import android.util.AtomicFile;
166import android.util.EventLog;
167import android.util.Log;
168import android.util.Pair;
169import android.util.PrintWriterPrinter;
170import android.util.Slog;
171import android.util.SparseArray;
172import android.util.TimeUtils;
173import android.util.Xml;
174import android.view.Gravity;
175import android.view.LayoutInflater;
176import android.view.View;
177import android.view.WindowManager;
178
179import java.io.BufferedInputStream;
180import java.io.BufferedOutputStream;
181import java.io.DataInputStream;
182import java.io.DataOutputStream;
183import java.io.File;
184import java.io.FileDescriptor;
185import java.io.FileInputStream;
186import java.io.FileNotFoundException;
187import java.io.FileOutputStream;
188import java.io.IOException;
189import java.io.InputStreamReader;
190import java.io.PrintWriter;
191import java.io.StringWriter;
192import java.lang.ref.WeakReference;
193import java.util.ArrayList;
194import java.util.Arrays;
195import java.util.Collections;
196import java.util.Comparator;
197import java.util.HashMap;
198import java.util.HashSet;
199import java.util.Iterator;
200import java.util.List;
201import java.util.Locale;
202import java.util.Map;
203import java.util.Set;
204import java.util.concurrent.atomic.AtomicBoolean;
205import java.util.concurrent.atomic.AtomicLong;
206
207public final class ActivityManagerService extends ActivityManagerNative
208        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
209    private static final String USER_DATA_DIR = "/data/user/";
210    static final String TAG = "ActivityManager";
211    static final String TAG_MU = "ActivityManagerServiceMU";
212    static final boolean DEBUG = false;
213    static final boolean localLOGV = DEBUG;
214    static final boolean DEBUG_BACKUP = localLOGV || false;
215    static final boolean DEBUG_BROADCAST = localLOGV || false;
216    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
217    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
218    static final boolean DEBUG_CLEANUP = localLOGV || false;
219    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
220    static final boolean DEBUG_FOCUS = false;
221    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
222    static final boolean DEBUG_MU = localLOGV || false;
223    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
224    static final boolean DEBUG_LRU = localLOGV || false;
225    static final boolean DEBUG_PAUSE = localLOGV || false;
226    static final boolean DEBUG_POWER = localLOGV || false;
227    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
228    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
229    static final boolean DEBUG_PROCESSES = localLOGV || false;
230    static final boolean DEBUG_PROVIDER = localLOGV || false;
231    static final boolean DEBUG_RESULTS = localLOGV || false;
232    static final boolean DEBUG_SERVICE = localLOGV || false;
233    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
234    static final boolean DEBUG_STACK = localLOGV || false;
235    static final boolean DEBUG_SWITCH = localLOGV || false;
236    static final boolean DEBUG_TASKS = localLOGV || false;
237    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
238    static final boolean DEBUG_TRANSITION = localLOGV || false;
239    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
240    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
241    static final boolean DEBUG_VISBILITY = localLOGV || false;
242    static final boolean DEBUG_PSS = localLOGV || false;
243    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
244    static final boolean VALIDATE_TOKENS = false;
245    static final boolean SHOW_ACTIVITY_START_TIME = true;
246
247    // Control over CPU and battery monitoring.
248    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
249    static final boolean MONITOR_CPU_USAGE = true;
250    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
251    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
252    static final boolean MONITOR_THREAD_CPU_USAGE = false;
253
254    // The flags that are set for all calls we make to the package manager.
255    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
256
257    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
258
259    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
260
261    // Maximum number of recent tasks that we can remember.
262    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
263
264    // Amount of time after a call to stopAppSwitches() during which we will
265    // prevent further untrusted switches from happening.
266    static final long APP_SWITCH_DELAY_TIME = 5*1000;
267
268    // How long we wait for a launched process to attach to the activity manager
269    // before we decide it's never going to come up for real.
270    static final int PROC_START_TIMEOUT = 10*1000;
271
272    // How long we wait for a launched process to attach to the activity manager
273    // before we decide it's never going to come up for real, when the process was
274    // started with a wrapper for instrumentation (such as Valgrind) because it
275    // could take much longer than usual.
276    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
277
278    // How long to wait after going idle before forcing apps to GC.
279    static final int GC_TIMEOUT = 5*1000;
280
281    // The minimum amount of time between successive GC requests for a process.
282    static final int GC_MIN_INTERVAL = 60*1000;
283
284    // The minimum amount of time between successive PSS requests for a process.
285    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
286
287    // The minimum amount of time between successive PSS requests for a process
288    // when the request is due to the memory state being lowered.
289    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
290
291    // The rate at which we check for apps using excessive power -- 15 mins.
292    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
293
294    // The minimum sample duration we will allow before deciding we have
295    // enough data on wake locks to start killing things.
296    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
297
298    // The minimum sample duration we will allow before deciding we have
299    // enough data on CPU usage to start killing things.
300    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
301
302    // How long we allow a receiver to run before giving up on it.
303    static final int BROADCAST_FG_TIMEOUT = 10*1000;
304    static final int BROADCAST_BG_TIMEOUT = 60*1000;
305
306    // How long we wait until we timeout on key dispatching.
307    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
308
309    // How long we wait until we timeout on key dispatching during instrumentation.
310    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
311
312    // Amount of time we wait for observers to handle a user switch before
313    // giving up on them and unfreezing the screen.
314    static final int USER_SWITCH_TIMEOUT = 2*1000;
315
316    // Maximum number of users we allow to be running at a time.
317    static final int MAX_RUNNING_USERS = 3;
318
319    // How long to wait in getAssistContextExtras for the activity and foreground services
320    // to respond with the result.
321    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
322
323    // Maximum number of persisted Uri grants a package is allowed
324    static final int MAX_PERSISTED_URI_GRANTS = 128;
325
326    static final int MY_PID = Process.myPid();
327
328    static final String[] EMPTY_STRING_ARRAY = new String[0];
329
330    // How many bytes to write into the dropbox log before truncating
331    static final int DROPBOX_MAX_SIZE = 256 * 1024;
332
333    /** Run all ActivityStacks through this */
334    ActivityStackSupervisor mStackSupervisor;
335
336    public IntentFirewall mIntentFirewall;
337
338    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
339    // default actuion automatically.  Important for devices without direct input
340    // devices.
341    private boolean mShowDialogs = true;
342
343    /**
344     * Description of a request to start a new activity, which has been held
345     * due to app switches being disabled.
346     */
347    static class PendingActivityLaunch {
348        final ActivityRecord r;
349        final ActivityRecord sourceRecord;
350        final int startFlags;
351        final ActivityStack stack;
352
353        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
354                int _startFlags, ActivityStack _stack) {
355            r = _r;
356            sourceRecord = _sourceRecord;
357            startFlags = _startFlags;
358            stack = _stack;
359        }
360    }
361
362    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
363            = new ArrayList<PendingActivityLaunch>();
364
365    BroadcastQueue mFgBroadcastQueue;
366    BroadcastQueue mBgBroadcastQueue;
367    // Convenient for easy iteration over the queues. Foreground is first
368    // so that dispatch of foreground broadcasts gets precedence.
369    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
370
371    BroadcastQueue broadcastQueueForIntent(Intent intent) {
372        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
373        if (DEBUG_BACKGROUND_BROADCAST) {
374            Slog.i(TAG, "Broadcast intent " + intent + " on "
375                    + (isFg ? "foreground" : "background")
376                    + " queue");
377        }
378        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
379    }
380
381    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
382        for (BroadcastQueue queue : mBroadcastQueues) {
383            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
384            if (r != null) {
385                return r;
386            }
387        }
388        return null;
389    }
390
391    /**
392     * Activity we have told the window manager to have key focus.
393     */
394    ActivityRecord mFocusedActivity = null;
395
396    /**
397     * List of intents that were used to start the most recent tasks.
398     */
399    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
400
401    public class PendingAssistExtras extends Binder implements Runnable {
402        public final ActivityRecord activity;
403        public boolean haveResult = false;
404        public Bundle result = null;
405        public PendingAssistExtras(ActivityRecord _activity) {
406            activity = _activity;
407        }
408        @Override
409        public void run() {
410            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
411            synchronized (this) {
412                haveResult = true;
413                notifyAll();
414            }
415        }
416    }
417
418    final ArrayList<PendingAssistExtras> mPendingAssistExtras
419            = new ArrayList<PendingAssistExtras>();
420
421    /**
422     * Process management.
423     */
424    final ProcessList mProcessList = new ProcessList();
425
426    /**
427     * All of the applications we currently have running organized by name.
428     * The keys are strings of the application package name (as
429     * returned by the package manager), and the keys are ApplicationRecord
430     * objects.
431     */
432    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
433
434    /**
435     * Tracking long-term execution of processes to look for abuse and other
436     * bad app behavior.
437     */
438    final ProcessStatsService mProcessStats;
439
440    /**
441     * The currently running isolated processes.
442     */
443    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
444
445    /**
446     * Counter for assigning isolated process uids, to avoid frequently reusing the
447     * same ones.
448     */
449    int mNextIsolatedProcessUid = 0;
450
451    /**
452     * The currently running heavy-weight process, if any.
453     */
454    ProcessRecord mHeavyWeightProcess = null;
455
456    /**
457     * The last time that various processes have crashed.
458     */
459    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
460
461    /**
462     * Information about a process that is currently marked as bad.
463     */
464    static final class BadProcessInfo {
465        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
466            this.time = time;
467            this.shortMsg = shortMsg;
468            this.longMsg = longMsg;
469            this.stack = stack;
470        }
471
472        final long time;
473        final String shortMsg;
474        final String longMsg;
475        final String stack;
476    }
477
478    /**
479     * Set of applications that we consider to be bad, and will reject
480     * incoming broadcasts from (which the user has no control over).
481     * Processes are added to this set when they have crashed twice within
482     * a minimum amount of time; they are removed from it when they are
483     * later restarted (hopefully due to some user action).  The value is the
484     * time it was added to the list.
485     */
486    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
487
488    /**
489     * All of the processes we currently have running organized by pid.
490     * The keys are the pid running the application.
491     *
492     * <p>NOTE: This object is protected by its own lock, NOT the global
493     * activity manager lock!
494     */
495    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
496
497    /**
498     * All of the processes that have been forced to be foreground.  The key
499     * is the pid of the caller who requested it (we hold a death
500     * link on it).
501     */
502    abstract class ForegroundToken implements IBinder.DeathRecipient {
503        int pid;
504        IBinder token;
505    }
506    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
507
508    /**
509     * List of records for processes that someone had tried to start before the
510     * system was ready.  We don't start them at that point, but ensure they
511     * are started by the time booting is complete.
512     */
513    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
514
515    /**
516     * List of persistent applications that are in the process
517     * of being started.
518     */
519    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
520
521    /**
522     * Processes that are being forcibly torn down.
523     */
524    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
525
526    /**
527     * List of running applications, sorted by recent usage.
528     * The first entry in the list is the least recently used.
529     */
530    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
531
532    /**
533     * Where in mLruProcesses that the processes hosting activities start.
534     */
535    int mLruProcessActivityStart = 0;
536
537    /**
538     * Where in mLruProcesses that the processes hosting services start.
539     * This is after (lower index) than mLruProcessesActivityStart.
540     */
541    int mLruProcessServiceStart = 0;
542
543    /**
544     * List of processes that should gc as soon as things are idle.
545     */
546    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
547
548    /**
549     * Processes we want to collect PSS data from.
550     */
551    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
552
553    /**
554     * Last time we requested PSS data of all processes.
555     */
556    long mLastFullPssTime = SystemClock.uptimeMillis();
557
558    /**
559     * This is the process holding what we currently consider to be
560     * the "home" activity.
561     */
562    ProcessRecord mHomeProcess;
563
564    /**
565     * This is the process holding the activity the user last visited that
566     * is in a different process from the one they are currently in.
567     */
568    ProcessRecord mPreviousProcess;
569
570    /**
571     * The time at which the previous process was last visible.
572     */
573    long mPreviousProcessVisibleTime;
574
575    /**
576     * Which uses have been started, so are allowed to run code.
577     */
578    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
579
580    /**
581     * LRU list of history of current users.  Most recently current is at the end.
582     */
583    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
584
585    /**
586     * Constant array of the users that are currently started.
587     */
588    int[] mStartedUserArray = new int[] { 0 };
589
590    /**
591     * Registered observers of the user switching mechanics.
592     */
593    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
594            = new RemoteCallbackList<IUserSwitchObserver>();
595
596    /**
597     * Currently active user switch.
598     */
599    Object mCurUserSwitchCallback;
600
601    /**
602     * Packages that the user has asked to have run in screen size
603     * compatibility mode instead of filling the screen.
604     */
605    final CompatModePackages mCompatModePackages;
606
607    /**
608     * Set of IntentSenderRecord objects that are currently active.
609     */
610    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
611            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
612
613    /**
614     * Fingerprints (hashCode()) of stack traces that we've
615     * already logged DropBox entries for.  Guarded by itself.  If
616     * something (rogue user app) forces this over
617     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
618     */
619    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
620    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
621
622    /**
623     * Strict Mode background batched logging state.
624     *
625     * The string buffer is guarded by itself, and its lock is also
626     * used to determine if another batched write is already
627     * in-flight.
628     */
629    private final StringBuilder mStrictModeBuffer = new StringBuilder();
630
631    /**
632     * Keeps track of all IIntentReceivers that have been registered for
633     * broadcasts.  Hash keys are the receiver IBinder, hash value is
634     * a ReceiverList.
635     */
636    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
637            new HashMap<IBinder, ReceiverList>();
638
639    /**
640     * Resolver for broadcast intents to registered receivers.
641     * Holds BroadcastFilter (subclass of IntentFilter).
642     */
643    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
644            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
645        @Override
646        protected boolean allowFilterResult(
647                BroadcastFilter filter, List<BroadcastFilter> dest) {
648            IBinder target = filter.receiverList.receiver.asBinder();
649            for (int i=dest.size()-1; i>=0; i--) {
650                if (dest.get(i).receiverList.receiver.asBinder() == target) {
651                    return false;
652                }
653            }
654            return true;
655        }
656
657        @Override
658        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
659            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
660                    || userId == filter.owningUserId) {
661                return super.newResult(filter, match, userId);
662            }
663            return null;
664        }
665
666        @Override
667        protected BroadcastFilter[] newArray(int size) {
668            return new BroadcastFilter[size];
669        }
670
671        @Override
672        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
673            return packageName.equals(filter.packageName);
674        }
675    };
676
677    /**
678     * State of all active sticky broadcasts per user.  Keys are the action of the
679     * sticky Intent, values are an ArrayList of all broadcasted intents with
680     * that action (which should usually be one).  The SparseArray is keyed
681     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
682     * for stickies that are sent to all users.
683     */
684    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
685            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
686
687    final ActiveServices mServices;
688
689    /**
690     * Backup/restore process management
691     */
692    String mBackupAppName = null;
693    BackupRecord mBackupTarget = null;
694
695    /**
696     * List of PendingThumbnailsRecord objects of clients who are still
697     * waiting to receive all of the thumbnails for a task.
698     */
699    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
700            new ArrayList<PendingThumbnailsRecord>();
701
702    final ProviderMap mProviderMap;
703
704    /**
705     * List of content providers who have clients waiting for them.  The
706     * application is currently being launched and the provider will be
707     * removed from this list once it is published.
708     */
709    final ArrayList<ContentProviderRecord> mLaunchingProviders
710            = new ArrayList<ContentProviderRecord>();
711
712    /**
713     * File storing persisted {@link #mGrantedUriPermissions}.
714     */
715    private final AtomicFile mGrantFile;
716
717    /** XML constants used in {@link #mGrantFile} */
718    private static final String TAG_URI_GRANTS = "uri-grants";
719    private static final String TAG_URI_GRANT = "uri-grant";
720    private static final String ATTR_USER_HANDLE = "userHandle";
721    private static final String ATTR_SOURCE_PKG = "sourcePkg";
722    private static final String ATTR_TARGET_PKG = "targetPkg";
723    private static final String ATTR_URI = "uri";
724    private static final String ATTR_MODE_FLAGS = "modeFlags";
725    private static final String ATTR_CREATED_TIME = "createdTime";
726
727    /**
728     * Global set of specific {@link Uri} permissions that have been granted.
729     * This optimized lookup structure maps from {@link UriPermission#targetUid}
730     * to {@link UriPermission#uri} to {@link UriPermission}.
731     */
732    @GuardedBy("this")
733    private final SparseArray<ArrayMap<Uri, UriPermission>>
734            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
735
736    CoreSettingsObserver mCoreSettingsObserver;
737
738    /**
739     * Thread-local storage used to carry caller permissions over through
740     * indirect content-provider access.
741     */
742    private class Identity {
743        public int pid;
744        public int uid;
745
746        Identity(int _pid, int _uid) {
747            pid = _pid;
748            uid = _uid;
749        }
750    }
751
752    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
753
754    /**
755     * All information we have collected about the runtime performance of
756     * any user id that can impact battery performance.
757     */
758    final BatteryStatsService mBatteryStatsService;
759
760    /**
761     * Information about component usage
762     */
763    final UsageStatsService mUsageStatsService;
764
765    /**
766     * Information about and control over application operations
767     */
768    final AppOpsService mAppOpsService;
769
770    /**
771     * Current configuration information.  HistoryRecord objects are given
772     * a reference to this object to indicate which configuration they are
773     * currently running in, so this object must be kept immutable.
774     */
775    Configuration mConfiguration = new Configuration();
776
777    /**
778     * Current sequencing integer of the configuration, for skipping old
779     * configurations.
780     */
781    int mConfigurationSeq = 0;
782
783    /**
784     * Hardware-reported OpenGLES version.
785     */
786    final int GL_ES_VERSION;
787
788    /**
789     * List of initialization arguments to pass to all processes when binding applications to them.
790     * For example, references to the commonly used services.
791     */
792    HashMap<String, IBinder> mAppBindArgs;
793
794    /**
795     * Temporary to avoid allocations.  Protected by main lock.
796     */
797    final StringBuilder mStringBuilder = new StringBuilder(256);
798
799    /**
800     * Used to control how we initialize the service.
801     */
802    ComponentName mTopComponent;
803    String mTopAction = Intent.ACTION_MAIN;
804    String mTopData;
805    boolean mProcessesReady = false;
806    boolean mSystemReady = false;
807    boolean mBooting = false;
808    boolean mWaitingUpdate = false;
809    boolean mDidUpdate = false;
810    boolean mOnBattery = false;
811    boolean mLaunchWarningShown = false;
812
813    Context mContext;
814
815    int mFactoryTest;
816
817    boolean mCheckedForSetup;
818
819    /**
820     * The time at which we will allow normal application switches again,
821     * after a call to {@link #stopAppSwitches()}.
822     */
823    long mAppSwitchesAllowedTime;
824
825    /**
826     * This is set to true after the first switch after mAppSwitchesAllowedTime
827     * is set; any switches after that will clear the time.
828     */
829    boolean mDidAppSwitch;
830
831    /**
832     * Last time (in realtime) at which we checked for power usage.
833     */
834    long mLastPowerCheckRealtime;
835
836    /**
837     * Last time (in uptime) at which we checked for power usage.
838     */
839    long mLastPowerCheckUptime;
840
841    /**
842     * Set while we are wanting to sleep, to prevent any
843     * activities from being started/resumed.
844     */
845    boolean mSleeping = false;
846
847    /**
848     * State of external calls telling us if the device is asleep.
849     */
850    boolean mWentToSleep = false;
851
852    /**
853     * State of external call telling us if the lock screen is shown.
854     */
855    boolean mLockScreenShown = false;
856
857    /**
858     * Set if we are shutting down the system, similar to sleeping.
859     */
860    boolean mShuttingDown = false;
861
862    /**
863     * Current sequence id for oom_adj computation traversal.
864     */
865    int mAdjSeq = 0;
866
867    /**
868     * Current sequence id for process LRU updating.
869     */
870    int mLruSeq = 0;
871
872    /**
873     * Keep track of the non-cached/empty process we last found, to help
874     * determine how to distribute cached/empty processes next time.
875     */
876    int mNumNonCachedProcs = 0;
877
878    /**
879     * Keep track of the number of cached hidden procs, to balance oom adj
880     * distribution between those and empty procs.
881     */
882    int mNumCachedHiddenProcs = 0;
883
884    /**
885     * Keep track of the number of service processes we last found, to
886     * determine on the next iteration which should be B services.
887     */
888    int mNumServiceProcs = 0;
889    int mNewNumAServiceProcs = 0;
890    int mNewNumServiceProcs = 0;
891
892    /**
893     * Allow the current computed overall memory level of the system to go down?
894     * This is set to false when we are killing processes for reasons other than
895     * memory management, so that the now smaller process list will not be taken as
896     * an indication that memory is tighter.
897     */
898    boolean mAllowLowerMemLevel = false;
899
900    /**
901     * The last computed memory level, for holding when we are in a state that
902     * processes are going away for other reasons.
903     */
904    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
905
906    /**
907     * The last total number of process we have, to determine if changes actually look
908     * like a shrinking number of process due to lower RAM.
909     */
910    int mLastNumProcesses;
911
912    /**
913     * The uptime of the last time we performed idle maintenance.
914     */
915    long mLastIdleTime = SystemClock.uptimeMillis();
916
917    /**
918     * Total time spent with RAM that has been added in the past since the last idle time.
919     */
920    long mLowRamTimeSinceLastIdle = 0;
921
922    /**
923     * If RAM is currently low, when that horrible situatin started.
924     */
925    long mLowRamStartTime = 0;
926
927    /**
928     * This is set if we had to do a delayed dexopt of an app before launching
929     * it, to increase the ANR timeouts in that case.
930     */
931    boolean mDidDexOpt;
932
933    /**
934     * Set if the systemServer made a call to enterSafeMode.
935     */
936    boolean mSafeMode;
937
938    String mDebugApp = null;
939    boolean mWaitForDebugger = false;
940    boolean mDebugTransient = false;
941    String mOrigDebugApp = null;
942    boolean mOrigWaitForDebugger = false;
943    boolean mAlwaysFinishActivities = false;
944    IActivityController mController = null;
945    String mProfileApp = null;
946    ProcessRecord mProfileProc = null;
947    String mProfileFile;
948    ParcelFileDescriptor mProfileFd;
949    int mProfileType = 0;
950    boolean mAutoStopProfiler = false;
951    String mOpenGlTraceApp = null;
952
953    static class ProcessChangeItem {
954        static final int CHANGE_ACTIVITIES = 1<<0;
955        static final int CHANGE_IMPORTANCE= 1<<1;
956        int changes;
957        int uid;
958        int pid;
959        int importance;
960        boolean foregroundActivities;
961    }
962
963    final RemoteCallbackList<IProcessObserver> mProcessObservers
964            = new RemoteCallbackList<IProcessObserver>();
965    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
966
967    final ArrayList<ProcessChangeItem> mPendingProcessChanges
968            = new ArrayList<ProcessChangeItem>();
969    final ArrayList<ProcessChangeItem> mAvailProcessChanges
970            = new ArrayList<ProcessChangeItem>();
971
972    /**
973     * Runtime CPU use collection thread.  This object's lock is used to
974     * protect all related state.
975     */
976    final Thread mProcessCpuThread;
977
978    /**
979     * Used to collect process stats when showing not responding dialog.
980     * Protected by mProcessCpuThread.
981     */
982    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
983            MONITOR_THREAD_CPU_USAGE);
984    final AtomicLong mLastCpuTime = new AtomicLong(0);
985    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
986
987    long mLastWriteTime = 0;
988
989    /**
990     * Used to retain an update lock when the foreground activity is in
991     * immersive mode.
992     */
993    final UpdateLock mUpdateLock = new UpdateLock("immersive");
994
995    /**
996     * Set to true after the system has finished booting.
997     */
998    boolean mBooted = false;
999
1000    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1001    int mProcessLimitOverride = -1;
1002
1003    WindowManagerService mWindowManager;
1004
1005    final ActivityThread mSystemThread;
1006
1007    int mCurrentUserId = 0;
1008    private UserManagerService mUserManager;
1009
1010    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1011        final ProcessRecord mApp;
1012        final int mPid;
1013        final IApplicationThread mAppThread;
1014
1015        AppDeathRecipient(ProcessRecord app, int pid,
1016                IApplicationThread thread) {
1017            if (localLOGV) Slog.v(
1018                TAG, "New death recipient " + this
1019                + " for thread " + thread.asBinder());
1020            mApp = app;
1021            mPid = pid;
1022            mAppThread = thread;
1023        }
1024
1025        @Override
1026        public void binderDied() {
1027            if (localLOGV) Slog.v(
1028                TAG, "Death received in " + this
1029                + " for thread " + mAppThread.asBinder());
1030            synchronized(ActivityManagerService.this) {
1031                appDiedLocked(mApp, mPid, mAppThread);
1032            }
1033        }
1034    }
1035
1036    static final int SHOW_ERROR_MSG = 1;
1037    static final int SHOW_NOT_RESPONDING_MSG = 2;
1038    static final int SHOW_FACTORY_ERROR_MSG = 3;
1039    static final int UPDATE_CONFIGURATION_MSG = 4;
1040    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1041    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1042    static final int SERVICE_TIMEOUT_MSG = 12;
1043    static final int UPDATE_TIME_ZONE = 13;
1044    static final int SHOW_UID_ERROR_MSG = 14;
1045    static final int IM_FEELING_LUCKY_MSG = 15;
1046    static final int PROC_START_TIMEOUT_MSG = 20;
1047    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1048    static final int KILL_APPLICATION_MSG = 22;
1049    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1050    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1051    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1052    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1053    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1054    static final int CLEAR_DNS_CACHE_MSG = 28;
1055    static final int UPDATE_HTTP_PROXY_MSG = 29;
1056    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1057    static final int DISPATCH_PROCESSES_CHANGED = 31;
1058    static final int DISPATCH_PROCESS_DIED = 32;
1059    static final int REPORT_MEM_USAGE_MSG = 33;
1060    static final int REPORT_USER_SWITCH_MSG = 34;
1061    static final int CONTINUE_USER_SWITCH_MSG = 35;
1062    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1063    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1064    static final int PERSIST_URI_GRANTS_MSG = 38;
1065    static final int REQUEST_ALL_PSS_MSG = 39;
1066    static final int UPDATE_TIME = 40;
1067
1068    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1069    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1070    static final int FIRST_COMPAT_MODE_MSG = 300;
1071    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1072
1073    AlertDialog mUidAlert;
1074    CompatModeDialog mCompatModeDialog;
1075    long mLastMemUsageReportTime = 0;
1076
1077    /**
1078     * Flag whether the current user is a "monkey", i.e. whether
1079     * the UI is driven by a UI automation tool.
1080     */
1081    private boolean mUserIsMonkey;
1082
1083    final ServiceThread mHandlerThread;
1084    final MainHandler mHandler;
1085
1086    final class MainHandler extends Handler {
1087        public MainHandler(Looper looper) {
1088            super(looper, null, true);
1089        }
1090
1091        @Override
1092        public void handleMessage(Message msg) {
1093            switch (msg.what) {
1094            case SHOW_ERROR_MSG: {
1095                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1096                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1097                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1098                synchronized (ActivityManagerService.this) {
1099                    ProcessRecord proc = (ProcessRecord)data.get("app");
1100                    AppErrorResult res = (AppErrorResult) data.get("result");
1101                    if (proc != null && proc.crashDialog != null) {
1102                        Slog.e(TAG, "App already has crash dialog: " + proc);
1103                        if (res != null) {
1104                            res.set(0);
1105                        }
1106                        return;
1107                    }
1108                    if (!showBackground && UserHandle.getAppId(proc.uid)
1109                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1110                            && proc.pid != MY_PID) {
1111                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1112                        if (res != null) {
1113                            res.set(0);
1114                        }
1115                        return;
1116                    }
1117                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1118                        Dialog d = new AppErrorDialog(mContext,
1119                                ActivityManagerService.this, res, proc);
1120                        d.show();
1121                        proc.crashDialog = d;
1122                    } else {
1123                        // The device is asleep, so just pretend that the user
1124                        // saw a crash dialog and hit "force quit".
1125                        if (res != null) {
1126                            res.set(0);
1127                        }
1128                    }
1129                }
1130
1131                ensureBootCompleted();
1132            } break;
1133            case SHOW_NOT_RESPONDING_MSG: {
1134                synchronized (ActivityManagerService.this) {
1135                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1136                    ProcessRecord proc = (ProcessRecord)data.get("app");
1137                    if (proc != null && proc.anrDialog != null) {
1138                        Slog.e(TAG, "App already has anr dialog: " + proc);
1139                        return;
1140                    }
1141
1142                    Intent intent = new Intent("android.intent.action.ANR");
1143                    if (!mProcessesReady) {
1144                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1145                                | Intent.FLAG_RECEIVER_FOREGROUND);
1146                    }
1147                    broadcastIntentLocked(null, null, intent,
1148                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1149                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1150
1151                    if (mShowDialogs) {
1152                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1153                                mContext, proc, (ActivityRecord)data.get("activity"),
1154                                msg.arg1 != 0);
1155                        d.show();
1156                        proc.anrDialog = d;
1157                    } else {
1158                        // Just kill the app if there is no dialog to be shown.
1159                        killAppAtUsersRequest(proc, null);
1160                    }
1161                }
1162
1163                ensureBootCompleted();
1164            } break;
1165            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1166                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1167                synchronized (ActivityManagerService.this) {
1168                    ProcessRecord proc = (ProcessRecord) data.get("app");
1169                    if (proc == null) {
1170                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1171                        break;
1172                    }
1173                    if (proc.crashDialog != null) {
1174                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1175                        return;
1176                    }
1177                    AppErrorResult res = (AppErrorResult) data.get("result");
1178                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1179                        Dialog d = new StrictModeViolationDialog(mContext,
1180                                ActivityManagerService.this, res, proc);
1181                        d.show();
1182                        proc.crashDialog = d;
1183                    } else {
1184                        // The device is asleep, so just pretend that the user
1185                        // saw a crash dialog and hit "force quit".
1186                        res.set(0);
1187                    }
1188                }
1189                ensureBootCompleted();
1190            } break;
1191            case SHOW_FACTORY_ERROR_MSG: {
1192                Dialog d = new FactoryErrorDialog(
1193                    mContext, msg.getData().getCharSequence("msg"));
1194                d.show();
1195                ensureBootCompleted();
1196            } break;
1197            case UPDATE_CONFIGURATION_MSG: {
1198                final ContentResolver resolver = mContext.getContentResolver();
1199                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1200            } break;
1201            case GC_BACKGROUND_PROCESSES_MSG: {
1202                synchronized (ActivityManagerService.this) {
1203                    performAppGcsIfAppropriateLocked();
1204                }
1205            } break;
1206            case WAIT_FOR_DEBUGGER_MSG: {
1207                synchronized (ActivityManagerService.this) {
1208                    ProcessRecord app = (ProcessRecord)msg.obj;
1209                    if (msg.arg1 != 0) {
1210                        if (!app.waitedForDebugger) {
1211                            Dialog d = new AppWaitingForDebuggerDialog(
1212                                    ActivityManagerService.this,
1213                                    mContext, app);
1214                            app.waitDialog = d;
1215                            app.waitedForDebugger = true;
1216                            d.show();
1217                        }
1218                    } else {
1219                        if (app.waitDialog != null) {
1220                            app.waitDialog.dismiss();
1221                            app.waitDialog = null;
1222                        }
1223                    }
1224                }
1225            } break;
1226            case SERVICE_TIMEOUT_MSG: {
1227                if (mDidDexOpt) {
1228                    mDidDexOpt = false;
1229                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1230                    nmsg.obj = msg.obj;
1231                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1232                    return;
1233                }
1234                mServices.serviceTimeout((ProcessRecord)msg.obj);
1235            } break;
1236            case UPDATE_TIME_ZONE: {
1237                synchronized (ActivityManagerService.this) {
1238                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1239                        ProcessRecord r = mLruProcesses.get(i);
1240                        if (r.thread != null) {
1241                            try {
1242                                r.thread.updateTimeZone();
1243                            } catch (RemoteException ex) {
1244                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1245                            }
1246                        }
1247                    }
1248                }
1249            } break;
1250            case CLEAR_DNS_CACHE_MSG: {
1251                synchronized (ActivityManagerService.this) {
1252                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1253                        ProcessRecord r = mLruProcesses.get(i);
1254                        if (r.thread != null) {
1255                            try {
1256                                r.thread.clearDnsCache();
1257                            } catch (RemoteException ex) {
1258                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1259                            }
1260                        }
1261                    }
1262                }
1263            } break;
1264            case UPDATE_HTTP_PROXY_MSG: {
1265                ProxyProperties proxy = (ProxyProperties)msg.obj;
1266                String host = "";
1267                String port = "";
1268                String exclList = "";
1269                String pacFileUrl = null;
1270                if (proxy != null) {
1271                    host = proxy.getHost();
1272                    port = Integer.toString(proxy.getPort());
1273                    exclList = proxy.getExclusionList();
1274                    pacFileUrl = proxy.getPacFileUrl();
1275                }
1276                synchronized (ActivityManagerService.this) {
1277                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1278                        ProcessRecord r = mLruProcesses.get(i);
1279                        if (r.thread != null) {
1280                            try {
1281                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1282                            } catch (RemoteException ex) {
1283                                Slog.w(TAG, "Failed to update http proxy for: " +
1284                                        r.info.processName);
1285                            }
1286                        }
1287                    }
1288                }
1289            } break;
1290            case SHOW_UID_ERROR_MSG: {
1291                String title = "System UIDs Inconsistent";
1292                String text = "UIDs on the system are inconsistent, you need to wipe your"
1293                        + " data partition or your device will be unstable.";
1294                Log.e(TAG, title + ": " + text);
1295                if (mShowDialogs) {
1296                    // XXX This is a temporary dialog, no need to localize.
1297                    AlertDialog d = new BaseErrorDialog(mContext);
1298                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1299                    d.setCancelable(false);
1300                    d.setTitle(title);
1301                    d.setMessage(text);
1302                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1303                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1304                    mUidAlert = d;
1305                    d.show();
1306                }
1307            } break;
1308            case IM_FEELING_LUCKY_MSG: {
1309                if (mUidAlert != null) {
1310                    mUidAlert.dismiss();
1311                    mUidAlert = null;
1312                }
1313            } break;
1314            case PROC_START_TIMEOUT_MSG: {
1315                if (mDidDexOpt) {
1316                    mDidDexOpt = false;
1317                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1318                    nmsg.obj = msg.obj;
1319                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1320                    return;
1321                }
1322                ProcessRecord app = (ProcessRecord)msg.obj;
1323                synchronized (ActivityManagerService.this) {
1324                    processStartTimedOutLocked(app);
1325                }
1326            } break;
1327            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1328                synchronized (ActivityManagerService.this) {
1329                    doPendingActivityLaunchesLocked(true);
1330                }
1331            } break;
1332            case KILL_APPLICATION_MSG: {
1333                synchronized (ActivityManagerService.this) {
1334                    int appid = msg.arg1;
1335                    boolean restart = (msg.arg2 == 1);
1336                    Bundle bundle = (Bundle)msg.obj;
1337                    String pkg = bundle.getString("pkg");
1338                    String reason = bundle.getString("reason");
1339                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1340                            UserHandle.USER_ALL, reason);
1341                }
1342            } break;
1343            case FINALIZE_PENDING_INTENT_MSG: {
1344                ((PendingIntentRecord)msg.obj).completeFinalize();
1345            } break;
1346            case POST_HEAVY_NOTIFICATION_MSG: {
1347                INotificationManager inm = NotificationManager.getService();
1348                if (inm == null) {
1349                    return;
1350                }
1351
1352                ActivityRecord root = (ActivityRecord)msg.obj;
1353                ProcessRecord process = root.app;
1354                if (process == null) {
1355                    return;
1356                }
1357
1358                try {
1359                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1360                    String text = mContext.getString(R.string.heavy_weight_notification,
1361                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1362                    Notification notification = new Notification();
1363                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1364                    notification.when = 0;
1365                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1366                    notification.tickerText = text;
1367                    notification.defaults = 0; // please be quiet
1368                    notification.sound = null;
1369                    notification.vibrate = null;
1370                    notification.setLatestEventInfo(context, text,
1371                            mContext.getText(R.string.heavy_weight_notification_detail),
1372                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1373                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1374                                    new UserHandle(root.userId)));
1375
1376                    try {
1377                        int[] outId = new int[1];
1378                        inm.enqueueNotificationWithTag("android", "android", null,
1379                                R.string.heavy_weight_notification,
1380                                notification, outId, root.userId);
1381                    } catch (RuntimeException e) {
1382                        Slog.w(ActivityManagerService.TAG,
1383                                "Error showing notification for heavy-weight app", e);
1384                    } catch (RemoteException e) {
1385                    }
1386                } catch (NameNotFoundException e) {
1387                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1388                }
1389            } break;
1390            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1391                INotificationManager inm = NotificationManager.getService();
1392                if (inm == null) {
1393                    return;
1394                }
1395                try {
1396                    inm.cancelNotificationWithTag("android", null,
1397                            R.string.heavy_weight_notification,  msg.arg1);
1398                } catch (RuntimeException e) {
1399                    Slog.w(ActivityManagerService.TAG,
1400                            "Error canceling notification for service", e);
1401                } catch (RemoteException e) {
1402                }
1403            } break;
1404            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1405                synchronized (ActivityManagerService.this) {
1406                    checkExcessivePowerUsageLocked(true);
1407                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1408                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1409                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1410                }
1411            } break;
1412            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1413                synchronized (ActivityManagerService.this) {
1414                    ActivityRecord ar = (ActivityRecord)msg.obj;
1415                    if (mCompatModeDialog != null) {
1416                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1417                                ar.info.applicationInfo.packageName)) {
1418                            return;
1419                        }
1420                        mCompatModeDialog.dismiss();
1421                        mCompatModeDialog = null;
1422                    }
1423                    if (ar != null && false) {
1424                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1425                                ar.packageName)) {
1426                            int mode = mCompatModePackages.computeCompatModeLocked(
1427                                    ar.info.applicationInfo);
1428                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1429                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1430                                mCompatModeDialog = new CompatModeDialog(
1431                                        ActivityManagerService.this, mContext,
1432                                        ar.info.applicationInfo);
1433                                mCompatModeDialog.show();
1434                            }
1435                        }
1436                    }
1437                }
1438                break;
1439            }
1440            case DISPATCH_PROCESSES_CHANGED: {
1441                dispatchProcessesChanged();
1442                break;
1443            }
1444            case DISPATCH_PROCESS_DIED: {
1445                final int pid = msg.arg1;
1446                final int uid = msg.arg2;
1447                dispatchProcessDied(pid, uid);
1448                break;
1449            }
1450            case REPORT_MEM_USAGE_MSG: {
1451                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1452                Thread thread = new Thread() {
1453                    @Override public void run() {
1454                        final SparseArray<ProcessMemInfo> infoMap
1455                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1456                        for (int i=0, N=memInfos.size(); i<N; i++) {
1457                            ProcessMemInfo mi = memInfos.get(i);
1458                            infoMap.put(mi.pid, mi);
1459                        }
1460                        updateCpuStatsNow();
1461                        synchronized (mProcessCpuThread) {
1462                            final int N = mProcessCpuTracker.countStats();
1463                            for (int i=0; i<N; i++) {
1464                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1465                                if (st.vsize > 0) {
1466                                    long pss = Debug.getPss(st.pid, null);
1467                                    if (pss > 0) {
1468                                        if (infoMap.indexOfKey(st.pid) < 0) {
1469                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1470                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1471                                            mi.pss = pss;
1472                                            memInfos.add(mi);
1473                                        }
1474                                    }
1475                                }
1476                            }
1477                        }
1478
1479                        long totalPss = 0;
1480                        for (int i=0, N=memInfos.size(); i<N; i++) {
1481                            ProcessMemInfo mi = memInfos.get(i);
1482                            if (mi.pss == 0) {
1483                                mi.pss = Debug.getPss(mi.pid, null);
1484                            }
1485                            totalPss += mi.pss;
1486                        }
1487                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1488                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1489                                if (lhs.oomAdj != rhs.oomAdj) {
1490                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1491                                }
1492                                if (lhs.pss != rhs.pss) {
1493                                    return lhs.pss < rhs.pss ? 1 : -1;
1494                                }
1495                                return 0;
1496                            }
1497                        });
1498
1499                        StringBuilder tag = new StringBuilder(128);
1500                        StringBuilder stack = new StringBuilder(128);
1501                        tag.append("Low on memory -- ");
1502                        appendMemBucket(tag, totalPss, "total", false);
1503                        appendMemBucket(stack, totalPss, "total", true);
1504
1505                        StringBuilder logBuilder = new StringBuilder(1024);
1506                        logBuilder.append("Low on memory:\n");
1507
1508                        boolean firstLine = true;
1509                        int lastOomAdj = Integer.MIN_VALUE;
1510                        for (int i=0, N=memInfos.size(); i<N; i++) {
1511                            ProcessMemInfo mi = memInfos.get(i);
1512
1513                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1514                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1515                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1516                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1517                                if (lastOomAdj != mi.oomAdj) {
1518                                    lastOomAdj = mi.oomAdj;
1519                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1520                                        tag.append(" / ");
1521                                    }
1522                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1523                                        if (firstLine) {
1524                                            stack.append(":");
1525                                            firstLine = false;
1526                                        }
1527                                        stack.append("\n\t at ");
1528                                    } else {
1529                                        stack.append("$");
1530                                    }
1531                                } else {
1532                                    tag.append(" ");
1533                                    stack.append("$");
1534                                }
1535                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1536                                    appendMemBucket(tag, mi.pss, mi.name, false);
1537                                }
1538                                appendMemBucket(stack, mi.pss, mi.name, true);
1539                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1540                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1541                                    stack.append("(");
1542                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1543                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1544                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1545                                            stack.append(":");
1546                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1547                                        }
1548                                    }
1549                                    stack.append(")");
1550                                }
1551                            }
1552
1553                            logBuilder.append("  ");
1554                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1555                            logBuilder.append(' ');
1556                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1557                            logBuilder.append(' ');
1558                            ProcessList.appendRamKb(logBuilder, mi.pss);
1559                            logBuilder.append(" kB: ");
1560                            logBuilder.append(mi.name);
1561                            logBuilder.append(" (");
1562                            logBuilder.append(mi.pid);
1563                            logBuilder.append(") ");
1564                            logBuilder.append(mi.adjType);
1565                            logBuilder.append('\n');
1566                            if (mi.adjReason != null) {
1567                                logBuilder.append("                      ");
1568                                logBuilder.append(mi.adjReason);
1569                                logBuilder.append('\n');
1570                            }
1571                        }
1572
1573                        logBuilder.append("           ");
1574                        ProcessList.appendRamKb(logBuilder, totalPss);
1575                        logBuilder.append(" kB: TOTAL\n");
1576
1577                        long[] infos = new long[Debug.MEMINFO_COUNT];
1578                        Debug.getMemInfo(infos);
1579                        logBuilder.append("  MemInfo: ");
1580                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1581                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1582                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1583                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1584                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1585                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1586                            logBuilder.append("  ZRAM: ");
1587                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1588                            logBuilder.append(" kB RAM, ");
1589                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1590                            logBuilder.append(" kB swap total, ");
1591                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1592                            logBuilder.append(" kB swap free\n");
1593                        }
1594                        Slog.i(TAG, logBuilder.toString());
1595
1596                        StringBuilder dropBuilder = new StringBuilder(1024);
1597                        /*
1598                        StringWriter oomSw = new StringWriter();
1599                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1600                        StringWriter catSw = new StringWriter();
1601                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1602                        String[] emptyArgs = new String[] { };
1603                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1604                        oomPw.flush();
1605                        String oomString = oomSw.toString();
1606                        */
1607                        dropBuilder.append(stack);
1608                        dropBuilder.append('\n');
1609                        dropBuilder.append('\n');
1610                        dropBuilder.append(logBuilder);
1611                        dropBuilder.append('\n');
1612                        /*
1613                        dropBuilder.append(oomString);
1614                        dropBuilder.append('\n');
1615                        */
1616                        StringWriter catSw = new StringWriter();
1617                        synchronized (ActivityManagerService.this) {
1618                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1619                            String[] emptyArgs = new String[] { };
1620                            catPw.println();
1621                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1622                            catPw.println();
1623                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1624                                    false, false, null);
1625                            catPw.println();
1626                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1627                            catPw.flush();
1628                        }
1629                        dropBuilder.append(catSw.toString());
1630                        addErrorToDropBox("lowmem", null, "system_server", null,
1631                                null, tag.toString(), dropBuilder.toString(), null, null);
1632                        //Slog.i(TAG, "Sent to dropbox:");
1633                        //Slog.i(TAG, dropBuilder.toString());
1634                        synchronized (ActivityManagerService.this) {
1635                            long now = SystemClock.uptimeMillis();
1636                            if (mLastMemUsageReportTime < now) {
1637                                mLastMemUsageReportTime = now;
1638                            }
1639                        }
1640                    }
1641                };
1642                thread.start();
1643                break;
1644            }
1645            case REPORT_USER_SWITCH_MSG: {
1646                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1647                break;
1648            }
1649            case CONTINUE_USER_SWITCH_MSG: {
1650                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1651                break;
1652            }
1653            case USER_SWITCH_TIMEOUT_MSG: {
1654                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1655                break;
1656            }
1657            case IMMERSIVE_MODE_LOCK_MSG: {
1658                final boolean nextState = (msg.arg1 != 0);
1659                if (mUpdateLock.isHeld() != nextState) {
1660                    if (DEBUG_IMMERSIVE) {
1661                        final ActivityRecord r = (ActivityRecord) msg.obj;
1662                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1663                    }
1664                    if (nextState) {
1665                        mUpdateLock.acquire();
1666                    } else {
1667                        mUpdateLock.release();
1668                    }
1669                }
1670                break;
1671            }
1672            case PERSIST_URI_GRANTS_MSG: {
1673                writeGrantedUriPermissions();
1674                break;
1675            }
1676            case REQUEST_ALL_PSS_MSG: {
1677                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1678                break;
1679            }
1680            case UPDATE_TIME: {
1681                synchronized (ActivityManagerService.this) {
1682                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1683                        ProcessRecord r = mLruProcesses.get(i);
1684                        if (r.thread != null) {
1685                            try {
1686                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1687                            } catch (RemoteException ex) {
1688                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1689                            }
1690                        }
1691                    }
1692                }
1693
1694                break;
1695            }
1696            }
1697        }
1698    };
1699
1700    static final int COLLECT_PSS_BG_MSG = 1;
1701
1702    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1703        @Override
1704        public void handleMessage(Message msg) {
1705            switch (msg.what) {
1706            case COLLECT_PSS_BG_MSG: {
1707                int i=0, num=0;
1708                long start = SystemClock.uptimeMillis();
1709                long[] tmp = new long[1];
1710                do {
1711                    ProcessRecord proc;
1712                    int procState;
1713                    int pid;
1714                    synchronized (ActivityManagerService.this) {
1715                        if (i >= mPendingPssProcesses.size()) {
1716                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1717                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1718                            mPendingPssProcesses.clear();
1719                            return;
1720                        }
1721                        proc = mPendingPssProcesses.get(i);
1722                        procState = proc.pssProcState;
1723                        if (proc.thread != null && procState == proc.setProcState) {
1724                            pid = proc.pid;
1725                        } else {
1726                            proc = null;
1727                            pid = 0;
1728                        }
1729                        i++;
1730                    }
1731                    if (proc != null) {
1732                        long pss = Debug.getPss(pid, tmp);
1733                        synchronized (ActivityManagerService.this) {
1734                            if (proc.thread != null && proc.setProcState == procState
1735                                    && proc.pid == pid) {
1736                                num++;
1737                                proc.lastPssTime = SystemClock.uptimeMillis();
1738                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1739                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1740                                        + ": " + pss + " lastPss=" + proc.lastPss
1741                                        + " state=" + ProcessList.makeProcStateString(procState));
1742                                if (proc.initialIdlePss == 0) {
1743                                    proc.initialIdlePss = pss;
1744                                }
1745                                proc.lastPss = pss;
1746                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1747                                    proc.lastCachedPss = pss;
1748                                }
1749                            }
1750                        }
1751                    }
1752                } while (true);
1753            }
1754            }
1755        }
1756    };
1757
1758    public void setSystemProcess() {
1759        try {
1760            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1761            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1762            ServiceManager.addService("meminfo", new MemBinder(this));
1763            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1764            ServiceManager.addService("dbinfo", new DbBinder(this));
1765            if (MONITOR_CPU_USAGE) {
1766                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1767            }
1768            ServiceManager.addService("permission", new PermissionController(this));
1769
1770            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1771                    "android", STOCK_PM_FLAGS);
1772            mSystemThread.installSystemApplicationInfo(info);
1773
1774            synchronized (this) {
1775                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1776                app.persistent = true;
1777                app.pid = MY_PID;
1778                app.maxAdj = ProcessList.SYSTEM_ADJ;
1779                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1780                mProcessNames.put(app.processName, app.uid, app);
1781                synchronized (mPidsSelfLocked) {
1782                    mPidsSelfLocked.put(app.pid, app);
1783                }
1784                updateLruProcessLocked(app, false, null);
1785                updateOomAdjLocked();
1786            }
1787        } catch (PackageManager.NameNotFoundException e) {
1788            throw new RuntimeException(
1789                    "Unable to find android system package", e);
1790        }
1791    }
1792
1793    public void setWindowManager(WindowManagerService wm) {
1794        mWindowManager = wm;
1795        mStackSupervisor.setWindowManager(wm);
1796    }
1797
1798    public void startObservingNativeCrashes() {
1799        final NativeCrashListener ncl = new NativeCrashListener(this);
1800        ncl.start();
1801    }
1802
1803    public IAppOpsService getAppOpsService() {
1804        return mAppOpsService;
1805    }
1806
1807    static class MemBinder extends Binder {
1808        ActivityManagerService mActivityManagerService;
1809        MemBinder(ActivityManagerService activityManagerService) {
1810            mActivityManagerService = activityManagerService;
1811        }
1812
1813        @Override
1814        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1815            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1816                    != PackageManager.PERMISSION_GRANTED) {
1817                pw.println("Permission Denial: can't dump meminfo from from pid="
1818                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1819                        + " without permission " + android.Manifest.permission.DUMP);
1820                return;
1821            }
1822
1823            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1824        }
1825    }
1826
1827    static class GraphicsBinder extends Binder {
1828        ActivityManagerService mActivityManagerService;
1829        GraphicsBinder(ActivityManagerService activityManagerService) {
1830            mActivityManagerService = activityManagerService;
1831        }
1832
1833        @Override
1834        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1835            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1836                    != PackageManager.PERMISSION_GRANTED) {
1837                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1838                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1839                        + " without permission " + android.Manifest.permission.DUMP);
1840                return;
1841            }
1842
1843            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1844        }
1845    }
1846
1847    static class DbBinder extends Binder {
1848        ActivityManagerService mActivityManagerService;
1849        DbBinder(ActivityManagerService activityManagerService) {
1850            mActivityManagerService = activityManagerService;
1851        }
1852
1853        @Override
1854        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1855            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1856                    != PackageManager.PERMISSION_GRANTED) {
1857                pw.println("Permission Denial: can't dump dbinfo from from pid="
1858                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1859                        + " without permission " + android.Manifest.permission.DUMP);
1860                return;
1861            }
1862
1863            mActivityManagerService.dumpDbInfo(fd, pw, args);
1864        }
1865    }
1866
1867    static class CpuBinder extends Binder {
1868        ActivityManagerService mActivityManagerService;
1869        CpuBinder(ActivityManagerService activityManagerService) {
1870            mActivityManagerService = activityManagerService;
1871        }
1872
1873        @Override
1874        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1875            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1876                    != PackageManager.PERMISSION_GRANTED) {
1877                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1878                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1879                        + " without permission " + android.Manifest.permission.DUMP);
1880                return;
1881            }
1882
1883            synchronized (mActivityManagerService.mProcessCpuThread) {
1884                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1885                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1886                        SystemClock.uptimeMillis()));
1887            }
1888        }
1889    }
1890
1891    public static final class Lifecycle extends SystemService {
1892        private final ActivityManagerService mService;
1893
1894        public Lifecycle(Context context) {
1895            super(context);
1896            mService = new ActivityManagerService(context);
1897        }
1898
1899        @Override
1900        public void onStart() {
1901            mService.start();
1902        }
1903
1904        public ActivityManagerService getService() {
1905            return mService;
1906        }
1907    }
1908
1909    // Note: This method is invoked on the main thread but may need to attach various
1910    // handlers to other threads.  So take care to be explicit about the looper.
1911    public ActivityManagerService(Context systemContext) {
1912        mContext = systemContext;
1913        mFactoryTest = FactoryTest.getMode();
1914        mSystemThread = ActivityThread.currentActivityThread();
1915
1916        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1917
1918        mHandlerThread = new ServiceThread(TAG,
1919                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1920        mHandlerThread.start();
1921        mHandler = new MainHandler(mHandlerThread.getLooper());
1922
1923        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1924                "foreground", BROADCAST_FG_TIMEOUT, false);
1925        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1926                "background", BROADCAST_BG_TIMEOUT, true);
1927        mBroadcastQueues[0] = mFgBroadcastQueue;
1928        mBroadcastQueues[1] = mBgBroadcastQueue;
1929
1930        mServices = new ActiveServices(this);
1931        mProviderMap = new ProviderMap(this);
1932
1933        // TODO: Move creation of battery stats service outside of activity manager service.
1934        File dataDir = Environment.getDataDirectory();
1935        File systemDir = new File(dataDir, "system");
1936        systemDir.mkdirs();
1937        mBatteryStatsService = new BatteryStatsService(new File(
1938                systemDir, "batterystats.bin").toString(), mHandler);
1939        mBatteryStatsService.getActiveStatistics().readLocked();
1940        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1941        mOnBattery = DEBUG_POWER ? true
1942                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1943        mBatteryStatsService.getActiveStatistics().setCallback(this);
1944
1945        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1946
1947        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1948        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1949
1950        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1951
1952        // User 0 is the first and only user that runs at boot.
1953        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1954        mUserLru.add(Integer.valueOf(0));
1955        updateStartedUserArrayLocked();
1956
1957        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1958            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1959
1960        mConfiguration.setToDefaults();
1961        mConfiguration.setLocale(Locale.getDefault());
1962
1963        mConfigurationSeq = mConfiguration.seq = 1;
1964        mProcessCpuTracker.init();
1965
1966        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1967        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1968        mStackSupervisor = new ActivityStackSupervisor(this);
1969
1970        mProcessCpuThread = new Thread("CpuTracker") {
1971            @Override
1972            public void run() {
1973                while (true) {
1974                    try {
1975                        try {
1976                            synchronized(this) {
1977                                final long now = SystemClock.uptimeMillis();
1978                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1979                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1980                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1981                                //        + ", write delay=" + nextWriteDelay);
1982                                if (nextWriteDelay < nextCpuDelay) {
1983                                    nextCpuDelay = nextWriteDelay;
1984                                }
1985                                if (nextCpuDelay > 0) {
1986                                    mProcessCpuMutexFree.set(true);
1987                                    this.wait(nextCpuDelay);
1988                                }
1989                            }
1990                        } catch (InterruptedException e) {
1991                        }
1992                        updateCpuStatsNow();
1993                    } catch (Exception e) {
1994                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1995                    }
1996                }
1997            }
1998        };
1999
2000        Watchdog.getInstance().addMonitor(this);
2001        Watchdog.getInstance().addThread(mHandler);
2002    }
2003
2004    private void start() {
2005        mProcessCpuThread.start();
2006
2007        mBatteryStatsService.publish(mContext);
2008        mUsageStatsService.publish(mContext);
2009        mAppOpsService.publish(mContext);
2010
2011        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2012    }
2013
2014    @Override
2015    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2016            throws RemoteException {
2017        if (code == SYSPROPS_TRANSACTION) {
2018            // We need to tell all apps about the system property change.
2019            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2020            synchronized(this) {
2021                final int NP = mProcessNames.getMap().size();
2022                for (int ip=0; ip<NP; ip++) {
2023                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2024                    final int NA = apps.size();
2025                    for (int ia=0; ia<NA; ia++) {
2026                        ProcessRecord app = apps.valueAt(ia);
2027                        if (app.thread != null) {
2028                            procs.add(app.thread.asBinder());
2029                        }
2030                    }
2031                }
2032            }
2033
2034            int N = procs.size();
2035            for (int i=0; i<N; i++) {
2036                Parcel data2 = Parcel.obtain();
2037                try {
2038                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2039                } catch (RemoteException e) {
2040                }
2041                data2.recycle();
2042            }
2043        }
2044        try {
2045            return super.onTransact(code, data, reply, flags);
2046        } catch (RuntimeException e) {
2047            // The activity manager only throws security exceptions, so let's
2048            // log all others.
2049            if (!(e instanceof SecurityException)) {
2050                Slog.wtf(TAG, "Activity Manager Crash", e);
2051            }
2052            throw e;
2053        }
2054    }
2055
2056    void updateCpuStats() {
2057        final long now = SystemClock.uptimeMillis();
2058        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2059            return;
2060        }
2061        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2062            synchronized (mProcessCpuThread) {
2063                mProcessCpuThread.notify();
2064            }
2065        }
2066    }
2067
2068    void updateCpuStatsNow() {
2069        synchronized (mProcessCpuThread) {
2070            mProcessCpuMutexFree.set(false);
2071            final long now = SystemClock.uptimeMillis();
2072            boolean haveNewCpuStats = false;
2073
2074            if (MONITOR_CPU_USAGE &&
2075                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2076                mLastCpuTime.set(now);
2077                haveNewCpuStats = true;
2078                mProcessCpuTracker.update();
2079                //Slog.i(TAG, mProcessCpu.printCurrentState());
2080                //Slog.i(TAG, "Total CPU usage: "
2081                //        + mProcessCpu.getTotalCpuPercent() + "%");
2082
2083                // Slog the cpu usage if the property is set.
2084                if ("true".equals(SystemProperties.get("events.cpu"))) {
2085                    int user = mProcessCpuTracker.getLastUserTime();
2086                    int system = mProcessCpuTracker.getLastSystemTime();
2087                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2088                    int irq = mProcessCpuTracker.getLastIrqTime();
2089                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2090                    int idle = mProcessCpuTracker.getLastIdleTime();
2091
2092                    int total = user + system + iowait + irq + softIrq + idle;
2093                    if (total == 0) total = 1;
2094
2095                    EventLog.writeEvent(EventLogTags.CPU,
2096                            ((user+system+iowait+irq+softIrq) * 100) / total,
2097                            (user * 100) / total,
2098                            (system * 100) / total,
2099                            (iowait * 100) / total,
2100                            (irq * 100) / total,
2101                            (softIrq * 100) / total);
2102                }
2103            }
2104
2105            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2106            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2107            synchronized(bstats) {
2108                synchronized(mPidsSelfLocked) {
2109                    if (haveNewCpuStats) {
2110                        if (mOnBattery) {
2111                            int perc = bstats.startAddingCpuLocked();
2112                            int totalUTime = 0;
2113                            int totalSTime = 0;
2114                            final int N = mProcessCpuTracker.countStats();
2115                            for (int i=0; i<N; i++) {
2116                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2117                                if (!st.working) {
2118                                    continue;
2119                                }
2120                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2121                                int otherUTime = (st.rel_utime*perc)/100;
2122                                int otherSTime = (st.rel_stime*perc)/100;
2123                                totalUTime += otherUTime;
2124                                totalSTime += otherSTime;
2125                                if (pr != null) {
2126                                    BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked(
2127                                            st.name, st.pid);
2128                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2129                                            st.rel_stime-otherSTime);
2130                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2131                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2132                                } else if (st.uid >= Process.FIRST_APPLICATION_UID) {
2133                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2134                                    if (ps == null) {
2135                                        st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid,
2136                                                "(Unknown)");
2137                                    }
2138                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2139                                            st.rel_stime-otherSTime);
2140                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2141                                } else {
2142                                    BatteryStatsImpl.Uid.Proc ps =
2143                                            bstats.getProcessStatsLocked(st.name, st.pid);
2144                                    if (ps != null) {
2145                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2146                                                st.rel_stime-otherSTime);
2147                                        ps.addSpeedStepTimes(cpuSpeedTimes);
2148                                    }
2149                                }
2150                            }
2151                            bstats.finishAddingCpuLocked(perc, totalUTime,
2152                                    totalSTime, cpuSpeedTimes);
2153                        }
2154                    }
2155                }
2156
2157                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2158                    mLastWriteTime = now;
2159                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2160                }
2161            }
2162        }
2163    }
2164
2165    @Override
2166    public void batteryNeedsCpuUpdate() {
2167        updateCpuStatsNow();
2168    }
2169
2170    @Override
2171    public void batteryPowerChanged(boolean onBattery) {
2172        // When plugging in, update the CPU stats first before changing
2173        // the plug state.
2174        updateCpuStatsNow();
2175        synchronized (this) {
2176            synchronized(mPidsSelfLocked) {
2177                mOnBattery = DEBUG_POWER ? true : onBattery;
2178            }
2179        }
2180    }
2181
2182    /**
2183     * Initialize the application bind args. These are passed to each
2184     * process when the bindApplication() IPC is sent to the process. They're
2185     * lazily setup to make sure the services are running when they're asked for.
2186     */
2187    private HashMap<String, IBinder> getCommonServicesLocked() {
2188        if (mAppBindArgs == null) {
2189            mAppBindArgs = new HashMap<String, IBinder>();
2190
2191            // Setup the application init args
2192            mAppBindArgs.put("package", ServiceManager.getService("package"));
2193            mAppBindArgs.put("window", ServiceManager.getService("window"));
2194            mAppBindArgs.put(Context.ALARM_SERVICE,
2195                    ServiceManager.getService(Context.ALARM_SERVICE));
2196        }
2197        return mAppBindArgs;
2198    }
2199
2200    final void setFocusedActivityLocked(ActivityRecord r) {
2201        if (mFocusedActivity != r) {
2202            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2203            mFocusedActivity = r;
2204            mStackSupervisor.setFocusedStack(r);
2205            if (r != null) {
2206                mWindowManager.setFocusedApp(r.appToken, true);
2207            }
2208            applyUpdateLockStateLocked(r);
2209        }
2210    }
2211
2212    @Override
2213    public void setFocusedStack(int stackId) {
2214        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2215        synchronized (ActivityManagerService.this) {
2216            ActivityStack stack = mStackSupervisor.getStack(stackId);
2217            if (stack != null) {
2218                ActivityRecord r = stack.topRunningActivityLocked(null);
2219                if (r != null) {
2220                    setFocusedActivityLocked(r);
2221                }
2222            }
2223        }
2224    }
2225
2226    @Override
2227    public void notifyActivityDrawn(IBinder token) {
2228        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2229        synchronized (this) {
2230            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2231            if (r != null) {
2232                r.task.stack.notifyActivityDrawnLocked(r);
2233            }
2234        }
2235    }
2236
2237    final void applyUpdateLockStateLocked(ActivityRecord r) {
2238        // Modifications to the UpdateLock state are done on our handler, outside
2239        // the activity manager's locks.  The new state is determined based on the
2240        // state *now* of the relevant activity record.  The object is passed to
2241        // the handler solely for logging detail, not to be consulted/modified.
2242        final boolean nextState = r != null && r.immersive;
2243        mHandler.sendMessage(
2244                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2245    }
2246
2247    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2248        Message msg = Message.obtain();
2249        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2250        msg.obj = r.task.askedCompatMode ? null : r;
2251        mHandler.sendMessage(msg);
2252    }
2253
2254    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2255            String what, Object obj, ProcessRecord srcApp) {
2256        app.lastActivityTime = now;
2257
2258        if (app.activities.size() > 0) {
2259            // Don't want to touch dependent processes that are hosting activities.
2260            return index;
2261        }
2262
2263        int lrui = mLruProcesses.lastIndexOf(app);
2264        if (lrui < 0) {
2265            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2266                    + what + " " + obj + " from " + srcApp);
2267            return index;
2268        }
2269
2270        if (lrui >= index) {
2271            // Don't want to cause this to move dependent processes *back* in the
2272            // list as if they were less frequently used.
2273            return index;
2274        }
2275
2276        if (lrui >= mLruProcessActivityStart) {
2277            // Don't want to touch dependent processes that are hosting activities.
2278            return index;
2279        }
2280
2281        mLruProcesses.remove(lrui);
2282        if (index > 0) {
2283            index--;
2284        }
2285        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2286                + " in LRU list: " + app);
2287        mLruProcesses.add(index, app);
2288        return index;
2289    }
2290
2291    final void removeLruProcessLocked(ProcessRecord app) {
2292        int lrui = mLruProcesses.lastIndexOf(app);
2293        if (lrui >= 0) {
2294            if (lrui <= mLruProcessActivityStart) {
2295                mLruProcessActivityStart--;
2296            }
2297            if (lrui <= mLruProcessServiceStart) {
2298                mLruProcessServiceStart--;
2299            }
2300            mLruProcesses.remove(lrui);
2301        }
2302    }
2303
2304    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2305            ProcessRecord client) {
2306        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2307        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2308        if (!activityChange && hasActivity) {
2309            // The process has activties, so we are only going to allow activity-based
2310            // adjustments move it.  It should be kept in the front of the list with other
2311            // processes that have activities, and we don't want those to change their
2312            // order except due to activity operations.
2313            return;
2314        }
2315
2316        mLruSeq++;
2317        final long now = SystemClock.uptimeMillis();
2318        app.lastActivityTime = now;
2319
2320        // First a quick reject: if the app is already at the position we will
2321        // put it, then there is nothing to do.
2322        if (hasActivity) {
2323            final int N = mLruProcesses.size();
2324            if (N > 0 && mLruProcesses.get(N-1) == app) {
2325                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2326                return;
2327            }
2328        } else {
2329            if (mLruProcessServiceStart > 0
2330                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2331                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2332                return;
2333            }
2334        }
2335
2336        int lrui = mLruProcesses.lastIndexOf(app);
2337
2338        if (app.persistent && lrui >= 0) {
2339            // We don't care about the position of persistent processes, as long as
2340            // they are in the list.
2341            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2342            return;
2343        }
2344
2345        /* In progress: compute new position first, so we can avoid doing work
2346           if the process is not actually going to move.  Not yet working.
2347        int addIndex;
2348        int nextIndex;
2349        boolean inActivity = false, inService = false;
2350        if (hasActivity) {
2351            // Process has activities, put it at the very tipsy-top.
2352            addIndex = mLruProcesses.size();
2353            nextIndex = mLruProcessServiceStart;
2354            inActivity = true;
2355        } else if (hasService) {
2356            // Process has services, put it at the top of the service list.
2357            addIndex = mLruProcessActivityStart;
2358            nextIndex = mLruProcessServiceStart;
2359            inActivity = true;
2360            inService = true;
2361        } else  {
2362            // Process not otherwise of interest, it goes to the top of the non-service area.
2363            addIndex = mLruProcessServiceStart;
2364            if (client != null) {
2365                int clientIndex = mLruProcesses.lastIndexOf(client);
2366                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2367                        + app);
2368                if (clientIndex >= 0 && addIndex > clientIndex) {
2369                    addIndex = clientIndex;
2370                }
2371            }
2372            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2373        }
2374
2375        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2376                + mLruProcessActivityStart + "): " + app);
2377        */
2378
2379        if (lrui >= 0) {
2380            if (lrui < mLruProcessActivityStart) {
2381                mLruProcessActivityStart--;
2382            }
2383            if (lrui < mLruProcessServiceStart) {
2384                mLruProcessServiceStart--;
2385            }
2386            /*
2387            if (addIndex > lrui) {
2388                addIndex--;
2389            }
2390            if (nextIndex > lrui) {
2391                nextIndex--;
2392            }
2393            */
2394            mLruProcesses.remove(lrui);
2395        }
2396
2397        /*
2398        mLruProcesses.add(addIndex, app);
2399        if (inActivity) {
2400            mLruProcessActivityStart++;
2401        }
2402        if (inService) {
2403            mLruProcessActivityStart++;
2404        }
2405        */
2406
2407        int nextIndex;
2408        if (hasActivity) {
2409            final int N = mLruProcesses.size();
2410            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2411                // Process doesn't have activities, but has clients with
2412                // activities...  move it up, but one below the top (the top
2413                // should always have a real activity).
2414                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2415                mLruProcesses.add(N-1, app);
2416                // To keep it from spamming the LRU list (by making a bunch of clients),
2417                // we will push down any other entries owned by the app.
2418                final int uid = app.info.uid;
2419                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2420                    ProcessRecord subProc = mLruProcesses.get(i);
2421                    if (subProc.info.uid == uid) {
2422                        // We want to push this one down the list.  If the process after
2423                        // it is for the same uid, however, don't do so, because we don't
2424                        // want them internally to be re-ordered.
2425                        if (mLruProcesses.get(i-1).info.uid != uid) {
2426                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2427                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2428                            ProcessRecord tmp = mLruProcesses.get(i);
2429                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2430                            mLruProcesses.set(i-1, tmp);
2431                            i--;
2432                        }
2433                    } else {
2434                        // A gap, we can stop here.
2435                        break;
2436                    }
2437                }
2438            } else {
2439                // Process has activities, put it at the very tipsy-top.
2440                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2441                mLruProcesses.add(app);
2442            }
2443            nextIndex = mLruProcessServiceStart;
2444        } else if (hasService) {
2445            // Process has services, put it at the top of the service list.
2446            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2447            mLruProcesses.add(mLruProcessActivityStart, app);
2448            nextIndex = mLruProcessServiceStart;
2449            mLruProcessActivityStart++;
2450        } else  {
2451            // Process not otherwise of interest, it goes to the top of the non-service area.
2452            int index = mLruProcessServiceStart;
2453            if (client != null) {
2454                // If there is a client, don't allow the process to be moved up higher
2455                // in the list than that client.
2456                int clientIndex = mLruProcesses.lastIndexOf(client);
2457                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2458                        + " when updating " + app);
2459                if (clientIndex <= lrui) {
2460                    // Don't allow the client index restriction to push it down farther in the
2461                    // list than it already is.
2462                    clientIndex = lrui;
2463                }
2464                if (clientIndex >= 0 && index > clientIndex) {
2465                    index = clientIndex;
2466                }
2467            }
2468            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2469            mLruProcesses.add(index, app);
2470            nextIndex = index-1;
2471            mLruProcessActivityStart++;
2472            mLruProcessServiceStart++;
2473        }
2474
2475        // If the app is currently using a content provider or service,
2476        // bump those processes as well.
2477        for (int j=app.connections.size()-1; j>=0; j--) {
2478            ConnectionRecord cr = app.connections.valueAt(j);
2479            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2480                    && cr.binding.service.app != null
2481                    && cr.binding.service.app.lruSeq != mLruSeq
2482                    && !cr.binding.service.app.persistent) {
2483                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2484                        "service connection", cr, app);
2485            }
2486        }
2487        for (int j=app.conProviders.size()-1; j>=0; j--) {
2488            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2489            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2490                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2491                        "provider reference", cpr, app);
2492            }
2493        }
2494    }
2495
2496    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2497        if (uid == Process.SYSTEM_UID) {
2498            // The system gets to run in any process.  If there are multiple
2499            // processes with the same uid, just pick the first (this
2500            // should never happen).
2501            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2502            if (procs == null) return null;
2503            final int N = procs.size();
2504            for (int i = 0; i < N; i++) {
2505                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2506            }
2507        }
2508        ProcessRecord proc = mProcessNames.get(processName, uid);
2509        if (false && proc != null && !keepIfLarge
2510                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2511                && proc.lastCachedPss >= 4000) {
2512            // Turn this condition on to cause killing to happen regularly, for testing.
2513            if (proc.baseProcessTracker != null) {
2514                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2515            }
2516            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2517                    + "k from cached");
2518        } else if (proc != null && !keepIfLarge
2519                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2520                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2521            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2522            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2523                if (proc.baseProcessTracker != null) {
2524                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2525                }
2526                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2527                        + "k from cached");
2528            }
2529        }
2530        return proc;
2531    }
2532
2533    void ensurePackageDexOpt(String packageName) {
2534        IPackageManager pm = AppGlobals.getPackageManager();
2535        try {
2536            if (pm.performDexOpt(packageName)) {
2537                mDidDexOpt = true;
2538            }
2539        } catch (RemoteException e) {
2540        }
2541    }
2542
2543    boolean isNextTransitionForward() {
2544        int transit = mWindowManager.getPendingAppTransition();
2545        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2546                || transit == AppTransition.TRANSIT_TASK_OPEN
2547                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2548    }
2549
2550    final ProcessRecord startProcessLocked(String processName,
2551            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2552            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2553            boolean isolated, boolean keepIfLarge) {
2554        ProcessRecord app;
2555        if (!isolated) {
2556            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2557        } else {
2558            // If this is an isolated process, it can't re-use an existing process.
2559            app = null;
2560        }
2561        // We don't have to do anything more if:
2562        // (1) There is an existing application record; and
2563        // (2) The caller doesn't think it is dead, OR there is no thread
2564        //     object attached to it so we know it couldn't have crashed; and
2565        // (3) There is a pid assigned to it, so it is either starting or
2566        //     already running.
2567        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2568                + " app=" + app + " knownToBeDead=" + knownToBeDead
2569                + " thread=" + (app != null ? app.thread : null)
2570                + " pid=" + (app != null ? app.pid : -1));
2571        if (app != null && app.pid > 0) {
2572            if (!knownToBeDead || app.thread == null) {
2573                // We already have the app running, or are waiting for it to
2574                // come up (we have a pid but not yet its thread), so keep it.
2575                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2576                // If this is a new package in the process, add the package to the list
2577                app.addPackage(info.packageName, mProcessStats);
2578                return app;
2579            }
2580
2581            // An application record is attached to a previous process,
2582            // clean it up now.
2583            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2584            handleAppDiedLocked(app, true, true);
2585        }
2586
2587        String hostingNameStr = hostingName != null
2588                ? hostingName.flattenToShortString() : null;
2589
2590        if (!isolated) {
2591            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2592                // If we are in the background, then check to see if this process
2593                // is bad.  If so, we will just silently fail.
2594                if (mBadProcesses.get(info.processName, info.uid) != null) {
2595                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2596                            + "/" + info.processName);
2597                    return null;
2598                }
2599            } else {
2600                // When the user is explicitly starting a process, then clear its
2601                // crash count so that we won't make it bad until they see at
2602                // least one crash dialog again, and make the process good again
2603                // if it had been bad.
2604                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2605                        + "/" + info.processName);
2606                mProcessCrashTimes.remove(info.processName, info.uid);
2607                if (mBadProcesses.get(info.processName, info.uid) != null) {
2608                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2609                            UserHandle.getUserId(info.uid), info.uid,
2610                            info.processName);
2611                    mBadProcesses.remove(info.processName, info.uid);
2612                    if (app != null) {
2613                        app.bad = false;
2614                    }
2615                }
2616            }
2617        }
2618
2619        if (app == null) {
2620            app = newProcessRecordLocked(info, processName, isolated);
2621            if (app == null) {
2622                Slog.w(TAG, "Failed making new process record for "
2623                        + processName + "/" + info.uid + " isolated=" + isolated);
2624                return null;
2625            }
2626            mProcessNames.put(processName, app.uid, app);
2627            if (isolated) {
2628                mIsolatedProcesses.put(app.uid, app);
2629            }
2630        } else {
2631            // If this is a new package in the process, add the package to the list
2632            app.addPackage(info.packageName, mProcessStats);
2633        }
2634
2635        // If the system is not ready yet, then hold off on starting this
2636        // process until it is.
2637        if (!mProcessesReady
2638                && !isAllowedWhileBooting(info)
2639                && !allowWhileBooting) {
2640            if (!mProcessesOnHold.contains(app)) {
2641                mProcessesOnHold.add(app);
2642            }
2643            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2644            return app;
2645        }
2646
2647        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2648        return (app.pid != 0) ? app : null;
2649    }
2650
2651    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2652        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2653    }
2654
2655    private final void startProcessLocked(ProcessRecord app,
2656            String hostingType, String hostingNameStr, String abiOverride) {
2657        if (app.pid > 0 && app.pid != MY_PID) {
2658            synchronized (mPidsSelfLocked) {
2659                mPidsSelfLocked.remove(app.pid);
2660                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2661            }
2662            app.setPid(0);
2663        }
2664
2665        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2666                "startProcessLocked removing on hold: " + app);
2667        mProcessesOnHold.remove(app);
2668
2669        updateCpuStats();
2670
2671        try {
2672            int uid = app.uid;
2673
2674            int[] gids = null;
2675            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2676            if (!app.isolated) {
2677                int[] permGids = null;
2678                try {
2679                    final PackageManager pm = mContext.getPackageManager();
2680                    permGids = pm.getPackageGids(app.info.packageName);
2681
2682                    if (Environment.isExternalStorageEmulated()) {
2683                        if (pm.checkPermission(
2684                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2685                                app.info.packageName) == PERMISSION_GRANTED) {
2686                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2687                        } else {
2688                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2689                        }
2690                    }
2691                } catch (PackageManager.NameNotFoundException e) {
2692                    Slog.w(TAG, "Unable to retrieve gids", e);
2693                }
2694
2695                /*
2696                 * Add shared application GID so applications can share some
2697                 * resources like shared libraries
2698                 */
2699                if (permGids == null) {
2700                    gids = new int[1];
2701                } else {
2702                    gids = new int[permGids.length + 1];
2703                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2704                }
2705                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2706            }
2707            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2708                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2709                        && mTopComponent != null
2710                        && app.processName.equals(mTopComponent.getPackageName())) {
2711                    uid = 0;
2712                }
2713                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2714                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2715                    uid = 0;
2716                }
2717            }
2718            int debugFlags = 0;
2719            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2720                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2721                // Also turn on CheckJNI for debuggable apps. It's quite
2722                // awkward to turn on otherwise.
2723                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2724            }
2725            // Run the app in safe mode if its manifest requests so or the
2726            // system is booted in safe mode.
2727            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2728                mSafeMode == true) {
2729                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2730            }
2731            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2732                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2733            }
2734            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2735                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2736            }
2737            if ("1".equals(SystemProperties.get("debug.assert"))) {
2738                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2739            }
2740
2741            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
2742            if (requiredAbi == null) {
2743                requiredAbi = Build.SUPPORTED_ABIS[0];
2744            }
2745
2746            // Start the process.  It will either succeed and return a result containing
2747            // the PID of the new process, or else throw a RuntimeException.
2748            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2749                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2750                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2751
2752            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2753            synchronized (bs) {
2754                if (bs.isOnBattery()) {
2755                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2756                }
2757            }
2758
2759            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2760                    UserHandle.getUserId(uid), startResult.pid, uid,
2761                    app.processName, hostingType,
2762                    hostingNameStr != null ? hostingNameStr : "");
2763
2764            if (app.persistent) {
2765                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2766            }
2767
2768            StringBuilder buf = mStringBuilder;
2769            buf.setLength(0);
2770            buf.append("Start proc ");
2771            buf.append(app.processName);
2772            buf.append(" for ");
2773            buf.append(hostingType);
2774            if (hostingNameStr != null) {
2775                buf.append(" ");
2776                buf.append(hostingNameStr);
2777            }
2778            buf.append(": pid=");
2779            buf.append(startResult.pid);
2780            buf.append(" uid=");
2781            buf.append(uid);
2782            buf.append(" gids={");
2783            if (gids != null) {
2784                for (int gi=0; gi<gids.length; gi++) {
2785                    if (gi != 0) buf.append(", ");
2786                    buf.append(gids[gi]);
2787
2788                }
2789            }
2790            buf.append("}");
2791            if (requiredAbi != null) {
2792                buf.append(" abi=");
2793                buf.append(requiredAbi);
2794            }
2795            Slog.i(TAG, buf.toString());
2796            app.setPid(startResult.pid);
2797            app.usingWrapper = startResult.usingWrapper;
2798            app.removed = false;
2799            synchronized (mPidsSelfLocked) {
2800                this.mPidsSelfLocked.put(startResult.pid, app);
2801                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2802                msg.obj = app;
2803                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2804                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2805            }
2806        } catch (RuntimeException e) {
2807            // XXX do better error recovery.
2808            app.setPid(0);
2809            Slog.e(TAG, "Failure starting process " + app.processName, e);
2810        }
2811    }
2812
2813    void updateUsageStats(ActivityRecord component, boolean resumed) {
2814        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2815        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2816        if (resumed) {
2817            mUsageStatsService.noteResumeComponent(component.realActivity);
2818            synchronized (stats) {
2819                stats.noteActivityResumedLocked(component.app.uid);
2820            }
2821        } else {
2822            mUsageStatsService.notePauseComponent(component.realActivity);
2823            synchronized (stats) {
2824                stats.noteActivityPausedLocked(component.app.uid);
2825            }
2826        }
2827    }
2828
2829    Intent getHomeIntent() {
2830        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2831        intent.setComponent(mTopComponent);
2832        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2833            intent.addCategory(Intent.CATEGORY_HOME);
2834        }
2835        return intent;
2836    }
2837
2838    boolean startHomeActivityLocked(int userId) {
2839        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2840                && mTopAction == null) {
2841            // We are running in factory test mode, but unable to find
2842            // the factory test app, so just sit around displaying the
2843            // error message and don't try to start anything.
2844            return false;
2845        }
2846        Intent intent = getHomeIntent();
2847        ActivityInfo aInfo =
2848            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2849        if (aInfo != null) {
2850            intent.setComponent(new ComponentName(
2851                    aInfo.applicationInfo.packageName, aInfo.name));
2852            // Don't do this if the home app is currently being
2853            // instrumented.
2854            aInfo = new ActivityInfo(aInfo);
2855            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2856            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2857                    aInfo.applicationInfo.uid, true);
2858            if (app == null || app.instrumentationClass == null) {
2859                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2860                mStackSupervisor.startHomeActivity(intent, aInfo);
2861            }
2862        }
2863
2864        return true;
2865    }
2866
2867    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2868        ActivityInfo ai = null;
2869        ComponentName comp = intent.getComponent();
2870        try {
2871            if (comp != null) {
2872                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2873            } else {
2874                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2875                        intent,
2876                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2877                            flags, userId);
2878
2879                if (info != null) {
2880                    ai = info.activityInfo;
2881                }
2882            }
2883        } catch (RemoteException e) {
2884            // ignore
2885        }
2886
2887        return ai;
2888    }
2889
2890    /**
2891     * Starts the "new version setup screen" if appropriate.
2892     */
2893    void startSetupActivityLocked() {
2894        // Only do this once per boot.
2895        if (mCheckedForSetup) {
2896            return;
2897        }
2898
2899        // We will show this screen if the current one is a different
2900        // version than the last one shown, and we are not running in
2901        // low-level factory test mode.
2902        final ContentResolver resolver = mContext.getContentResolver();
2903        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2904                Settings.Global.getInt(resolver,
2905                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2906            mCheckedForSetup = true;
2907
2908            // See if we should be showing the platform update setup UI.
2909            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2910            List<ResolveInfo> ris = mContext.getPackageManager()
2911                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2912
2913            // We don't allow third party apps to replace this.
2914            ResolveInfo ri = null;
2915            for (int i=0; ris != null && i<ris.size(); i++) {
2916                if ((ris.get(i).activityInfo.applicationInfo.flags
2917                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2918                    ri = ris.get(i);
2919                    break;
2920                }
2921            }
2922
2923            if (ri != null) {
2924                String vers = ri.activityInfo.metaData != null
2925                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2926                        : null;
2927                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2928                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2929                            Intent.METADATA_SETUP_VERSION);
2930                }
2931                String lastVers = Settings.Secure.getString(
2932                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2933                if (vers != null && !vers.equals(lastVers)) {
2934                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2935                    intent.setComponent(new ComponentName(
2936                            ri.activityInfo.packageName, ri.activityInfo.name));
2937                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2938                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2939                }
2940            }
2941        }
2942    }
2943
2944    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2945        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2946    }
2947
2948    void enforceNotIsolatedCaller(String caller) {
2949        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2950            throw new SecurityException("Isolated process not allowed to call " + caller);
2951        }
2952    }
2953
2954    @Override
2955    public int getFrontActivityScreenCompatMode() {
2956        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2957        synchronized (this) {
2958            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2959        }
2960    }
2961
2962    @Override
2963    public void setFrontActivityScreenCompatMode(int mode) {
2964        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2965                "setFrontActivityScreenCompatMode");
2966        synchronized (this) {
2967            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2968        }
2969    }
2970
2971    @Override
2972    public int getPackageScreenCompatMode(String packageName) {
2973        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2974        synchronized (this) {
2975            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2976        }
2977    }
2978
2979    @Override
2980    public void setPackageScreenCompatMode(String packageName, int mode) {
2981        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2982                "setPackageScreenCompatMode");
2983        synchronized (this) {
2984            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2985        }
2986    }
2987
2988    @Override
2989    public boolean getPackageAskScreenCompat(String packageName) {
2990        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2991        synchronized (this) {
2992            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2993        }
2994    }
2995
2996    @Override
2997    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2998        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2999                "setPackageAskScreenCompat");
3000        synchronized (this) {
3001            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3002        }
3003    }
3004
3005    private void dispatchProcessesChanged() {
3006        int N;
3007        synchronized (this) {
3008            N = mPendingProcessChanges.size();
3009            if (mActiveProcessChanges.length < N) {
3010                mActiveProcessChanges = new ProcessChangeItem[N];
3011            }
3012            mPendingProcessChanges.toArray(mActiveProcessChanges);
3013            mAvailProcessChanges.addAll(mPendingProcessChanges);
3014            mPendingProcessChanges.clear();
3015            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3016        }
3017
3018        int i = mProcessObservers.beginBroadcast();
3019        while (i > 0) {
3020            i--;
3021            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3022            if (observer != null) {
3023                try {
3024                    for (int j=0; j<N; j++) {
3025                        ProcessChangeItem item = mActiveProcessChanges[j];
3026                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3027                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3028                                    + item.pid + " uid=" + item.uid + ": "
3029                                    + item.foregroundActivities);
3030                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3031                                    item.foregroundActivities);
3032                        }
3033                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3034                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3035                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3036                            observer.onImportanceChanged(item.pid, item.uid,
3037                                    item.importance);
3038                        }
3039                    }
3040                } catch (RemoteException e) {
3041                }
3042            }
3043        }
3044        mProcessObservers.finishBroadcast();
3045    }
3046
3047    private void dispatchProcessDied(int pid, int uid) {
3048        int i = mProcessObservers.beginBroadcast();
3049        while (i > 0) {
3050            i--;
3051            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3052            if (observer != null) {
3053                try {
3054                    observer.onProcessDied(pid, uid);
3055                } catch (RemoteException e) {
3056                }
3057            }
3058        }
3059        mProcessObservers.finishBroadcast();
3060    }
3061
3062    final void doPendingActivityLaunchesLocked(boolean doResume) {
3063        final int N = mPendingActivityLaunches.size();
3064        if (N <= 0) {
3065            return;
3066        }
3067        for (int i=0; i<N; i++) {
3068            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3069            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3070                    doResume && i == (N-1), null);
3071        }
3072        mPendingActivityLaunches.clear();
3073    }
3074
3075    @Override
3076    public final int startActivity(IApplicationThread caller, String callingPackage,
3077            Intent intent, String resolvedType, IBinder resultTo,
3078            String resultWho, int requestCode, int startFlags,
3079            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3080        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3081                resultWho, requestCode,
3082                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3083    }
3084
3085    @Override
3086    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3087            Intent intent, String resolvedType, IBinder resultTo,
3088            String resultWho, int requestCode, int startFlags,
3089            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3090        enforceNotIsolatedCaller("startActivity");
3091        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3092                false, true, "startActivity", null);
3093        // TODO: Switch to user app stacks here.
3094        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3095                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3096                null, null, options, userId, null);
3097    }
3098
3099    @Override
3100    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3101            Intent intent, String resolvedType, IBinder resultTo,
3102            String resultWho, int requestCode, int startFlags, String profileFile,
3103            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3104        enforceNotIsolatedCaller("startActivityAndWait");
3105        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3106                false, true, "startActivityAndWait", null);
3107        WaitResult res = new WaitResult();
3108        // TODO: Switch to user app stacks here.
3109        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3110                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3111                res, null, options, UserHandle.getCallingUserId(), null);
3112        return res;
3113    }
3114
3115    @Override
3116    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3117            Intent intent, String resolvedType, IBinder resultTo,
3118            String resultWho, int requestCode, int startFlags, Configuration config,
3119            Bundle options, int userId) {
3120        enforceNotIsolatedCaller("startActivityWithConfig");
3121        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3122                false, true, "startActivityWithConfig", null);
3123        // TODO: Switch to user app stacks here.
3124        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3125                resolvedType, resultTo, resultWho, requestCode, startFlags,
3126                null, null, null, config, options, userId, null);
3127        return ret;
3128    }
3129
3130    @Override
3131    public int startActivityIntentSender(IApplicationThread caller,
3132            IntentSender intent, Intent fillInIntent, String resolvedType,
3133            IBinder resultTo, String resultWho, int requestCode,
3134            int flagsMask, int flagsValues, Bundle options) {
3135        enforceNotIsolatedCaller("startActivityIntentSender");
3136        // Refuse possible leaked file descriptors
3137        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3138            throw new IllegalArgumentException("File descriptors passed in Intent");
3139        }
3140
3141        IIntentSender sender = intent.getTarget();
3142        if (!(sender instanceof PendingIntentRecord)) {
3143            throw new IllegalArgumentException("Bad PendingIntent object");
3144        }
3145
3146        PendingIntentRecord pir = (PendingIntentRecord)sender;
3147
3148        synchronized (this) {
3149            // If this is coming from the currently resumed activity, it is
3150            // effectively saying that app switches are allowed at this point.
3151            final ActivityStack stack = getFocusedStack();
3152            if (stack.mResumedActivity != null &&
3153                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3154                mAppSwitchesAllowedTime = 0;
3155            }
3156        }
3157        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3158                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3159        return ret;
3160    }
3161
3162    @Override
3163    public boolean startNextMatchingActivity(IBinder callingActivity,
3164            Intent intent, Bundle options) {
3165        // Refuse possible leaked file descriptors
3166        if (intent != null && intent.hasFileDescriptors() == true) {
3167            throw new IllegalArgumentException("File descriptors passed in Intent");
3168        }
3169
3170        synchronized (this) {
3171            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3172            if (r == null) {
3173                ActivityOptions.abort(options);
3174                return false;
3175            }
3176            if (r.app == null || r.app.thread == null) {
3177                // The caller is not running...  d'oh!
3178                ActivityOptions.abort(options);
3179                return false;
3180            }
3181            intent = new Intent(intent);
3182            // The caller is not allowed to change the data.
3183            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3184            // And we are resetting to find the next component...
3185            intent.setComponent(null);
3186
3187            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3188
3189            ActivityInfo aInfo = null;
3190            try {
3191                List<ResolveInfo> resolves =
3192                    AppGlobals.getPackageManager().queryIntentActivities(
3193                            intent, r.resolvedType,
3194                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3195                            UserHandle.getCallingUserId());
3196
3197                // Look for the original activity in the list...
3198                final int N = resolves != null ? resolves.size() : 0;
3199                for (int i=0; i<N; i++) {
3200                    ResolveInfo rInfo = resolves.get(i);
3201                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3202                            && rInfo.activityInfo.name.equals(r.info.name)) {
3203                        // We found the current one...  the next matching is
3204                        // after it.
3205                        i++;
3206                        if (i<N) {
3207                            aInfo = resolves.get(i).activityInfo;
3208                        }
3209                        if (debug) {
3210                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3211                                    + "/" + r.info.name);
3212                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3213                                    + "/" + aInfo.name);
3214                        }
3215                        break;
3216                    }
3217                }
3218            } catch (RemoteException e) {
3219            }
3220
3221            if (aInfo == null) {
3222                // Nobody who is next!
3223                ActivityOptions.abort(options);
3224                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3225                return false;
3226            }
3227
3228            intent.setComponent(new ComponentName(
3229                    aInfo.applicationInfo.packageName, aInfo.name));
3230            intent.setFlags(intent.getFlags()&~(
3231                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3232                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3233                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3234                    Intent.FLAG_ACTIVITY_NEW_TASK));
3235
3236            // Okay now we need to start the new activity, replacing the
3237            // currently running activity.  This is a little tricky because
3238            // we want to start the new one as if the current one is finished,
3239            // but not finish the current one first so that there is no flicker.
3240            // And thus...
3241            final boolean wasFinishing = r.finishing;
3242            r.finishing = true;
3243
3244            // Propagate reply information over to the new activity.
3245            final ActivityRecord resultTo = r.resultTo;
3246            final String resultWho = r.resultWho;
3247            final int requestCode = r.requestCode;
3248            r.resultTo = null;
3249            if (resultTo != null) {
3250                resultTo.removeResultsLocked(r, resultWho, requestCode);
3251            }
3252
3253            final long origId = Binder.clearCallingIdentity();
3254            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3255                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3256                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3257                    options, false, null, null);
3258            Binder.restoreCallingIdentity(origId);
3259
3260            r.finishing = wasFinishing;
3261            if (res != ActivityManager.START_SUCCESS) {
3262                return false;
3263            }
3264            return true;
3265        }
3266    }
3267
3268    final int startActivityInPackage(int uid, String callingPackage,
3269            Intent intent, String resolvedType, IBinder resultTo,
3270            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3271                    IActivityContainer container) {
3272
3273        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3274                false, true, "startActivityInPackage", null);
3275
3276        // TODO: Switch to user app stacks here.
3277        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3278                resultTo, resultWho, requestCode, startFlags,
3279                null, null, null, null, options, userId, container);
3280        return ret;
3281    }
3282
3283    @Override
3284    public final int startActivities(IApplicationThread caller, String callingPackage,
3285            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3286            int userId) {
3287        enforceNotIsolatedCaller("startActivities");
3288        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3289                false, true, "startActivity", null);
3290        // TODO: Switch to user app stacks here.
3291        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3292                resolvedTypes, resultTo, options, userId);
3293        return ret;
3294    }
3295
3296    final int startActivitiesInPackage(int uid, String callingPackage,
3297            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3298            Bundle options, int userId) {
3299
3300        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3301                false, true, "startActivityInPackage", null);
3302        // TODO: Switch to user app stacks here.
3303        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3304                resultTo, options, userId);
3305        return ret;
3306    }
3307
3308    final void addRecentTaskLocked(TaskRecord task) {
3309        int N = mRecentTasks.size();
3310        // Quick case: check if the top-most recent task is the same.
3311        if (N > 0 && mRecentTasks.get(0) == task) {
3312            return;
3313        }
3314        // Remove any existing entries that are the same kind of task.
3315        for (int i=0; i<N; i++) {
3316            TaskRecord tr = mRecentTasks.get(i);
3317            if (task.userId == tr.userId
3318                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3319                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3320                tr.disposeThumbnail();
3321                mRecentTasks.remove(i);
3322                i--;
3323                N--;
3324                if (task.intent == null) {
3325                    // If the new recent task we are adding is not fully
3326                    // specified, then replace it with the existing recent task.
3327                    task = tr;
3328                }
3329            }
3330        }
3331        if (N >= MAX_RECENT_TASKS) {
3332            mRecentTasks.remove(N-1).disposeThumbnail();
3333        }
3334        mRecentTasks.add(0, task);
3335    }
3336
3337    @Override
3338    public void reportActivityFullyDrawn(IBinder token) {
3339        synchronized (this) {
3340            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3341            if (r == null) {
3342                return;
3343            }
3344            r.reportFullyDrawnLocked();
3345        }
3346    }
3347
3348    @Override
3349    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3350        synchronized (this) {
3351            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3352            if (r == null) {
3353                return;
3354            }
3355            final long origId = Binder.clearCallingIdentity();
3356            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3357            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3358                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3359            if (config != null) {
3360                r.frozenBeforeDestroy = true;
3361                if (!updateConfigurationLocked(config, r, false, false)) {
3362                    mStackSupervisor.resumeTopActivitiesLocked();
3363                }
3364            }
3365            Binder.restoreCallingIdentity(origId);
3366        }
3367    }
3368
3369    @Override
3370    public int getRequestedOrientation(IBinder token) {
3371        synchronized (this) {
3372            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3373            if (r == null) {
3374                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3375            }
3376            return mWindowManager.getAppOrientation(r.appToken);
3377        }
3378    }
3379
3380    /**
3381     * This is the internal entry point for handling Activity.finish().
3382     *
3383     * @param token The Binder token referencing the Activity we want to finish.
3384     * @param resultCode Result code, if any, from this Activity.
3385     * @param resultData Result data (Intent), if any, from this Activity.
3386     *
3387     * @return Returns true if the activity successfully finished, or false if it is still running.
3388     */
3389    @Override
3390    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3391        // Refuse possible leaked file descriptors
3392        if (resultData != null && resultData.hasFileDescriptors() == true) {
3393            throw new IllegalArgumentException("File descriptors passed in Intent");
3394        }
3395
3396        synchronized(this) {
3397            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3398            if (r == null) {
3399                return true;
3400            }
3401            if (mController != null) {
3402                // Find the first activity that is not finishing.
3403                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3404                if (next != null) {
3405                    // ask watcher if this is allowed
3406                    boolean resumeOK = true;
3407                    try {
3408                        resumeOK = mController.activityResuming(next.packageName);
3409                    } catch (RemoteException e) {
3410                        mController = null;
3411                        Watchdog.getInstance().setActivityController(null);
3412                    }
3413
3414                    if (!resumeOK) {
3415                        return false;
3416                    }
3417                }
3418            }
3419            final long origId = Binder.clearCallingIdentity();
3420            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3421                    resultData, "app-request", true);
3422            Binder.restoreCallingIdentity(origId);
3423            return res;
3424        }
3425    }
3426
3427    @Override
3428    public final void finishHeavyWeightApp() {
3429        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3430                != PackageManager.PERMISSION_GRANTED) {
3431            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3432                    + Binder.getCallingPid()
3433                    + ", uid=" + Binder.getCallingUid()
3434                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3435            Slog.w(TAG, msg);
3436            throw new SecurityException(msg);
3437        }
3438
3439        synchronized(this) {
3440            if (mHeavyWeightProcess == null) {
3441                return;
3442            }
3443
3444            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3445                    mHeavyWeightProcess.activities);
3446            for (int i=0; i<activities.size(); i++) {
3447                ActivityRecord r = activities.get(i);
3448                if (!r.finishing) {
3449                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3450                            null, "finish-heavy", true);
3451                }
3452            }
3453
3454            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3455                    mHeavyWeightProcess.userId, 0));
3456            mHeavyWeightProcess = null;
3457        }
3458    }
3459
3460    @Override
3461    public void crashApplication(int uid, int initialPid, String packageName,
3462            String message) {
3463        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3464                != PackageManager.PERMISSION_GRANTED) {
3465            String msg = "Permission Denial: crashApplication() from pid="
3466                    + Binder.getCallingPid()
3467                    + ", uid=" + Binder.getCallingUid()
3468                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3469            Slog.w(TAG, msg);
3470            throw new SecurityException(msg);
3471        }
3472
3473        synchronized(this) {
3474            ProcessRecord proc = null;
3475
3476            // Figure out which process to kill.  We don't trust that initialPid
3477            // still has any relation to current pids, so must scan through the
3478            // list.
3479            synchronized (mPidsSelfLocked) {
3480                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3481                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3482                    if (p.uid != uid) {
3483                        continue;
3484                    }
3485                    if (p.pid == initialPid) {
3486                        proc = p;
3487                        break;
3488                    }
3489                    if (p.pkgList.containsKey(packageName)) {
3490                        proc = p;
3491                    }
3492                }
3493            }
3494
3495            if (proc == null) {
3496                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3497                        + " initialPid=" + initialPid
3498                        + " packageName=" + packageName);
3499                return;
3500            }
3501
3502            if (proc.thread != null) {
3503                if (proc.pid == Process.myPid()) {
3504                    Log.w(TAG, "crashApplication: trying to crash self!");
3505                    return;
3506                }
3507                long ident = Binder.clearCallingIdentity();
3508                try {
3509                    proc.thread.scheduleCrash(message);
3510                } catch (RemoteException e) {
3511                }
3512                Binder.restoreCallingIdentity(ident);
3513            }
3514        }
3515    }
3516
3517    @Override
3518    public final void finishSubActivity(IBinder token, String resultWho,
3519            int requestCode) {
3520        synchronized(this) {
3521            final long origId = Binder.clearCallingIdentity();
3522            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3523            if (r != null) {
3524                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3525            }
3526            Binder.restoreCallingIdentity(origId);
3527        }
3528    }
3529
3530    @Override
3531    public boolean finishActivityAffinity(IBinder token) {
3532        synchronized(this) {
3533            final long origId = Binder.clearCallingIdentity();
3534            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3535            boolean res = false;
3536            if (r != null) {
3537                res = r.task.stack.finishActivityAffinityLocked(r);
3538            }
3539            Binder.restoreCallingIdentity(origId);
3540            return res;
3541        }
3542    }
3543
3544    @Override
3545    public boolean willActivityBeVisible(IBinder token) {
3546        synchronized(this) {
3547            ActivityStack stack = ActivityRecord.getStackLocked(token);
3548            if (stack != null) {
3549                return stack.willActivityBeVisibleLocked(token);
3550            }
3551            return false;
3552        }
3553    }
3554
3555    @Override
3556    public void overridePendingTransition(IBinder token, String packageName,
3557            int enterAnim, int exitAnim) {
3558        synchronized(this) {
3559            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3560            if (self == null) {
3561                return;
3562            }
3563
3564            final long origId = Binder.clearCallingIdentity();
3565
3566            if (self.state == ActivityState.RESUMED
3567                    || self.state == ActivityState.PAUSING) {
3568                mWindowManager.overridePendingAppTransition(packageName,
3569                        enterAnim, exitAnim, null);
3570            }
3571
3572            Binder.restoreCallingIdentity(origId);
3573        }
3574    }
3575
3576    /**
3577     * Main function for removing an existing process from the activity manager
3578     * as a result of that process going away.  Clears out all connections
3579     * to the process.
3580     */
3581    private final void handleAppDiedLocked(ProcessRecord app,
3582            boolean restarting, boolean allowRestart) {
3583        int pid = app.pid;
3584        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3585        if (!restarting) {
3586            removeLruProcessLocked(app);
3587            if (pid > 0) {
3588                ProcessList.remove(pid);
3589            }
3590        }
3591
3592        if (mProfileProc == app) {
3593            clearProfilerLocked();
3594        }
3595
3596        // Remove this application's activities from active lists.
3597        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3598
3599        app.activities.clear();
3600
3601        if (app.instrumentationClass != null) {
3602            Slog.w(TAG, "Crash of app " + app.processName
3603                  + " running instrumentation " + app.instrumentationClass);
3604            Bundle info = new Bundle();
3605            info.putString("shortMsg", "Process crashed.");
3606            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3607        }
3608
3609        if (!restarting) {
3610            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3611                // If there was nothing to resume, and we are not already
3612                // restarting this process, but there is a visible activity that
3613                // is hosted by the process...  then make sure all visible
3614                // activities are running, taking care of restarting this
3615                // process.
3616                if (hasVisibleActivities) {
3617                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3618                }
3619            }
3620        }
3621    }
3622
3623    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3624        IBinder threadBinder = thread.asBinder();
3625        // Find the application record.
3626        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3627            ProcessRecord rec = mLruProcesses.get(i);
3628            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3629                return i;
3630            }
3631        }
3632        return -1;
3633    }
3634
3635    final ProcessRecord getRecordForAppLocked(
3636            IApplicationThread thread) {
3637        if (thread == null) {
3638            return null;
3639        }
3640
3641        int appIndex = getLRURecordIndexForAppLocked(thread);
3642        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3643    }
3644
3645    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3646        // If there are no longer any background processes running,
3647        // and the app that died was not running instrumentation,
3648        // then tell everyone we are now low on memory.
3649        boolean haveBg = false;
3650        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3651            ProcessRecord rec = mLruProcesses.get(i);
3652            if (rec.thread != null
3653                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3654                haveBg = true;
3655                break;
3656            }
3657        }
3658
3659        if (!haveBg) {
3660            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3661            if (doReport) {
3662                long now = SystemClock.uptimeMillis();
3663                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3664                    doReport = false;
3665                } else {
3666                    mLastMemUsageReportTime = now;
3667                }
3668            }
3669            final ArrayList<ProcessMemInfo> memInfos
3670                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3671            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3672            long now = SystemClock.uptimeMillis();
3673            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3674                ProcessRecord rec = mLruProcesses.get(i);
3675                if (rec == dyingProc || rec.thread == null) {
3676                    continue;
3677                }
3678                if (doReport) {
3679                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3680                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3681                }
3682                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3683                    // The low memory report is overriding any current
3684                    // state for a GC request.  Make sure to do
3685                    // heavy/important/visible/foreground processes first.
3686                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3687                        rec.lastRequestedGc = 0;
3688                    } else {
3689                        rec.lastRequestedGc = rec.lastLowMemory;
3690                    }
3691                    rec.reportLowMemory = true;
3692                    rec.lastLowMemory = now;
3693                    mProcessesToGc.remove(rec);
3694                    addProcessToGcListLocked(rec);
3695                }
3696            }
3697            if (doReport) {
3698                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3699                mHandler.sendMessage(msg);
3700            }
3701            scheduleAppGcsLocked();
3702        }
3703    }
3704
3705    final void appDiedLocked(ProcessRecord app, int pid,
3706            IApplicationThread thread) {
3707
3708        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3709        synchronized (stats) {
3710            stats.noteProcessDiedLocked(app.info.uid, pid);
3711        }
3712
3713        // Clean up already done if the process has been re-started.
3714        if (app.pid == pid && app.thread != null &&
3715                app.thread.asBinder() == thread.asBinder()) {
3716            boolean doLowMem = app.instrumentationClass == null;
3717            boolean doOomAdj = doLowMem;
3718            if (!app.killedByAm) {
3719                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3720                        + ") has died.");
3721                mAllowLowerMemLevel = true;
3722            } else {
3723                // Note that we always want to do oom adj to update our state with the
3724                // new number of procs.
3725                mAllowLowerMemLevel = false;
3726                doLowMem = false;
3727            }
3728            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3729            if (DEBUG_CLEANUP) Slog.v(
3730                TAG, "Dying app: " + app + ", pid: " + pid
3731                + ", thread: " + thread.asBinder());
3732            handleAppDiedLocked(app, false, true);
3733
3734            if (doOomAdj) {
3735                updateOomAdjLocked();
3736            }
3737            if (doLowMem) {
3738                doLowMemReportIfNeededLocked(app);
3739            }
3740        } else if (app.pid != pid) {
3741            // A new process has already been started.
3742            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3743                    + ") has died and restarted (pid " + app.pid + ").");
3744            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3745        } else if (DEBUG_PROCESSES) {
3746            Slog.d(TAG, "Received spurious death notification for thread "
3747                    + thread.asBinder());
3748        }
3749    }
3750
3751    /**
3752     * If a stack trace dump file is configured, dump process stack traces.
3753     * @param clearTraces causes the dump file to be erased prior to the new
3754     *    traces being written, if true; when false, the new traces will be
3755     *    appended to any existing file content.
3756     * @param firstPids of dalvik VM processes to dump stack traces for first
3757     * @param lastPids of dalvik VM processes to dump stack traces for last
3758     * @param nativeProcs optional list of native process names to dump stack crawls
3759     * @return file containing stack traces, or null if no dump file is configured
3760     */
3761    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3762            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3763        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3764        if (tracesPath == null || tracesPath.length() == 0) {
3765            return null;
3766        }
3767
3768        File tracesFile = new File(tracesPath);
3769        try {
3770            File tracesDir = tracesFile.getParentFile();
3771            if (!tracesDir.exists()) {
3772                tracesFile.mkdirs();
3773                if (!SELinux.restorecon(tracesDir)) {
3774                    return null;
3775                }
3776            }
3777            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3778
3779            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3780            tracesFile.createNewFile();
3781            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3782        } catch (IOException e) {
3783            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3784            return null;
3785        }
3786
3787        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3788        return tracesFile;
3789    }
3790
3791    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3792            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3793        // Use a FileObserver to detect when traces finish writing.
3794        // The order of traces is considered important to maintain for legibility.
3795        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3796            @Override
3797            public synchronized void onEvent(int event, String path) { notify(); }
3798        };
3799
3800        try {
3801            observer.startWatching();
3802
3803            // First collect all of the stacks of the most important pids.
3804            if (firstPids != null) {
3805                try {
3806                    int num = firstPids.size();
3807                    for (int i = 0; i < num; i++) {
3808                        synchronized (observer) {
3809                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3810                            observer.wait(200);  // Wait for write-close, give up after 200msec
3811                        }
3812                    }
3813                } catch (InterruptedException e) {
3814                    Log.wtf(TAG, e);
3815                }
3816            }
3817
3818            // Next collect the stacks of the native pids
3819            if (nativeProcs != null) {
3820                int[] pids = Process.getPidsForCommands(nativeProcs);
3821                if (pids != null) {
3822                    for (int pid : pids) {
3823                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3824                    }
3825                }
3826            }
3827
3828            // Lastly, measure CPU usage.
3829            if (processCpuTracker != null) {
3830                processCpuTracker.init();
3831                System.gc();
3832                processCpuTracker.update();
3833                try {
3834                    synchronized (processCpuTracker) {
3835                        processCpuTracker.wait(500); // measure over 1/2 second.
3836                    }
3837                } catch (InterruptedException e) {
3838                }
3839                processCpuTracker.update();
3840
3841                // We'll take the stack crawls of just the top apps using CPU.
3842                final int N = processCpuTracker.countWorkingStats();
3843                int numProcs = 0;
3844                for (int i=0; i<N && numProcs<5; i++) {
3845                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3846                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3847                        numProcs++;
3848                        try {
3849                            synchronized (observer) {
3850                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3851                                observer.wait(200);  // Wait for write-close, give up after 200msec
3852                            }
3853                        } catch (InterruptedException e) {
3854                            Log.wtf(TAG, e);
3855                        }
3856
3857                    }
3858                }
3859            }
3860        } finally {
3861            observer.stopWatching();
3862        }
3863    }
3864
3865    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3866        if (true || IS_USER_BUILD) {
3867            return;
3868        }
3869        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3870        if (tracesPath == null || tracesPath.length() == 0) {
3871            return;
3872        }
3873
3874        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3875        StrictMode.allowThreadDiskWrites();
3876        try {
3877            final File tracesFile = new File(tracesPath);
3878            final File tracesDir = tracesFile.getParentFile();
3879            final File tracesTmp = new File(tracesDir, "__tmp__");
3880            try {
3881                if (!tracesDir.exists()) {
3882                    tracesFile.mkdirs();
3883                    if (!SELinux.restorecon(tracesDir.getPath())) {
3884                        return;
3885                    }
3886                }
3887                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3888
3889                if (tracesFile.exists()) {
3890                    tracesTmp.delete();
3891                    tracesFile.renameTo(tracesTmp);
3892                }
3893                StringBuilder sb = new StringBuilder();
3894                Time tobj = new Time();
3895                tobj.set(System.currentTimeMillis());
3896                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3897                sb.append(": ");
3898                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3899                sb.append(" since ");
3900                sb.append(msg);
3901                FileOutputStream fos = new FileOutputStream(tracesFile);
3902                fos.write(sb.toString().getBytes());
3903                if (app == null) {
3904                    fos.write("\n*** No application process!".getBytes());
3905                }
3906                fos.close();
3907                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3908            } catch (IOException e) {
3909                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3910                return;
3911            }
3912
3913            if (app != null) {
3914                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3915                firstPids.add(app.pid);
3916                dumpStackTraces(tracesPath, firstPids, null, null, null);
3917            }
3918
3919            File lastTracesFile = null;
3920            File curTracesFile = null;
3921            for (int i=9; i>=0; i--) {
3922                String name = String.format(Locale.US, "slow%02d.txt", i);
3923                curTracesFile = new File(tracesDir, name);
3924                if (curTracesFile.exists()) {
3925                    if (lastTracesFile != null) {
3926                        curTracesFile.renameTo(lastTracesFile);
3927                    } else {
3928                        curTracesFile.delete();
3929                    }
3930                }
3931                lastTracesFile = curTracesFile;
3932            }
3933            tracesFile.renameTo(curTracesFile);
3934            if (tracesTmp.exists()) {
3935                tracesTmp.renameTo(tracesFile);
3936            }
3937        } finally {
3938            StrictMode.setThreadPolicy(oldPolicy);
3939        }
3940    }
3941
3942    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3943            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3944        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3945        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3946
3947        if (mController != null) {
3948            try {
3949                // 0 == continue, -1 = kill process immediately
3950                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3951                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3952            } catch (RemoteException e) {
3953                mController = null;
3954                Watchdog.getInstance().setActivityController(null);
3955            }
3956        }
3957
3958        long anrTime = SystemClock.uptimeMillis();
3959        if (MONITOR_CPU_USAGE) {
3960            updateCpuStatsNow();
3961        }
3962
3963        synchronized (this) {
3964            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3965            if (mShuttingDown) {
3966                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3967                return;
3968            } else if (app.notResponding) {
3969                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3970                return;
3971            } else if (app.crashing) {
3972                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3973                return;
3974            }
3975
3976            // In case we come through here for the same app before completing
3977            // this one, mark as anring now so we will bail out.
3978            app.notResponding = true;
3979
3980            // Log the ANR to the event log.
3981            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3982                    app.processName, app.info.flags, annotation);
3983
3984            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3985            firstPids.add(app.pid);
3986
3987            int parentPid = app.pid;
3988            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3989            if (parentPid != app.pid) firstPids.add(parentPid);
3990
3991            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3992
3993            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3994                ProcessRecord r = mLruProcesses.get(i);
3995                if (r != null && r.thread != null) {
3996                    int pid = r.pid;
3997                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3998                        if (r.persistent) {
3999                            firstPids.add(pid);
4000                        } else {
4001                            lastPids.put(pid, Boolean.TRUE);
4002                        }
4003                    }
4004                }
4005            }
4006        }
4007
4008        // Log the ANR to the main log.
4009        StringBuilder info = new StringBuilder();
4010        info.setLength(0);
4011        info.append("ANR in ").append(app.processName);
4012        if (activity != null && activity.shortComponentName != null) {
4013            info.append(" (").append(activity.shortComponentName).append(")");
4014        }
4015        info.append("\n");
4016        info.append("PID: ").append(app.pid).append("\n");
4017        if (annotation != null) {
4018            info.append("Reason: ").append(annotation).append("\n");
4019        }
4020        if (parent != null && parent != activity) {
4021            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4022        }
4023
4024        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4025
4026        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4027                NATIVE_STACKS_OF_INTEREST);
4028
4029        String cpuInfo = null;
4030        if (MONITOR_CPU_USAGE) {
4031            updateCpuStatsNow();
4032            synchronized (mProcessCpuThread) {
4033                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4034            }
4035            info.append(processCpuTracker.printCurrentLoad());
4036            info.append(cpuInfo);
4037        }
4038
4039        info.append(processCpuTracker.printCurrentState(anrTime));
4040
4041        Slog.e(TAG, info.toString());
4042        if (tracesFile == null) {
4043            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4044            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4045        }
4046
4047        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4048                cpuInfo, tracesFile, null);
4049
4050        if (mController != null) {
4051            try {
4052                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4053                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4054                if (res != 0) {
4055                    if (res < 0 && app.pid != MY_PID) {
4056                        Process.killProcess(app.pid);
4057                    } else {
4058                        synchronized (this) {
4059                            mServices.scheduleServiceTimeoutLocked(app);
4060                        }
4061                    }
4062                    return;
4063                }
4064            } catch (RemoteException e) {
4065                mController = null;
4066                Watchdog.getInstance().setActivityController(null);
4067            }
4068        }
4069
4070        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4071        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4072                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4073
4074        synchronized (this) {
4075            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4076                killUnneededProcessLocked(app, "background ANR");
4077                return;
4078            }
4079
4080            // Set the app's notResponding state, and look up the errorReportReceiver
4081            makeAppNotRespondingLocked(app,
4082                    activity != null ? activity.shortComponentName : null,
4083                    annotation != null ? "ANR " + annotation : "ANR",
4084                    info.toString());
4085
4086            // Bring up the infamous App Not Responding dialog
4087            Message msg = Message.obtain();
4088            HashMap<String, Object> map = new HashMap<String, Object>();
4089            msg.what = SHOW_NOT_RESPONDING_MSG;
4090            msg.obj = map;
4091            msg.arg1 = aboveSystem ? 1 : 0;
4092            map.put("app", app);
4093            if (activity != null) {
4094                map.put("activity", activity);
4095            }
4096
4097            mHandler.sendMessage(msg);
4098        }
4099    }
4100
4101    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4102        if (!mLaunchWarningShown) {
4103            mLaunchWarningShown = true;
4104            mHandler.post(new Runnable() {
4105                @Override
4106                public void run() {
4107                    synchronized (ActivityManagerService.this) {
4108                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4109                        d.show();
4110                        mHandler.postDelayed(new Runnable() {
4111                            @Override
4112                            public void run() {
4113                                synchronized (ActivityManagerService.this) {
4114                                    d.dismiss();
4115                                    mLaunchWarningShown = false;
4116                                }
4117                            }
4118                        }, 4000);
4119                    }
4120                }
4121            });
4122        }
4123    }
4124
4125    @Override
4126    public boolean clearApplicationUserData(final String packageName,
4127            final IPackageDataObserver observer, int userId) {
4128        enforceNotIsolatedCaller("clearApplicationUserData");
4129        int uid = Binder.getCallingUid();
4130        int pid = Binder.getCallingPid();
4131        userId = handleIncomingUser(pid, uid,
4132                userId, false, true, "clearApplicationUserData", null);
4133        long callingId = Binder.clearCallingIdentity();
4134        try {
4135            IPackageManager pm = AppGlobals.getPackageManager();
4136            int pkgUid = -1;
4137            synchronized(this) {
4138                try {
4139                    pkgUid = pm.getPackageUid(packageName, userId);
4140                } catch (RemoteException e) {
4141                }
4142                if (pkgUid == -1) {
4143                    Slog.w(TAG, "Invalid packageName: " + packageName);
4144                    if (observer != null) {
4145                        try {
4146                            observer.onRemoveCompleted(packageName, false);
4147                        } catch (RemoteException e) {
4148                            Slog.i(TAG, "Observer no longer exists.");
4149                        }
4150                    }
4151                    return false;
4152                }
4153                if (uid == pkgUid || checkComponentPermission(
4154                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4155                        pid, uid, -1, true)
4156                        == PackageManager.PERMISSION_GRANTED) {
4157                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4158                } else {
4159                    throw new SecurityException("PID " + pid + " does not have permission "
4160                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4161                                    + " of package " + packageName);
4162                }
4163            }
4164
4165            try {
4166                // Clear application user data
4167                pm.clearApplicationUserData(packageName, observer, userId);
4168
4169                // Remove all permissions granted from/to this package
4170                removeUriPermissionsForPackageLocked(packageName, userId, true);
4171
4172                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4173                        Uri.fromParts("package", packageName, null));
4174                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4175                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4176                        null, null, 0, null, null, null, false, false, userId);
4177            } catch (RemoteException e) {
4178            }
4179        } finally {
4180            Binder.restoreCallingIdentity(callingId);
4181        }
4182        return true;
4183    }
4184
4185    @Override
4186    public void killBackgroundProcesses(final String packageName, int userId) {
4187        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4188                != PackageManager.PERMISSION_GRANTED &&
4189                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4190                        != PackageManager.PERMISSION_GRANTED) {
4191            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4192                    + Binder.getCallingPid()
4193                    + ", uid=" + Binder.getCallingUid()
4194                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4195            Slog.w(TAG, msg);
4196            throw new SecurityException(msg);
4197        }
4198
4199        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4200                userId, true, true, "killBackgroundProcesses", null);
4201        long callingId = Binder.clearCallingIdentity();
4202        try {
4203            IPackageManager pm = AppGlobals.getPackageManager();
4204            synchronized(this) {
4205                int appId = -1;
4206                try {
4207                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4208                } catch (RemoteException e) {
4209                }
4210                if (appId == -1) {
4211                    Slog.w(TAG, "Invalid packageName: " + packageName);
4212                    return;
4213                }
4214                killPackageProcessesLocked(packageName, appId, userId,
4215                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4216            }
4217        } finally {
4218            Binder.restoreCallingIdentity(callingId);
4219        }
4220    }
4221
4222    @Override
4223    public void killAllBackgroundProcesses() {
4224        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4225                != PackageManager.PERMISSION_GRANTED) {
4226            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4227                    + Binder.getCallingPid()
4228                    + ", uid=" + Binder.getCallingUid()
4229                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4230            Slog.w(TAG, msg);
4231            throw new SecurityException(msg);
4232        }
4233
4234        long callingId = Binder.clearCallingIdentity();
4235        try {
4236            synchronized(this) {
4237                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4238                final int NP = mProcessNames.getMap().size();
4239                for (int ip=0; ip<NP; ip++) {
4240                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4241                    final int NA = apps.size();
4242                    for (int ia=0; ia<NA; ia++) {
4243                        ProcessRecord app = apps.valueAt(ia);
4244                        if (app.persistent) {
4245                            // we don't kill persistent processes
4246                            continue;
4247                        }
4248                        if (app.removed) {
4249                            procs.add(app);
4250                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4251                            app.removed = true;
4252                            procs.add(app);
4253                        }
4254                    }
4255                }
4256
4257                int N = procs.size();
4258                for (int i=0; i<N; i++) {
4259                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4260                }
4261                mAllowLowerMemLevel = true;
4262                updateOomAdjLocked();
4263                doLowMemReportIfNeededLocked(null);
4264            }
4265        } finally {
4266            Binder.restoreCallingIdentity(callingId);
4267        }
4268    }
4269
4270    @Override
4271    public void forceStopPackage(final String packageName, int userId) {
4272        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4273                != PackageManager.PERMISSION_GRANTED) {
4274            String msg = "Permission Denial: forceStopPackage() from pid="
4275                    + Binder.getCallingPid()
4276                    + ", uid=" + Binder.getCallingUid()
4277                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4278            Slog.w(TAG, msg);
4279            throw new SecurityException(msg);
4280        }
4281        final int callingPid = Binder.getCallingPid();
4282        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4283                userId, true, true, "forceStopPackage", null);
4284        long callingId = Binder.clearCallingIdentity();
4285        try {
4286            IPackageManager pm = AppGlobals.getPackageManager();
4287            synchronized(this) {
4288                int[] users = userId == UserHandle.USER_ALL
4289                        ? getUsersLocked() : new int[] { userId };
4290                for (int user : users) {
4291                    int pkgUid = -1;
4292                    try {
4293                        pkgUid = pm.getPackageUid(packageName, user);
4294                    } catch (RemoteException e) {
4295                    }
4296                    if (pkgUid == -1) {
4297                        Slog.w(TAG, "Invalid packageName: " + packageName);
4298                        continue;
4299                    }
4300                    try {
4301                        pm.setPackageStoppedState(packageName, true, user);
4302                    } catch (RemoteException e) {
4303                    } catch (IllegalArgumentException e) {
4304                        Slog.w(TAG, "Failed trying to unstop package "
4305                                + packageName + ": " + e);
4306                    }
4307                    if (isUserRunningLocked(user, false)) {
4308                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4309                    }
4310                }
4311            }
4312        } finally {
4313            Binder.restoreCallingIdentity(callingId);
4314        }
4315    }
4316
4317    /*
4318     * The pkg name and app id have to be specified.
4319     */
4320    @Override
4321    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4322        if (pkg == null) {
4323            return;
4324        }
4325        // Make sure the uid is valid.
4326        if (appid < 0) {
4327            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4328            return;
4329        }
4330        int callerUid = Binder.getCallingUid();
4331        // Only the system server can kill an application
4332        if (callerUid == Process.SYSTEM_UID) {
4333            // Post an aysnc message to kill the application
4334            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4335            msg.arg1 = appid;
4336            msg.arg2 = 0;
4337            Bundle bundle = new Bundle();
4338            bundle.putString("pkg", pkg);
4339            bundle.putString("reason", reason);
4340            msg.obj = bundle;
4341            mHandler.sendMessage(msg);
4342        } else {
4343            throw new SecurityException(callerUid + " cannot kill pkg: " +
4344                    pkg);
4345        }
4346    }
4347
4348    @Override
4349    public void closeSystemDialogs(String reason) {
4350        enforceNotIsolatedCaller("closeSystemDialogs");
4351
4352        final int pid = Binder.getCallingPid();
4353        final int uid = Binder.getCallingUid();
4354        final long origId = Binder.clearCallingIdentity();
4355        try {
4356            synchronized (this) {
4357                // Only allow this from foreground processes, so that background
4358                // applications can't abuse it to prevent system UI from being shown.
4359                if (uid >= Process.FIRST_APPLICATION_UID) {
4360                    ProcessRecord proc;
4361                    synchronized (mPidsSelfLocked) {
4362                        proc = mPidsSelfLocked.get(pid);
4363                    }
4364                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4365                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4366                                + " from background process " + proc);
4367                        return;
4368                    }
4369                }
4370                closeSystemDialogsLocked(reason);
4371            }
4372        } finally {
4373            Binder.restoreCallingIdentity(origId);
4374        }
4375    }
4376
4377    void closeSystemDialogsLocked(String reason) {
4378        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4379        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4380                | Intent.FLAG_RECEIVER_FOREGROUND);
4381        if (reason != null) {
4382            intent.putExtra("reason", reason);
4383        }
4384        mWindowManager.closeSystemDialogs(reason);
4385
4386        mStackSupervisor.closeSystemDialogsLocked();
4387
4388        broadcastIntentLocked(null, null, intent, null,
4389                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4390                Process.SYSTEM_UID, UserHandle.USER_ALL);
4391    }
4392
4393    @Override
4394    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4395        enforceNotIsolatedCaller("getProcessMemoryInfo");
4396        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4397        for (int i=pids.length-1; i>=0; i--) {
4398            ProcessRecord proc;
4399            int oomAdj;
4400            synchronized (this) {
4401                synchronized (mPidsSelfLocked) {
4402                    proc = mPidsSelfLocked.get(pids[i]);
4403                    oomAdj = proc != null ? proc.setAdj : 0;
4404                }
4405            }
4406            infos[i] = new Debug.MemoryInfo();
4407            Debug.getMemoryInfo(pids[i], infos[i]);
4408            if (proc != null) {
4409                synchronized (this) {
4410                    if (proc.thread != null && proc.setAdj == oomAdj) {
4411                        // Record this for posterity if the process has been stable.
4412                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4413                                infos[i].getTotalUss(), false, proc.pkgList);
4414                    }
4415                }
4416            }
4417        }
4418        return infos;
4419    }
4420
4421    @Override
4422    public long[] getProcessPss(int[] pids) {
4423        enforceNotIsolatedCaller("getProcessPss");
4424        long[] pss = new long[pids.length];
4425        for (int i=pids.length-1; i>=0; i--) {
4426            ProcessRecord proc;
4427            int oomAdj;
4428            synchronized (this) {
4429                synchronized (mPidsSelfLocked) {
4430                    proc = mPidsSelfLocked.get(pids[i]);
4431                    oomAdj = proc != null ? proc.setAdj : 0;
4432                }
4433            }
4434            long[] tmpUss = new long[1];
4435            pss[i] = Debug.getPss(pids[i], tmpUss);
4436            if (proc != null) {
4437                synchronized (this) {
4438                    if (proc.thread != null && proc.setAdj == oomAdj) {
4439                        // Record this for posterity if the process has been stable.
4440                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4441                    }
4442                }
4443            }
4444        }
4445        return pss;
4446    }
4447
4448    @Override
4449    public void killApplicationProcess(String processName, int uid) {
4450        if (processName == null) {
4451            return;
4452        }
4453
4454        int callerUid = Binder.getCallingUid();
4455        // Only the system server can kill an application
4456        if (callerUid == Process.SYSTEM_UID) {
4457            synchronized (this) {
4458                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4459                if (app != null && app.thread != null) {
4460                    try {
4461                        app.thread.scheduleSuicide();
4462                    } catch (RemoteException e) {
4463                        // If the other end already died, then our work here is done.
4464                    }
4465                } else {
4466                    Slog.w(TAG, "Process/uid not found attempting kill of "
4467                            + processName + " / " + uid);
4468                }
4469            }
4470        } else {
4471            throw new SecurityException(callerUid + " cannot kill app process: " +
4472                    processName);
4473        }
4474    }
4475
4476    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4477        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4478                false, true, false, UserHandle.getUserId(uid), reason);
4479        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4480                Uri.fromParts("package", packageName, null));
4481        if (!mProcessesReady) {
4482            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4483                    | Intent.FLAG_RECEIVER_FOREGROUND);
4484        }
4485        intent.putExtra(Intent.EXTRA_UID, uid);
4486        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4487        broadcastIntentLocked(null, null, intent,
4488                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4489                false, false,
4490                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4491    }
4492
4493    private void forceStopUserLocked(int userId, String reason) {
4494        forceStopPackageLocked(null, -1, false, false, true, false, userId, reason);
4495        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4496        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4497                | Intent.FLAG_RECEIVER_FOREGROUND);
4498        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4499        broadcastIntentLocked(null, null, intent,
4500                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4501                false, false,
4502                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4503    }
4504
4505    private final boolean killPackageProcessesLocked(String packageName, int appId,
4506            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4507            boolean doit, boolean evenPersistent, String reason) {
4508        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4509
4510        // Remove all processes this package may have touched: all with the
4511        // same UID (except for the system or root user), and all whose name
4512        // matches the package name.
4513        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4514        final int NP = mProcessNames.getMap().size();
4515        for (int ip=0; ip<NP; ip++) {
4516            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4517            final int NA = apps.size();
4518            for (int ia=0; ia<NA; ia++) {
4519                ProcessRecord app = apps.valueAt(ia);
4520                if (app.persistent && !evenPersistent) {
4521                    // we don't kill persistent processes
4522                    continue;
4523                }
4524                if (app.removed) {
4525                    if (doit) {
4526                        procs.add(app);
4527                    }
4528                    continue;
4529                }
4530
4531                // Skip process if it doesn't meet our oom adj requirement.
4532                if (app.setAdj < minOomAdj) {
4533                    continue;
4534                }
4535
4536                // If no package is specified, we call all processes under the
4537                // give user id.
4538                if (packageName == null) {
4539                    if (app.userId != userId) {
4540                        continue;
4541                    }
4542                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4543                        continue;
4544                    }
4545                // Package has been specified, we want to hit all processes
4546                // that match it.  We need to qualify this by the processes
4547                // that are running under the specified app and user ID.
4548                } else {
4549                    if (UserHandle.getAppId(app.uid) != appId) {
4550                        continue;
4551                    }
4552                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4553                        continue;
4554                    }
4555                    if (!app.pkgList.containsKey(packageName)) {
4556                        continue;
4557                    }
4558                }
4559
4560                // Process has passed all conditions, kill it!
4561                if (!doit) {
4562                    return true;
4563                }
4564                app.removed = true;
4565                procs.add(app);
4566            }
4567        }
4568
4569        int N = procs.size();
4570        for (int i=0; i<N; i++) {
4571            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4572        }
4573        updateOomAdjLocked();
4574        return N > 0;
4575    }
4576
4577    private final boolean forceStopPackageLocked(String name, int appId,
4578            boolean callerWillRestart, boolean purgeCache, boolean doit,
4579            boolean evenPersistent, int userId, String reason) {
4580        int i;
4581        int N;
4582
4583        if (userId == UserHandle.USER_ALL && name == null) {
4584            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4585        }
4586
4587        if (appId < 0 && name != null) {
4588            try {
4589                appId = UserHandle.getAppId(
4590                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4591            } catch (RemoteException e) {
4592            }
4593        }
4594
4595        if (doit) {
4596            if (name != null) {
4597                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4598                        + " user=" + userId + ": " + reason);
4599            } else {
4600                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4601            }
4602
4603            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4604            for (int ip=pmap.size()-1; ip>=0; ip--) {
4605                SparseArray<Long> ba = pmap.valueAt(ip);
4606                for (i=ba.size()-1; i>=0; i--) {
4607                    boolean remove = false;
4608                    final int entUid = ba.keyAt(i);
4609                    if (name != null) {
4610                        if (userId == UserHandle.USER_ALL) {
4611                            if (UserHandle.getAppId(entUid) == appId) {
4612                                remove = true;
4613                            }
4614                        } else {
4615                            if (entUid == UserHandle.getUid(userId, appId)) {
4616                                remove = true;
4617                            }
4618                        }
4619                    } else if (UserHandle.getUserId(entUid) == userId) {
4620                        remove = true;
4621                    }
4622                    if (remove) {
4623                        ba.removeAt(i);
4624                    }
4625                }
4626                if (ba.size() == 0) {
4627                    pmap.removeAt(ip);
4628                }
4629            }
4630        }
4631
4632        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4633                -100, callerWillRestart, true, doit, evenPersistent,
4634                name == null ? ("stop user " + userId) : ("stop " + name));
4635
4636        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4637            if (!doit) {
4638                return true;
4639            }
4640            didSomething = true;
4641        }
4642
4643        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4644            if (!doit) {
4645                return true;
4646            }
4647            didSomething = true;
4648        }
4649
4650        if (name == null) {
4651            // Remove all sticky broadcasts from this user.
4652            mStickyBroadcasts.remove(userId);
4653        }
4654
4655        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4656        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4657                userId, providers)) {
4658            if (!doit) {
4659                return true;
4660            }
4661            didSomething = true;
4662        }
4663        N = providers.size();
4664        for (i=0; i<N; i++) {
4665            removeDyingProviderLocked(null, providers.get(i), true);
4666        }
4667
4668        // Remove transient permissions granted from/to this package/user
4669        removeUriPermissionsForPackageLocked(name, userId, false);
4670
4671        if (name == null) {
4672            // Remove pending intents.  For now we only do this when force
4673            // stopping users, because we have some problems when doing this
4674            // for packages -- app widgets are not currently cleaned up for
4675            // such packages, so they can be left with bad pending intents.
4676            if (mIntentSenderRecords.size() > 0) {
4677                Iterator<WeakReference<PendingIntentRecord>> it
4678                        = mIntentSenderRecords.values().iterator();
4679                while (it.hasNext()) {
4680                    WeakReference<PendingIntentRecord> wpir = it.next();
4681                    if (wpir == null) {
4682                        it.remove();
4683                        continue;
4684                    }
4685                    PendingIntentRecord pir = wpir.get();
4686                    if (pir == null) {
4687                        it.remove();
4688                        continue;
4689                    }
4690                    if (name == null) {
4691                        // Stopping user, remove all objects for the user.
4692                        if (pir.key.userId != userId) {
4693                            // Not the same user, skip it.
4694                            continue;
4695                        }
4696                    } else {
4697                        if (UserHandle.getAppId(pir.uid) != appId) {
4698                            // Different app id, skip it.
4699                            continue;
4700                        }
4701                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4702                            // Different user, skip it.
4703                            continue;
4704                        }
4705                        if (!pir.key.packageName.equals(name)) {
4706                            // Different package, skip it.
4707                            continue;
4708                        }
4709                    }
4710                    if (!doit) {
4711                        return true;
4712                    }
4713                    didSomething = true;
4714                    it.remove();
4715                    pir.canceled = true;
4716                    if (pir.key.activity != null) {
4717                        pir.key.activity.pendingResults.remove(pir.ref);
4718                    }
4719                }
4720            }
4721        }
4722
4723        if (doit) {
4724            if (purgeCache && name != null) {
4725                AttributeCache ac = AttributeCache.instance();
4726                if (ac != null) {
4727                    ac.removePackage(name);
4728                }
4729            }
4730            if (mBooted) {
4731                mStackSupervisor.resumeTopActivitiesLocked();
4732                mStackSupervisor.scheduleIdleLocked();
4733            }
4734        }
4735
4736        return didSomething;
4737    }
4738
4739    private final boolean removeProcessLocked(ProcessRecord app,
4740            boolean callerWillRestart, boolean allowRestart, String reason) {
4741        final String name = app.processName;
4742        final int uid = app.uid;
4743        if (DEBUG_PROCESSES) Slog.d(
4744            TAG, "Force removing proc " + app.toShortString() + " (" + name
4745            + "/" + uid + ")");
4746
4747        mProcessNames.remove(name, uid);
4748        mIsolatedProcesses.remove(app.uid);
4749        if (mHeavyWeightProcess == app) {
4750            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4751                    mHeavyWeightProcess.userId, 0));
4752            mHeavyWeightProcess = null;
4753        }
4754        boolean needRestart = false;
4755        if (app.pid > 0 && app.pid != MY_PID) {
4756            int pid = app.pid;
4757            synchronized (mPidsSelfLocked) {
4758                mPidsSelfLocked.remove(pid);
4759                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4760            }
4761            killUnneededProcessLocked(app, reason);
4762            handleAppDiedLocked(app, true, allowRestart);
4763            removeLruProcessLocked(app);
4764
4765            if (app.persistent && !app.isolated) {
4766                if (!callerWillRestart) {
4767                    addAppLocked(app.info, false, null /* ABI override */);
4768                } else {
4769                    needRestart = true;
4770                }
4771            }
4772        } else {
4773            mRemovedProcesses.add(app);
4774        }
4775
4776        return needRestart;
4777    }
4778
4779    private final void processStartTimedOutLocked(ProcessRecord app) {
4780        final int pid = app.pid;
4781        boolean gone = false;
4782        synchronized (mPidsSelfLocked) {
4783            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4784            if (knownApp != null && knownApp.thread == null) {
4785                mPidsSelfLocked.remove(pid);
4786                gone = true;
4787            }
4788        }
4789
4790        if (gone) {
4791            Slog.w(TAG, "Process " + app + " failed to attach");
4792            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4793                    pid, app.uid, app.processName);
4794            mProcessNames.remove(app.processName, app.uid);
4795            mIsolatedProcesses.remove(app.uid);
4796            if (mHeavyWeightProcess == app) {
4797                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4798                        mHeavyWeightProcess.userId, 0));
4799                mHeavyWeightProcess = null;
4800            }
4801            // Take care of any launching providers waiting for this process.
4802            checkAppInLaunchingProvidersLocked(app, true);
4803            // Take care of any services that are waiting for the process.
4804            mServices.processStartTimedOutLocked(app);
4805            killUnneededProcessLocked(app, "start timeout");
4806            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4807                Slog.w(TAG, "Unattached app died before backup, skipping");
4808                try {
4809                    IBackupManager bm = IBackupManager.Stub.asInterface(
4810                            ServiceManager.getService(Context.BACKUP_SERVICE));
4811                    bm.agentDisconnected(app.info.packageName);
4812                } catch (RemoteException e) {
4813                    // Can't happen; the backup manager is local
4814                }
4815            }
4816            if (isPendingBroadcastProcessLocked(pid)) {
4817                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4818                skipPendingBroadcastLocked(pid);
4819            }
4820        } else {
4821            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4822        }
4823    }
4824
4825    private final boolean attachApplicationLocked(IApplicationThread thread,
4826            int pid) {
4827
4828        // Find the application record that is being attached...  either via
4829        // the pid if we are running in multiple processes, or just pull the
4830        // next app record if we are emulating process with anonymous threads.
4831        ProcessRecord app;
4832        if (pid != MY_PID && pid >= 0) {
4833            synchronized (mPidsSelfLocked) {
4834                app = mPidsSelfLocked.get(pid);
4835            }
4836        } else {
4837            app = null;
4838        }
4839
4840        if (app == null) {
4841            Slog.w(TAG, "No pending application record for pid " + pid
4842                    + " (IApplicationThread " + thread + "); dropping process");
4843            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4844            if (pid > 0 && pid != MY_PID) {
4845                Process.killProcessQuiet(pid);
4846            } else {
4847                try {
4848                    thread.scheduleExit();
4849                } catch (Exception e) {
4850                    // Ignore exceptions.
4851                }
4852            }
4853            return false;
4854        }
4855
4856        // If this application record is still attached to a previous
4857        // process, clean it up now.
4858        if (app.thread != null) {
4859            handleAppDiedLocked(app, true, true);
4860        }
4861
4862        // Tell the process all about itself.
4863
4864        if (localLOGV) Slog.v(
4865                TAG, "Binding process pid " + pid + " to record " + app);
4866
4867        final String processName = app.processName;
4868        try {
4869            AppDeathRecipient adr = new AppDeathRecipient(
4870                    app, pid, thread);
4871            thread.asBinder().linkToDeath(adr, 0);
4872            app.deathRecipient = adr;
4873        } catch (RemoteException e) {
4874            app.resetPackageList(mProcessStats);
4875            startProcessLocked(app, "link fail", processName, null /* ABI override */);
4876            return false;
4877        }
4878
4879        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4880
4881        app.makeActive(thread, mProcessStats);
4882        app.curAdj = app.setAdj = -100;
4883        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4884        app.forcingToForeground = null;
4885        app.foregroundServices = false;
4886        app.hasShownUi = false;
4887        app.debugging = false;
4888        app.cached = false;
4889
4890        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4891
4892        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4893        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4894
4895        if (!normalMode) {
4896            Slog.i(TAG, "Launching preboot mode app: " + app);
4897        }
4898
4899        if (localLOGV) Slog.v(
4900            TAG, "New app record " + app
4901            + " thread=" + thread.asBinder() + " pid=" + pid);
4902        try {
4903            int testMode = IApplicationThread.DEBUG_OFF;
4904            if (mDebugApp != null && mDebugApp.equals(processName)) {
4905                testMode = mWaitForDebugger
4906                    ? IApplicationThread.DEBUG_WAIT
4907                    : IApplicationThread.DEBUG_ON;
4908                app.debugging = true;
4909                if (mDebugTransient) {
4910                    mDebugApp = mOrigDebugApp;
4911                    mWaitForDebugger = mOrigWaitForDebugger;
4912                }
4913            }
4914            String profileFile = app.instrumentationProfileFile;
4915            ParcelFileDescriptor profileFd = null;
4916            boolean profileAutoStop = false;
4917            if (mProfileApp != null && mProfileApp.equals(processName)) {
4918                mProfileProc = app;
4919                profileFile = mProfileFile;
4920                profileFd = mProfileFd;
4921                profileAutoStop = mAutoStopProfiler;
4922            }
4923            boolean enableOpenGlTrace = false;
4924            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4925                enableOpenGlTrace = true;
4926                mOpenGlTraceApp = null;
4927            }
4928
4929            // If the app is being launched for restore or full backup, set it up specially
4930            boolean isRestrictedBackupMode = false;
4931            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4932                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4933                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4934                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4935            }
4936
4937            ensurePackageDexOpt(app.instrumentationInfo != null
4938                    ? app.instrumentationInfo.packageName
4939                    : app.info.packageName);
4940            if (app.instrumentationClass != null) {
4941                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4942            }
4943            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4944                    + processName + " with config " + mConfiguration);
4945            ApplicationInfo appInfo = app.instrumentationInfo != null
4946                    ? app.instrumentationInfo : app.info;
4947            app.compat = compatibilityInfoForPackageLocked(appInfo);
4948            if (profileFd != null) {
4949                profileFd = profileFd.dup();
4950            }
4951            thread.bindApplication(processName, appInfo, providers,
4952                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4953                    app.instrumentationArguments, app.instrumentationWatcher,
4954                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4955                    isRestrictedBackupMode || !normalMode, app.persistent,
4956                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4957                    mCoreSettingsObserver.getCoreSettingsLocked());
4958            updateLruProcessLocked(app, false, null);
4959            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4960        } catch (Exception e) {
4961            // todo: Yikes!  What should we do?  For now we will try to
4962            // start another process, but that could easily get us in
4963            // an infinite loop of restarting processes...
4964            Slog.w(TAG, "Exception thrown during bind!", e);
4965
4966            app.resetPackageList(mProcessStats);
4967            app.unlinkDeathRecipient();
4968            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
4969            return false;
4970        }
4971
4972        // Remove this record from the list of starting applications.
4973        mPersistentStartingProcesses.remove(app);
4974        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4975                "Attach application locked removing on hold: " + app);
4976        mProcessesOnHold.remove(app);
4977
4978        boolean badApp = false;
4979        boolean didSomething = false;
4980
4981        // See if the top visible activity is waiting to run in this process...
4982        if (normalMode) {
4983            try {
4984                if (mStackSupervisor.attachApplicationLocked(app)) {
4985                    didSomething = true;
4986                }
4987            } catch (Exception e) {
4988                badApp = true;
4989            }
4990        }
4991
4992        // Find any services that should be running in this process...
4993        if (!badApp) {
4994            try {
4995                didSomething |= mServices.attachApplicationLocked(app, processName);
4996            } catch (Exception e) {
4997                badApp = true;
4998            }
4999        }
5000
5001        // Check if a next-broadcast receiver is in this process...
5002        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5003            try {
5004                didSomething |= sendPendingBroadcastsLocked(app);
5005            } catch (Exception e) {
5006                // If the app died trying to launch the receiver we declare it 'bad'
5007                badApp = true;
5008            }
5009        }
5010
5011        // Check whether the next backup agent is in this process...
5012        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5013            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5014            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5015            try {
5016                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5017                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5018                        mBackupTarget.backupMode);
5019            } catch (Exception e) {
5020                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5021                e.printStackTrace();
5022            }
5023        }
5024
5025        if (badApp) {
5026            // todo: Also need to kill application to deal with all
5027            // kinds of exceptions.
5028            handleAppDiedLocked(app, false, true);
5029            return false;
5030        }
5031
5032        if (!didSomething) {
5033            updateOomAdjLocked();
5034        }
5035
5036        return true;
5037    }
5038
5039    @Override
5040    public final void attachApplication(IApplicationThread thread) {
5041        synchronized (this) {
5042            int callingPid = Binder.getCallingPid();
5043            final long origId = Binder.clearCallingIdentity();
5044            attachApplicationLocked(thread, callingPid);
5045            Binder.restoreCallingIdentity(origId);
5046        }
5047    }
5048
5049    @Override
5050    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5051        final long origId = Binder.clearCallingIdentity();
5052        synchronized (this) {
5053            ActivityStack stack = ActivityRecord.getStackLocked(token);
5054            if (stack != null) {
5055                ActivityRecord r =
5056                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5057                if (stopProfiling) {
5058                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5059                        try {
5060                            mProfileFd.close();
5061                        } catch (IOException e) {
5062                        }
5063                        clearProfilerLocked();
5064                    }
5065                }
5066            }
5067        }
5068        Binder.restoreCallingIdentity(origId);
5069    }
5070
5071    void enableScreenAfterBoot() {
5072        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5073                SystemClock.uptimeMillis());
5074        mWindowManager.enableScreenAfterBoot();
5075
5076        synchronized (this) {
5077            updateEventDispatchingLocked();
5078        }
5079    }
5080
5081    @Override
5082    public void showBootMessage(final CharSequence msg, final boolean always) {
5083        enforceNotIsolatedCaller("showBootMessage");
5084        mWindowManager.showBootMessage(msg, always);
5085    }
5086
5087    @Override
5088    public void dismissKeyguardOnNextActivity() {
5089        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5090        final long token = Binder.clearCallingIdentity();
5091        try {
5092            synchronized (this) {
5093                if (DEBUG_LOCKSCREEN) logLockScreen("");
5094                if (mLockScreenShown) {
5095                    mLockScreenShown = false;
5096                    comeOutOfSleepIfNeededLocked();
5097                }
5098                mStackSupervisor.setDismissKeyguard(true);
5099            }
5100        } finally {
5101            Binder.restoreCallingIdentity(token);
5102        }
5103    }
5104
5105    final void finishBooting() {
5106        IntentFilter pkgFilter = new IntentFilter();
5107        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5108        pkgFilter.addDataScheme("package");
5109        mContext.registerReceiver(new BroadcastReceiver() {
5110            @Override
5111            public void onReceive(Context context, Intent intent) {
5112                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5113                if (pkgs != null) {
5114                    for (String pkg : pkgs) {
5115                        synchronized (ActivityManagerService.this) {
5116                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0,
5117                                    "finished booting")) {
5118                                setResultCode(Activity.RESULT_OK);
5119                                return;
5120                            }
5121                        }
5122                    }
5123                }
5124            }
5125        }, pkgFilter);
5126
5127        synchronized (this) {
5128            // Ensure that any processes we had put on hold are now started
5129            // up.
5130            final int NP = mProcessesOnHold.size();
5131            if (NP > 0) {
5132                ArrayList<ProcessRecord> procs =
5133                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5134                for (int ip=0; ip<NP; ip++) {
5135                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5136                            + procs.get(ip));
5137                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5138                }
5139            }
5140
5141            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5142                // Start looking for apps that are abusing wake locks.
5143                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5144                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5145                // Tell anyone interested that we are done booting!
5146                SystemProperties.set("sys.boot_completed", "1");
5147                SystemProperties.set("dev.bootcomplete", "1");
5148                for (int i=0; i<mStartedUsers.size(); i++) {
5149                    UserStartedState uss = mStartedUsers.valueAt(i);
5150                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5151                        uss.mState = UserStartedState.STATE_RUNNING;
5152                        final int userId = mStartedUsers.keyAt(i);
5153                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5154                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5155                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5156                        broadcastIntentLocked(null, null, intent, null,
5157                                new IIntentReceiver.Stub() {
5158                                    @Override
5159                                    public void performReceive(Intent intent, int resultCode,
5160                                            String data, Bundle extras, boolean ordered,
5161                                            boolean sticky, int sendingUser) {
5162                                        synchronized (ActivityManagerService.this) {
5163                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5164                                                    true, false);
5165                                        }
5166                                    }
5167                                },
5168                                0, null, null,
5169                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5170                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5171                                userId);
5172                    }
5173                }
5174            }
5175        }
5176    }
5177
5178    final void ensureBootCompleted() {
5179        boolean booting;
5180        boolean enableScreen;
5181        synchronized (this) {
5182            booting = mBooting;
5183            mBooting = false;
5184            enableScreen = !mBooted;
5185            mBooted = true;
5186        }
5187
5188        if (booting) {
5189            finishBooting();
5190        }
5191
5192        if (enableScreen) {
5193            enableScreenAfterBoot();
5194        }
5195    }
5196
5197    @Override
5198    public final void activityResumed(IBinder token) {
5199        final long origId = Binder.clearCallingIdentity();
5200        synchronized(this) {
5201            ActivityStack stack = ActivityRecord.getStackLocked(token);
5202            if (stack != null) {
5203                ActivityRecord.activityResumedLocked(token);
5204            }
5205        }
5206        Binder.restoreCallingIdentity(origId);
5207    }
5208
5209    @Override
5210    public final void activityPaused(IBinder token) {
5211        final long origId = Binder.clearCallingIdentity();
5212        synchronized(this) {
5213            ActivityStack stack = ActivityRecord.getStackLocked(token);
5214            if (stack != null) {
5215                stack.activityPausedLocked(token, false);
5216            }
5217        }
5218        Binder.restoreCallingIdentity(origId);
5219    }
5220
5221    @Override
5222    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5223            CharSequence description) {
5224        if (localLOGV) Slog.v(
5225            TAG, "Activity stopped: token=" + token);
5226
5227        // Refuse possible leaked file descriptors
5228        if (icicle != null && icicle.hasFileDescriptors()) {
5229            throw new IllegalArgumentException("File descriptors passed in Bundle");
5230        }
5231
5232        ActivityRecord r = null;
5233
5234        final long origId = Binder.clearCallingIdentity();
5235
5236        synchronized (this) {
5237            r = ActivityRecord.isInStackLocked(token);
5238            if (r != null) {
5239                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5240            }
5241        }
5242
5243        if (r != null) {
5244            sendPendingThumbnail(r, null, null, null, false);
5245        }
5246
5247        trimApplications();
5248
5249        Binder.restoreCallingIdentity(origId);
5250    }
5251
5252    @Override
5253    public final void activityDestroyed(IBinder token) {
5254        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5255        synchronized (this) {
5256            ActivityStack stack = ActivityRecord.getStackLocked(token);
5257            if (stack != null) {
5258                stack.activityDestroyedLocked(token);
5259            }
5260        }
5261    }
5262
5263    @Override
5264    public String getCallingPackage(IBinder token) {
5265        synchronized (this) {
5266            ActivityRecord r = getCallingRecordLocked(token);
5267            return r != null ? r.info.packageName : null;
5268        }
5269    }
5270
5271    @Override
5272    public ComponentName getCallingActivity(IBinder token) {
5273        synchronized (this) {
5274            ActivityRecord r = getCallingRecordLocked(token);
5275            return r != null ? r.intent.getComponent() : null;
5276        }
5277    }
5278
5279    private ActivityRecord getCallingRecordLocked(IBinder token) {
5280        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5281        if (r == null) {
5282            return null;
5283        }
5284        return r.resultTo;
5285    }
5286
5287    @Override
5288    public ComponentName getActivityClassForToken(IBinder token) {
5289        synchronized(this) {
5290            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5291            if (r == null) {
5292                return null;
5293            }
5294            return r.intent.getComponent();
5295        }
5296    }
5297
5298    @Override
5299    public String getPackageForToken(IBinder token) {
5300        synchronized(this) {
5301            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5302            if (r == null) {
5303                return null;
5304            }
5305            return r.packageName;
5306        }
5307    }
5308
5309    @Override
5310    public IIntentSender getIntentSender(int type,
5311            String packageName, IBinder token, String resultWho,
5312            int requestCode, Intent[] intents, String[] resolvedTypes,
5313            int flags, Bundle options, int userId) {
5314        enforceNotIsolatedCaller("getIntentSender");
5315        // Refuse possible leaked file descriptors
5316        if (intents != null) {
5317            if (intents.length < 1) {
5318                throw new IllegalArgumentException("Intents array length must be >= 1");
5319            }
5320            for (int i=0; i<intents.length; i++) {
5321                Intent intent = intents[i];
5322                if (intent != null) {
5323                    if (intent.hasFileDescriptors()) {
5324                        throw new IllegalArgumentException("File descriptors passed in Intent");
5325                    }
5326                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5327                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5328                        throw new IllegalArgumentException(
5329                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5330                    }
5331                    intents[i] = new Intent(intent);
5332                }
5333            }
5334            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5335                throw new IllegalArgumentException(
5336                        "Intent array length does not match resolvedTypes length");
5337            }
5338        }
5339        if (options != null) {
5340            if (options.hasFileDescriptors()) {
5341                throw new IllegalArgumentException("File descriptors passed in options");
5342            }
5343        }
5344
5345        synchronized(this) {
5346            int callingUid = Binder.getCallingUid();
5347            int origUserId = userId;
5348            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5349                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5350                    "getIntentSender", null);
5351            if (origUserId == UserHandle.USER_CURRENT) {
5352                // We don't want to evaluate this until the pending intent is
5353                // actually executed.  However, we do want to always do the
5354                // security checking for it above.
5355                userId = UserHandle.USER_CURRENT;
5356            }
5357            try {
5358                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5359                    int uid = AppGlobals.getPackageManager()
5360                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5361                    if (!UserHandle.isSameApp(callingUid, uid)) {
5362                        String msg = "Permission Denial: getIntentSender() from pid="
5363                            + Binder.getCallingPid()
5364                            + ", uid=" + Binder.getCallingUid()
5365                            + ", (need uid=" + uid + ")"
5366                            + " is not allowed to send as package " + packageName;
5367                        Slog.w(TAG, msg);
5368                        throw new SecurityException(msg);
5369                    }
5370                }
5371
5372                return getIntentSenderLocked(type, packageName, callingUid, userId,
5373                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5374
5375            } catch (RemoteException e) {
5376                throw new SecurityException(e);
5377            }
5378        }
5379    }
5380
5381    IIntentSender getIntentSenderLocked(int type, String packageName,
5382            int callingUid, int userId, IBinder token, String resultWho,
5383            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5384            Bundle options) {
5385        if (DEBUG_MU)
5386            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5387        ActivityRecord activity = null;
5388        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5389            activity = ActivityRecord.isInStackLocked(token);
5390            if (activity == null) {
5391                return null;
5392            }
5393            if (activity.finishing) {
5394                return null;
5395            }
5396        }
5397
5398        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5399        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5400        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5401        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5402                |PendingIntent.FLAG_UPDATE_CURRENT);
5403
5404        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5405                type, packageName, activity, resultWho,
5406                requestCode, intents, resolvedTypes, flags, options, userId);
5407        WeakReference<PendingIntentRecord> ref;
5408        ref = mIntentSenderRecords.get(key);
5409        PendingIntentRecord rec = ref != null ? ref.get() : null;
5410        if (rec != null) {
5411            if (!cancelCurrent) {
5412                if (updateCurrent) {
5413                    if (rec.key.requestIntent != null) {
5414                        rec.key.requestIntent.replaceExtras(intents != null ?
5415                                intents[intents.length - 1] : null);
5416                    }
5417                    if (intents != null) {
5418                        intents[intents.length-1] = rec.key.requestIntent;
5419                        rec.key.allIntents = intents;
5420                        rec.key.allResolvedTypes = resolvedTypes;
5421                    } else {
5422                        rec.key.allIntents = null;
5423                        rec.key.allResolvedTypes = null;
5424                    }
5425                }
5426                return rec;
5427            }
5428            rec.canceled = true;
5429            mIntentSenderRecords.remove(key);
5430        }
5431        if (noCreate) {
5432            return rec;
5433        }
5434        rec = new PendingIntentRecord(this, key, callingUid);
5435        mIntentSenderRecords.put(key, rec.ref);
5436        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5437            if (activity.pendingResults == null) {
5438                activity.pendingResults
5439                        = new HashSet<WeakReference<PendingIntentRecord>>();
5440            }
5441            activity.pendingResults.add(rec.ref);
5442        }
5443        return rec;
5444    }
5445
5446    @Override
5447    public void cancelIntentSender(IIntentSender sender) {
5448        if (!(sender instanceof PendingIntentRecord)) {
5449            return;
5450        }
5451        synchronized(this) {
5452            PendingIntentRecord rec = (PendingIntentRecord)sender;
5453            try {
5454                int uid = AppGlobals.getPackageManager()
5455                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5456                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5457                    String msg = "Permission Denial: cancelIntentSender() from pid="
5458                        + Binder.getCallingPid()
5459                        + ", uid=" + Binder.getCallingUid()
5460                        + " is not allowed to cancel packges "
5461                        + rec.key.packageName;
5462                    Slog.w(TAG, msg);
5463                    throw new SecurityException(msg);
5464                }
5465            } catch (RemoteException e) {
5466                throw new SecurityException(e);
5467            }
5468            cancelIntentSenderLocked(rec, true);
5469        }
5470    }
5471
5472    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5473        rec.canceled = true;
5474        mIntentSenderRecords.remove(rec.key);
5475        if (cleanActivity && rec.key.activity != null) {
5476            rec.key.activity.pendingResults.remove(rec.ref);
5477        }
5478    }
5479
5480    @Override
5481    public String getPackageForIntentSender(IIntentSender pendingResult) {
5482        if (!(pendingResult instanceof PendingIntentRecord)) {
5483            return null;
5484        }
5485        try {
5486            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5487            return res.key.packageName;
5488        } catch (ClassCastException e) {
5489        }
5490        return null;
5491    }
5492
5493    @Override
5494    public int getUidForIntentSender(IIntentSender sender) {
5495        if (sender instanceof PendingIntentRecord) {
5496            try {
5497                PendingIntentRecord res = (PendingIntentRecord)sender;
5498                return res.uid;
5499            } catch (ClassCastException e) {
5500            }
5501        }
5502        return -1;
5503    }
5504
5505    @Override
5506    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5507        if (!(pendingResult instanceof PendingIntentRecord)) {
5508            return false;
5509        }
5510        try {
5511            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5512            if (res.key.allIntents == null) {
5513                return false;
5514            }
5515            for (int i=0; i<res.key.allIntents.length; i++) {
5516                Intent intent = res.key.allIntents[i];
5517                if (intent.getPackage() != null && intent.getComponent() != null) {
5518                    return false;
5519                }
5520            }
5521            return true;
5522        } catch (ClassCastException e) {
5523        }
5524        return false;
5525    }
5526
5527    @Override
5528    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5529        if (!(pendingResult instanceof PendingIntentRecord)) {
5530            return false;
5531        }
5532        try {
5533            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5534            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5535                return true;
5536            }
5537            return false;
5538        } catch (ClassCastException e) {
5539        }
5540        return false;
5541    }
5542
5543    @Override
5544    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5545        if (!(pendingResult instanceof PendingIntentRecord)) {
5546            return null;
5547        }
5548        try {
5549            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5550            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5551        } catch (ClassCastException e) {
5552        }
5553        return null;
5554    }
5555
5556    @Override
5557    public void setProcessLimit(int max) {
5558        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5559                "setProcessLimit()");
5560        synchronized (this) {
5561            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5562            mProcessLimitOverride = max;
5563        }
5564        trimApplications();
5565    }
5566
5567    @Override
5568    public int getProcessLimit() {
5569        synchronized (this) {
5570            return mProcessLimitOverride;
5571        }
5572    }
5573
5574    void foregroundTokenDied(ForegroundToken token) {
5575        synchronized (ActivityManagerService.this) {
5576            synchronized (mPidsSelfLocked) {
5577                ForegroundToken cur
5578                    = mForegroundProcesses.get(token.pid);
5579                if (cur != token) {
5580                    return;
5581                }
5582                mForegroundProcesses.remove(token.pid);
5583                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5584                if (pr == null) {
5585                    return;
5586                }
5587                pr.forcingToForeground = null;
5588                pr.foregroundServices = false;
5589            }
5590            updateOomAdjLocked();
5591        }
5592    }
5593
5594    @Override
5595    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5596        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5597                "setProcessForeground()");
5598        synchronized(this) {
5599            boolean changed = false;
5600
5601            synchronized (mPidsSelfLocked) {
5602                ProcessRecord pr = mPidsSelfLocked.get(pid);
5603                if (pr == null && isForeground) {
5604                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5605                    return;
5606                }
5607                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5608                if (oldToken != null) {
5609                    oldToken.token.unlinkToDeath(oldToken, 0);
5610                    mForegroundProcesses.remove(pid);
5611                    if (pr != null) {
5612                        pr.forcingToForeground = null;
5613                    }
5614                    changed = true;
5615                }
5616                if (isForeground && token != null) {
5617                    ForegroundToken newToken = new ForegroundToken() {
5618                        @Override
5619                        public void binderDied() {
5620                            foregroundTokenDied(this);
5621                        }
5622                    };
5623                    newToken.pid = pid;
5624                    newToken.token = token;
5625                    try {
5626                        token.linkToDeath(newToken, 0);
5627                        mForegroundProcesses.put(pid, newToken);
5628                        pr.forcingToForeground = token;
5629                        changed = true;
5630                    } catch (RemoteException e) {
5631                        // If the process died while doing this, we will later
5632                        // do the cleanup with the process death link.
5633                    }
5634                }
5635            }
5636
5637            if (changed) {
5638                updateOomAdjLocked();
5639            }
5640        }
5641    }
5642
5643    // =========================================================
5644    // PERMISSIONS
5645    // =========================================================
5646
5647    static class PermissionController extends IPermissionController.Stub {
5648        ActivityManagerService mActivityManagerService;
5649        PermissionController(ActivityManagerService activityManagerService) {
5650            mActivityManagerService = activityManagerService;
5651        }
5652
5653        @Override
5654        public boolean checkPermission(String permission, int pid, int uid) {
5655            return mActivityManagerService.checkPermission(permission, pid,
5656                    uid) == PackageManager.PERMISSION_GRANTED;
5657        }
5658    }
5659
5660    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5661        @Override
5662        public int checkComponentPermission(String permission, int pid, int uid,
5663                int owningUid, boolean exported) {
5664            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5665                    owningUid, exported);
5666        }
5667
5668        @Override
5669        public Object getAMSLock() {
5670            return ActivityManagerService.this;
5671        }
5672    }
5673
5674    /**
5675     * This can be called with or without the global lock held.
5676     */
5677    int checkComponentPermission(String permission, int pid, int uid,
5678            int owningUid, boolean exported) {
5679        // We might be performing an operation on behalf of an indirect binder
5680        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5681        // client identity accordingly before proceeding.
5682        Identity tlsIdentity = sCallerIdentity.get();
5683        if (tlsIdentity != null) {
5684            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5685                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5686            uid = tlsIdentity.uid;
5687            pid = tlsIdentity.pid;
5688        }
5689
5690        if (pid == MY_PID) {
5691            return PackageManager.PERMISSION_GRANTED;
5692        }
5693
5694        return ActivityManager.checkComponentPermission(permission, uid,
5695                owningUid, exported);
5696    }
5697
5698    /**
5699     * As the only public entry point for permissions checking, this method
5700     * can enforce the semantic that requesting a check on a null global
5701     * permission is automatically denied.  (Internally a null permission
5702     * string is used when calling {@link #checkComponentPermission} in cases
5703     * when only uid-based security is needed.)
5704     *
5705     * This can be called with or without the global lock held.
5706     */
5707    @Override
5708    public int checkPermission(String permission, int pid, int uid) {
5709        if (permission == null) {
5710            return PackageManager.PERMISSION_DENIED;
5711        }
5712        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5713    }
5714
5715    /**
5716     * Binder IPC calls go through the public entry point.
5717     * This can be called with or without the global lock held.
5718     */
5719    int checkCallingPermission(String permission) {
5720        return checkPermission(permission,
5721                Binder.getCallingPid(),
5722                UserHandle.getAppId(Binder.getCallingUid()));
5723    }
5724
5725    /**
5726     * This can be called with or without the global lock held.
5727     */
5728    void enforceCallingPermission(String permission, String func) {
5729        if (checkCallingPermission(permission)
5730                == PackageManager.PERMISSION_GRANTED) {
5731            return;
5732        }
5733
5734        String msg = "Permission Denial: " + func + " from pid="
5735                + Binder.getCallingPid()
5736                + ", uid=" + Binder.getCallingUid()
5737                + " requires " + permission;
5738        Slog.w(TAG, msg);
5739        throw new SecurityException(msg);
5740    }
5741
5742    /**
5743     * Determine if UID is holding permissions required to access {@link Uri} in
5744     * the given {@link ProviderInfo}. Final permission checking is always done
5745     * in {@link ContentProvider}.
5746     */
5747    private final boolean checkHoldingPermissionsLocked(
5748            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5749        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5750                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5751
5752        if (pi.applicationInfo.uid == uid) {
5753            return true;
5754        } else if (!pi.exported) {
5755            return false;
5756        }
5757
5758        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5759        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5760        try {
5761            // check if target holds top-level <provider> permissions
5762            if (!readMet && pi.readPermission != null
5763                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5764                readMet = true;
5765            }
5766            if (!writeMet && pi.writePermission != null
5767                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5768                writeMet = true;
5769            }
5770
5771            // track if unprotected read/write is allowed; any denied
5772            // <path-permission> below removes this ability
5773            boolean allowDefaultRead = pi.readPermission == null;
5774            boolean allowDefaultWrite = pi.writePermission == null;
5775
5776            // check if target holds any <path-permission> that match uri
5777            final PathPermission[] pps = pi.pathPermissions;
5778            if (pps != null) {
5779                final String path = uri.getPath();
5780                int i = pps.length;
5781                while (i > 0 && (!readMet || !writeMet)) {
5782                    i--;
5783                    PathPermission pp = pps[i];
5784                    if (pp.match(path)) {
5785                        if (!readMet) {
5786                            final String pprperm = pp.getReadPermission();
5787                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5788                                    + pprperm + " for " + pp.getPath()
5789                                    + ": match=" + pp.match(path)
5790                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5791                            if (pprperm != null) {
5792                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5793                                    readMet = true;
5794                                } else {
5795                                    allowDefaultRead = false;
5796                                }
5797                            }
5798                        }
5799                        if (!writeMet) {
5800                            final String ppwperm = pp.getWritePermission();
5801                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5802                                    + ppwperm + " for " + pp.getPath()
5803                                    + ": match=" + pp.match(path)
5804                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5805                            if (ppwperm != null) {
5806                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5807                                    writeMet = true;
5808                                } else {
5809                                    allowDefaultWrite = false;
5810                                }
5811                            }
5812                        }
5813                    }
5814                }
5815            }
5816
5817            // grant unprotected <provider> read/write, if not blocked by
5818            // <path-permission> above
5819            if (allowDefaultRead) readMet = true;
5820            if (allowDefaultWrite) writeMet = true;
5821
5822        } catch (RemoteException e) {
5823            return false;
5824        }
5825
5826        return readMet && writeMet;
5827    }
5828
5829    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5830        ProviderInfo pi = null;
5831        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5832        if (cpr != null) {
5833            pi = cpr.info;
5834        } else {
5835            try {
5836                pi = AppGlobals.getPackageManager().resolveContentProvider(
5837                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5838            } catch (RemoteException ex) {
5839            }
5840        }
5841        return pi;
5842    }
5843
5844    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5845        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5846        if (targetUris != null) {
5847            return targetUris.get(uri);
5848        } else {
5849            return null;
5850        }
5851    }
5852
5853    private UriPermission findOrCreateUriPermissionLocked(
5854            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5855        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5856        if (targetUris == null) {
5857            targetUris = Maps.newArrayMap();
5858            mGrantedUriPermissions.put(targetUid, targetUris);
5859        }
5860
5861        UriPermission perm = targetUris.get(uri);
5862        if (perm == null) {
5863            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5864            targetUris.put(uri, perm);
5865        }
5866
5867        return perm;
5868    }
5869
5870    private final boolean checkUriPermissionLocked(
5871            Uri uri, int uid, int modeFlags, int minStrength) {
5872        // Root gets to do everything.
5873        if (uid == 0) {
5874            return true;
5875        }
5876        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5877        if (perms == null) return false;
5878        UriPermission perm = perms.get(uri);
5879        if (perm == null) return false;
5880        return perm.getStrength(modeFlags) >= minStrength;
5881    }
5882
5883    @Override
5884    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5885        enforceNotIsolatedCaller("checkUriPermission");
5886
5887        // Another redirected-binder-call permissions check as in
5888        // {@link checkComponentPermission}.
5889        Identity tlsIdentity = sCallerIdentity.get();
5890        if (tlsIdentity != null) {
5891            uid = tlsIdentity.uid;
5892            pid = tlsIdentity.pid;
5893        }
5894
5895        // Our own process gets to do everything.
5896        if (pid == MY_PID) {
5897            return PackageManager.PERMISSION_GRANTED;
5898        }
5899        synchronized(this) {
5900            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5901                    ? PackageManager.PERMISSION_GRANTED
5902                    : PackageManager.PERMISSION_DENIED;
5903        }
5904    }
5905
5906    /**
5907     * Check if the targetPkg can be granted permission to access uri by
5908     * the callingUid using the given modeFlags.  Throws a security exception
5909     * if callingUid is not allowed to do this.  Returns the uid of the target
5910     * if the URI permission grant should be performed; returns -1 if it is not
5911     * needed (for example targetPkg already has permission to access the URI).
5912     * If you already know the uid of the target, you can supply it in
5913     * lastTargetUid else set that to -1.
5914     */
5915    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5916            Uri uri, int modeFlags, int lastTargetUid) {
5917        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5918        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5919                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5920        if (modeFlags == 0) {
5921            return -1;
5922        }
5923
5924        if (targetPkg != null) {
5925            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5926                    "Checking grant " + targetPkg + " permission to " + uri);
5927        }
5928
5929        final IPackageManager pm = AppGlobals.getPackageManager();
5930
5931        // If this is not a content: uri, we can't do anything with it.
5932        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5933            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5934                    "Can't grant URI permission for non-content URI: " + uri);
5935            return -1;
5936        }
5937
5938        final String authority = uri.getAuthority();
5939        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5940        if (pi == null) {
5941            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5942            return -1;
5943        }
5944
5945        int targetUid = lastTargetUid;
5946        if (targetUid < 0 && targetPkg != null) {
5947            try {
5948                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5949                if (targetUid < 0) {
5950                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5951                            "Can't grant URI permission no uid for: " + targetPkg);
5952                    return -1;
5953                }
5954            } catch (RemoteException ex) {
5955                return -1;
5956            }
5957        }
5958
5959        if (targetUid >= 0) {
5960            // First...  does the target actually need this permission?
5961            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5962                // No need to grant the target this permission.
5963                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5964                        "Target " + targetPkg + " already has full permission to " + uri);
5965                return -1;
5966            }
5967        } else {
5968            // First...  there is no target package, so can anyone access it?
5969            boolean allowed = pi.exported;
5970            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5971                if (pi.readPermission != null) {
5972                    allowed = false;
5973                }
5974            }
5975            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5976                if (pi.writePermission != null) {
5977                    allowed = false;
5978                }
5979            }
5980            if (allowed) {
5981                return -1;
5982            }
5983        }
5984
5985        // Second...  is the provider allowing granting of URI permissions?
5986        if (!pi.grantUriPermissions) {
5987            throw new SecurityException("Provider " + pi.packageName
5988                    + "/" + pi.name
5989                    + " does not allow granting of Uri permissions (uri "
5990                    + uri + ")");
5991        }
5992        if (pi.uriPermissionPatterns != null) {
5993            final int N = pi.uriPermissionPatterns.length;
5994            boolean allowed = false;
5995            for (int i=0; i<N; i++) {
5996                if (pi.uriPermissionPatterns[i] != null
5997                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5998                    allowed = true;
5999                    break;
6000                }
6001            }
6002            if (!allowed) {
6003                throw new SecurityException("Provider " + pi.packageName
6004                        + "/" + pi.name
6005                        + " does not allow granting of permission to path of Uri "
6006                        + uri);
6007            }
6008        }
6009
6010        // Third...  does the caller itself have permission to access
6011        // this uri?
6012        if (callingUid != Process.myUid()) {
6013            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6014                // Require they hold a strong enough Uri permission
6015                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6016                        : UriPermission.STRENGTH_OWNED;
6017                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6018                    throw new SecurityException("Uid " + callingUid
6019                            + " does not have permission to uri " + uri);
6020                }
6021            }
6022        }
6023
6024        return targetUid;
6025    }
6026
6027    @Override
6028    public int checkGrantUriPermission(int callingUid, String targetPkg,
6029            Uri uri, int modeFlags) {
6030        enforceNotIsolatedCaller("checkGrantUriPermission");
6031        synchronized(this) {
6032            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6033        }
6034    }
6035
6036    void grantUriPermissionUncheckedLocked(
6037            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6038        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6039        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6040                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6041        if (modeFlags == 0) {
6042            return;
6043        }
6044
6045        // So here we are: the caller has the assumed permission
6046        // to the uri, and the target doesn't.  Let's now give this to
6047        // the target.
6048
6049        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6050                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6051
6052        final String authority = uri.getAuthority();
6053        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6054        if (pi == null) {
6055            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6056            return;
6057        }
6058
6059        final UriPermission perm = findOrCreateUriPermissionLocked(
6060                pi.packageName, targetPkg, targetUid, uri);
6061        perm.grantModes(modeFlags, persistable, owner);
6062    }
6063
6064    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6065            int modeFlags, UriPermissionOwner owner) {
6066        if (targetPkg == null) {
6067            throw new NullPointerException("targetPkg");
6068        }
6069
6070        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6071        if (targetUid < 0) {
6072            return;
6073        }
6074
6075        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6076    }
6077
6078    static class NeededUriGrants extends ArrayList<Uri> {
6079        final String targetPkg;
6080        final int targetUid;
6081        final int flags;
6082
6083        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6084            this.targetPkg = targetPkg;
6085            this.targetUid = targetUid;
6086            this.flags = flags;
6087        }
6088    }
6089
6090    /**
6091     * Like checkGrantUriPermissionLocked, but takes an Intent.
6092     */
6093    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6094            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6095        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6096                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6097                + " clip=" + (intent != null ? intent.getClipData() : null)
6098                + " from " + intent + "; flags=0x"
6099                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6100
6101        if (targetPkg == null) {
6102            throw new NullPointerException("targetPkg");
6103        }
6104
6105        if (intent == null) {
6106            return null;
6107        }
6108        Uri data = intent.getData();
6109        ClipData clip = intent.getClipData();
6110        if (data == null && clip == null) {
6111            return null;
6112        }
6113
6114        if (data != null) {
6115            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6116                mode, needed != null ? needed.targetUid : -1);
6117            if (targetUid > 0) {
6118                if (needed == null) {
6119                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6120                }
6121                needed.add(data);
6122            }
6123        }
6124        if (clip != null) {
6125            for (int i=0; i<clip.getItemCount(); i++) {
6126                Uri uri = clip.getItemAt(i).getUri();
6127                if (uri != null) {
6128                    int targetUid = -1;
6129                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6130                            mode, needed != null ? needed.targetUid : -1);
6131                    if (targetUid > 0) {
6132                        if (needed == null) {
6133                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6134                        }
6135                        needed.add(uri);
6136                    }
6137                } else {
6138                    Intent clipIntent = clip.getItemAt(i).getIntent();
6139                    if (clipIntent != null) {
6140                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6141                                callingUid, targetPkg, clipIntent, mode, needed);
6142                        if (newNeeded != null) {
6143                            needed = newNeeded;
6144                        }
6145                    }
6146                }
6147            }
6148        }
6149
6150        return needed;
6151    }
6152
6153    /**
6154     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6155     */
6156    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6157            UriPermissionOwner owner) {
6158        if (needed != null) {
6159            for (int i=0; i<needed.size(); i++) {
6160                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6161                        needed.get(i), needed.flags, owner);
6162            }
6163        }
6164    }
6165
6166    void grantUriPermissionFromIntentLocked(int callingUid,
6167            String targetPkg, Intent intent, UriPermissionOwner owner) {
6168        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6169                intent, intent != null ? intent.getFlags() : 0, null);
6170        if (needed == null) {
6171            return;
6172        }
6173
6174        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6175    }
6176
6177    @Override
6178    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6179            Uri uri, int modeFlags) {
6180        enforceNotIsolatedCaller("grantUriPermission");
6181        synchronized(this) {
6182            final ProcessRecord r = getRecordForAppLocked(caller);
6183            if (r == null) {
6184                throw new SecurityException("Unable to find app for caller "
6185                        + caller
6186                        + " when granting permission to uri " + uri);
6187            }
6188            if (targetPkg == null) {
6189                throw new IllegalArgumentException("null target");
6190            }
6191            if (uri == null) {
6192                throw new IllegalArgumentException("null uri");
6193            }
6194
6195            // Persistable only supported through Intents
6196            Preconditions.checkFlagsArgument(modeFlags,
6197                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6198
6199            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6200                    null);
6201        }
6202    }
6203
6204    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6205        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6206                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6207            ArrayMap<Uri, UriPermission> perms
6208                    = mGrantedUriPermissions.get(perm.targetUid);
6209            if (perms != null) {
6210                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6211                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6212                perms.remove(perm.uri);
6213                if (perms.size() == 0) {
6214                    mGrantedUriPermissions.remove(perm.targetUid);
6215                }
6216            }
6217        }
6218    }
6219
6220    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6221        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6222
6223        final IPackageManager pm = AppGlobals.getPackageManager();
6224        final String authority = uri.getAuthority();
6225        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6226        if (pi == null) {
6227            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6228            return;
6229        }
6230
6231        // Does the caller have this permission on the URI?
6232        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6233            // Right now, if you are not the original owner of the permission,
6234            // you are not allowed to revoke it.
6235            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6236                throw new SecurityException("Uid " + callingUid
6237                        + " does not have permission to uri " + uri);
6238            //}
6239        }
6240
6241        boolean persistChanged = false;
6242
6243        // Go through all of the permissions and remove any that match.
6244        final List<String> SEGMENTS = uri.getPathSegments();
6245        if (SEGMENTS != null) {
6246            final int NS = SEGMENTS.size();
6247            int N = mGrantedUriPermissions.size();
6248            for (int i=0; i<N; i++) {
6249                ArrayMap<Uri, UriPermission> perms
6250                        = mGrantedUriPermissions.valueAt(i);
6251                Iterator<UriPermission> it = perms.values().iterator();
6252            toploop:
6253                while (it.hasNext()) {
6254                    UriPermission perm = it.next();
6255                    Uri targetUri = perm.uri;
6256                    if (!authority.equals(targetUri.getAuthority())) {
6257                        continue;
6258                    }
6259                    List<String> targetSegments = targetUri.getPathSegments();
6260                    if (targetSegments == null) {
6261                        continue;
6262                    }
6263                    if (targetSegments.size() < NS) {
6264                        continue;
6265                    }
6266                    for (int j=0; j<NS; j++) {
6267                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6268                            continue toploop;
6269                        }
6270                    }
6271                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6272                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6273                    persistChanged |= perm.clearModes(modeFlags, true);
6274                    if (perm.modeFlags == 0) {
6275                        it.remove();
6276                    }
6277                }
6278                if (perms.size() == 0) {
6279                    mGrantedUriPermissions.remove(
6280                            mGrantedUriPermissions.keyAt(i));
6281                    N--;
6282                    i--;
6283                }
6284            }
6285        }
6286
6287        if (persistChanged) {
6288            schedulePersistUriGrants();
6289        }
6290    }
6291
6292    @Override
6293    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6294            int modeFlags) {
6295        enforceNotIsolatedCaller("revokeUriPermission");
6296        synchronized(this) {
6297            final ProcessRecord r = getRecordForAppLocked(caller);
6298            if (r == null) {
6299                throw new SecurityException("Unable to find app for caller "
6300                        + caller
6301                        + " when revoking permission to uri " + uri);
6302            }
6303            if (uri == null) {
6304                Slog.w(TAG, "revokeUriPermission: null uri");
6305                return;
6306            }
6307
6308            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6309                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6310            if (modeFlags == 0) {
6311                return;
6312            }
6313
6314            final IPackageManager pm = AppGlobals.getPackageManager();
6315            final String authority = uri.getAuthority();
6316            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6317            if (pi == null) {
6318                Slog.w(TAG, "No content provider found for permission revoke: "
6319                        + uri.toSafeString());
6320                return;
6321            }
6322
6323            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6324        }
6325    }
6326
6327    /**
6328     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6329     * given package.
6330     *
6331     * @param packageName Package name to match, or {@code null} to apply to all
6332     *            packages.
6333     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6334     *            to all users.
6335     * @param persistable If persistable grants should be removed.
6336     */
6337    private void removeUriPermissionsForPackageLocked(
6338            String packageName, int userHandle, boolean persistable) {
6339        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6340            throw new IllegalArgumentException("Must narrow by either package or user");
6341        }
6342
6343        boolean persistChanged = false;
6344
6345        final int size = mGrantedUriPermissions.size();
6346        for (int i = 0; i < size; i++) {
6347            // Only inspect grants matching user
6348            if (userHandle == UserHandle.USER_ALL
6349                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6350                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6351                        .values().iterator();
6352                while (it.hasNext()) {
6353                    final UriPermission perm = it.next();
6354
6355                    // Only inspect grants matching package
6356                    if (packageName == null || perm.sourcePkg.equals(packageName)
6357                            || perm.targetPkg.equals(packageName)) {
6358                        persistChanged |= perm.clearModes(~0, persistable);
6359
6360                        // Only remove when no modes remain; any persisted grants
6361                        // will keep this alive.
6362                        if (perm.modeFlags == 0) {
6363                            it.remove();
6364                        }
6365                    }
6366                }
6367            }
6368        }
6369
6370        if (persistChanged) {
6371            schedulePersistUriGrants();
6372        }
6373    }
6374
6375    @Override
6376    public IBinder newUriPermissionOwner(String name) {
6377        enforceNotIsolatedCaller("newUriPermissionOwner");
6378        synchronized(this) {
6379            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6380            return owner.getExternalTokenLocked();
6381        }
6382    }
6383
6384    @Override
6385    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6386            Uri uri, int modeFlags) {
6387        synchronized(this) {
6388            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6389            if (owner == null) {
6390                throw new IllegalArgumentException("Unknown owner: " + token);
6391            }
6392            if (fromUid != Binder.getCallingUid()) {
6393                if (Binder.getCallingUid() != Process.myUid()) {
6394                    // Only system code can grant URI permissions on behalf
6395                    // of other users.
6396                    throw new SecurityException("nice try");
6397                }
6398            }
6399            if (targetPkg == null) {
6400                throw new IllegalArgumentException("null target");
6401            }
6402            if (uri == null) {
6403                throw new IllegalArgumentException("null uri");
6404            }
6405
6406            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6407        }
6408    }
6409
6410    @Override
6411    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6412        synchronized(this) {
6413            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6414            if (owner == null) {
6415                throw new IllegalArgumentException("Unknown owner: " + token);
6416            }
6417
6418            if (uri == null) {
6419                owner.removeUriPermissionsLocked(mode);
6420            } else {
6421                owner.removeUriPermissionLocked(uri, mode);
6422            }
6423        }
6424    }
6425
6426    private void schedulePersistUriGrants() {
6427        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6428            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6429                    10 * DateUtils.SECOND_IN_MILLIS);
6430        }
6431    }
6432
6433    private void writeGrantedUriPermissions() {
6434        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6435
6436        // Snapshot permissions so we can persist without lock
6437        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6438        synchronized (this) {
6439            final int size = mGrantedUriPermissions.size();
6440            for (int i = 0 ; i < size; i++) {
6441                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6442                    if (perm.persistedModeFlags != 0) {
6443                        persist.add(perm.snapshot());
6444                    }
6445                }
6446            }
6447        }
6448
6449        FileOutputStream fos = null;
6450        try {
6451            fos = mGrantFile.startWrite();
6452
6453            XmlSerializer out = new FastXmlSerializer();
6454            out.setOutput(fos, "utf-8");
6455            out.startDocument(null, true);
6456            out.startTag(null, TAG_URI_GRANTS);
6457            for (UriPermission.Snapshot perm : persist) {
6458                out.startTag(null, TAG_URI_GRANT);
6459                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6460                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6461                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6462                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6463                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6464                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6465                out.endTag(null, TAG_URI_GRANT);
6466            }
6467            out.endTag(null, TAG_URI_GRANTS);
6468            out.endDocument();
6469
6470            mGrantFile.finishWrite(fos);
6471        } catch (IOException e) {
6472            if (fos != null) {
6473                mGrantFile.failWrite(fos);
6474            }
6475        }
6476    }
6477
6478    private void readGrantedUriPermissionsLocked() {
6479        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6480
6481        final long now = System.currentTimeMillis();
6482
6483        FileInputStream fis = null;
6484        try {
6485            fis = mGrantFile.openRead();
6486            final XmlPullParser in = Xml.newPullParser();
6487            in.setInput(fis, null);
6488
6489            int type;
6490            while ((type = in.next()) != END_DOCUMENT) {
6491                final String tag = in.getName();
6492                if (type == START_TAG) {
6493                    if (TAG_URI_GRANT.equals(tag)) {
6494                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6495                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6496                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6497                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6498                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6499                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6500
6501                        // Sanity check that provider still belongs to source package
6502                        final ProviderInfo pi = getProviderInfoLocked(
6503                                uri.getAuthority(), userHandle);
6504                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6505                            int targetUid = -1;
6506                            try {
6507                                targetUid = AppGlobals.getPackageManager()
6508                                        .getPackageUid(targetPkg, userHandle);
6509                            } catch (RemoteException e) {
6510                            }
6511                            if (targetUid != -1) {
6512                                final UriPermission perm = findOrCreateUriPermissionLocked(
6513                                        sourcePkg, targetPkg, targetUid, uri);
6514                                perm.initPersistedModes(modeFlags, createdTime);
6515                            }
6516                        } else {
6517                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6518                                    + " but instead found " + pi);
6519                        }
6520                    }
6521                }
6522            }
6523        } catch (FileNotFoundException e) {
6524            // Missing grants is okay
6525        } catch (IOException e) {
6526            Log.wtf(TAG, "Failed reading Uri grants", e);
6527        } catch (XmlPullParserException e) {
6528            Log.wtf(TAG, "Failed reading Uri grants", e);
6529        } finally {
6530            IoUtils.closeQuietly(fis);
6531        }
6532    }
6533
6534    @Override
6535    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6536        enforceNotIsolatedCaller("takePersistableUriPermission");
6537
6538        Preconditions.checkFlagsArgument(modeFlags,
6539                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6540
6541        synchronized (this) {
6542            final int callingUid = Binder.getCallingUid();
6543            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6544            if (perm == null) {
6545                throw new SecurityException("No permission grant found for UID " + callingUid
6546                        + " and Uri " + uri.toSafeString());
6547            }
6548
6549            boolean persistChanged = perm.takePersistableModes(modeFlags);
6550            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6551
6552            if (persistChanged) {
6553                schedulePersistUriGrants();
6554            }
6555        }
6556    }
6557
6558    @Override
6559    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6560        enforceNotIsolatedCaller("releasePersistableUriPermission");
6561
6562        Preconditions.checkFlagsArgument(modeFlags,
6563                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6564
6565        synchronized (this) {
6566            final int callingUid = Binder.getCallingUid();
6567
6568            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6569            if (perm == null) {
6570                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6571                        + uri.toSafeString());
6572                return;
6573            }
6574
6575            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6576            removeUriPermissionIfNeededLocked(perm);
6577            if (persistChanged) {
6578                schedulePersistUriGrants();
6579            }
6580        }
6581    }
6582
6583    /**
6584     * Prune any older {@link UriPermission} for the given UID until outstanding
6585     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6586     *
6587     * @return if any mutations occured that require persisting.
6588     */
6589    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6590        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6591        if (perms == null) return false;
6592        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6593
6594        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6595        for (UriPermission perm : perms.values()) {
6596            if (perm.persistedModeFlags != 0) {
6597                persisted.add(perm);
6598            }
6599        }
6600
6601        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6602        if (trimCount <= 0) return false;
6603
6604        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6605        for (int i = 0; i < trimCount; i++) {
6606            final UriPermission perm = persisted.get(i);
6607
6608            if (DEBUG_URI_PERMISSION) {
6609                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6610            }
6611
6612            perm.releasePersistableModes(~0);
6613            removeUriPermissionIfNeededLocked(perm);
6614        }
6615
6616        return true;
6617    }
6618
6619    @Override
6620    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6621            String packageName, boolean incoming) {
6622        enforceNotIsolatedCaller("getPersistedUriPermissions");
6623        Preconditions.checkNotNull(packageName, "packageName");
6624
6625        final int callingUid = Binder.getCallingUid();
6626        final IPackageManager pm = AppGlobals.getPackageManager();
6627        try {
6628            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6629            if (packageUid != callingUid) {
6630                throw new SecurityException(
6631                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6632            }
6633        } catch (RemoteException e) {
6634            throw new SecurityException("Failed to verify package name ownership");
6635        }
6636
6637        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6638        synchronized (this) {
6639            if (incoming) {
6640                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6641                if (perms == null) {
6642                    Slog.w(TAG, "No permission grants found for " + packageName);
6643                } else {
6644                    final int size = perms.size();
6645                    for (int i = 0; i < size; i++) {
6646                        final UriPermission perm = perms.valueAt(i);
6647                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6648                            result.add(perm.buildPersistedPublicApiObject());
6649                        }
6650                    }
6651                }
6652            } else {
6653                final int size = mGrantedUriPermissions.size();
6654                for (int i = 0; i < size; i++) {
6655                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6656                    final int permsSize = perms.size();
6657                    for (int j = 0; j < permsSize; j++) {
6658                        final UriPermission perm = perms.valueAt(j);
6659                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6660                            result.add(perm.buildPersistedPublicApiObject());
6661                        }
6662                    }
6663                }
6664            }
6665        }
6666        return new ParceledListSlice<android.content.UriPermission>(result);
6667    }
6668
6669    @Override
6670    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6671        synchronized (this) {
6672            ProcessRecord app =
6673                who != null ? getRecordForAppLocked(who) : null;
6674            if (app == null) return;
6675
6676            Message msg = Message.obtain();
6677            msg.what = WAIT_FOR_DEBUGGER_MSG;
6678            msg.obj = app;
6679            msg.arg1 = waiting ? 1 : 0;
6680            mHandler.sendMessage(msg);
6681        }
6682    }
6683
6684    @Override
6685    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6686        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6687        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6688        outInfo.availMem = Process.getFreeMemory();
6689        outInfo.totalMem = Process.getTotalMemory();
6690        outInfo.threshold = homeAppMem;
6691        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6692        outInfo.hiddenAppThreshold = cachedAppMem;
6693        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6694                ProcessList.SERVICE_ADJ);
6695        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6696                ProcessList.VISIBLE_APP_ADJ);
6697        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6698                ProcessList.FOREGROUND_APP_ADJ);
6699    }
6700
6701    // =========================================================
6702    // TASK MANAGEMENT
6703    // =========================================================
6704
6705    @Override
6706    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6707                         IThumbnailReceiver receiver) {
6708        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6709
6710        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6711        ActivityRecord topRecord = null;
6712
6713        synchronized(this) {
6714            if (localLOGV) Slog.v(
6715                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6716                + ", receiver=" + receiver);
6717
6718            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6719                    != PackageManager.PERMISSION_GRANTED) {
6720                if (receiver != null) {
6721                    // If the caller wants to wait for pending thumbnails,
6722                    // it ain't gonna get them.
6723                    try {
6724                        receiver.finished();
6725                    } catch (RemoteException ex) {
6726                    }
6727                }
6728                String msg = "Permission Denial: getTasks() from pid="
6729                        + Binder.getCallingPid()
6730                        + ", uid=" + Binder.getCallingUid()
6731                        + " requires " + android.Manifest.permission.GET_TASKS;
6732                Slog.w(TAG, msg);
6733                throw new SecurityException(msg);
6734            }
6735
6736            // TODO: Improve with MRU list from all ActivityStacks.
6737            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6738
6739            if (!pending.pendingRecords.isEmpty()) {
6740                mPendingThumbnails.add(pending);
6741            }
6742        }
6743
6744        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6745
6746        if (topRecord != null) {
6747            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6748            try {
6749                IApplicationThread topThumbnail = topRecord.app.thread;
6750                topThumbnail.requestThumbnail(topRecord.appToken);
6751            } catch (Exception e) {
6752                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6753                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6754            }
6755        }
6756
6757        if (pending == null && receiver != null) {
6758            // In this case all thumbnails were available and the client
6759            // is being asked to be told when the remaining ones come in...
6760            // which is unusually, since the top-most currently running
6761            // activity should never have a canned thumbnail!  Oh well.
6762            try {
6763                receiver.finished();
6764            } catch (RemoteException ex) {
6765            }
6766        }
6767
6768        return list;
6769    }
6770
6771    TaskRecord getMostRecentTask() {
6772        return mRecentTasks.get(0);
6773    }
6774
6775    @Override
6776    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6777            int flags, int userId) {
6778        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6779                false, true, "getRecentTasks", null);
6780
6781        synchronized (this) {
6782            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6783                    "getRecentTasks()");
6784            final boolean detailed = checkCallingPermission(
6785                    android.Manifest.permission.GET_DETAILED_TASKS)
6786                    == PackageManager.PERMISSION_GRANTED;
6787
6788            IPackageManager pm = AppGlobals.getPackageManager();
6789
6790            final int N = mRecentTasks.size();
6791            ArrayList<ActivityManager.RecentTaskInfo> res
6792                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6793                            maxNum < N ? maxNum : N);
6794            for (int i=0; i<N && maxNum > 0; i++) {
6795                TaskRecord tr = mRecentTasks.get(i);
6796                // Only add calling user's recent tasks
6797                if (tr.userId != userId) continue;
6798                // Return the entry if desired by the caller.  We always return
6799                // the first entry, because callers always expect this to be the
6800                // foreground app.  We may filter others if the caller has
6801                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6802                // we should exclude the entry.
6803
6804                if (i == 0
6805                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6806                        || (tr.intent == null)
6807                        || ((tr.intent.getFlags()
6808                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6809                    ActivityManager.RecentTaskInfo rti
6810                            = new ActivityManager.RecentTaskInfo();
6811                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6812                    rti.persistentId = tr.taskId;
6813                    rti.baseIntent = new Intent(
6814                            tr.intent != null ? tr.intent : tr.affinityIntent);
6815                    if (!detailed) {
6816                        rti.baseIntent.replaceExtras((Bundle)null);
6817                    }
6818                    rti.origActivity = tr.origActivity;
6819                    rti.description = tr.lastDescription;
6820                    rti.stackId = tr.stack.mStackId;
6821
6822                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6823                        // Check whether this activity is currently available.
6824                        try {
6825                            if (rti.origActivity != null) {
6826                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6827                                        == null) {
6828                                    continue;
6829                                }
6830                            } else if (rti.baseIntent != null) {
6831                                if (pm.queryIntentActivities(rti.baseIntent,
6832                                        null, 0, userId) == null) {
6833                                    continue;
6834                                }
6835                            }
6836                        } catch (RemoteException e) {
6837                            // Will never happen.
6838                        }
6839                    }
6840
6841                    res.add(rti);
6842                    maxNum--;
6843                }
6844            }
6845            return res;
6846        }
6847    }
6848
6849    private TaskRecord recentTaskForIdLocked(int id) {
6850        final int N = mRecentTasks.size();
6851            for (int i=0; i<N; i++) {
6852                TaskRecord tr = mRecentTasks.get(i);
6853                if (tr.taskId == id) {
6854                    return tr;
6855                }
6856            }
6857            return null;
6858    }
6859
6860    @Override
6861    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6862        synchronized (this) {
6863            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6864                    "getTaskThumbnails()");
6865            TaskRecord tr = recentTaskForIdLocked(id);
6866            if (tr != null) {
6867                return tr.getTaskThumbnailsLocked();
6868            }
6869        }
6870        return null;
6871    }
6872
6873    @Override
6874    public Bitmap getTaskTopThumbnail(int id) {
6875        synchronized (this) {
6876            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6877                    "getTaskTopThumbnail()");
6878            TaskRecord tr = recentTaskForIdLocked(id);
6879            if (tr != null) {
6880                return tr.getTaskTopThumbnailLocked();
6881            }
6882        }
6883        return null;
6884    }
6885
6886    @Override
6887    public boolean removeSubTask(int taskId, int subTaskIndex) {
6888        synchronized (this) {
6889            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6890                    "removeSubTask()");
6891            long ident = Binder.clearCallingIdentity();
6892            try {
6893                TaskRecord tr = recentTaskForIdLocked(taskId);
6894                if (tr != null) {
6895                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6896                }
6897                return false;
6898            } finally {
6899                Binder.restoreCallingIdentity(ident);
6900            }
6901        }
6902    }
6903
6904    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6905        if (!pr.killedByAm) {
6906            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6907            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6908                    pr.processName, pr.setAdj, reason);
6909            pr.killedByAm = true;
6910            Process.killProcessQuiet(pr.pid);
6911        }
6912    }
6913
6914    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6915        tr.disposeThumbnail();
6916        mRecentTasks.remove(tr);
6917        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6918        Intent baseIntent = new Intent(
6919                tr.intent != null ? tr.intent : tr.affinityIntent);
6920        ComponentName component = baseIntent.getComponent();
6921        if (component == null) {
6922            Slog.w(TAG, "Now component for base intent of task: " + tr);
6923            return;
6924        }
6925
6926        // Find any running services associated with this app.
6927        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6928
6929        if (killProcesses) {
6930            // Find any running processes associated with this app.
6931            final String pkg = component.getPackageName();
6932            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6933            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6934            for (int i=0; i<pmap.size(); i++) {
6935                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6936                for (int j=0; j<uids.size(); j++) {
6937                    ProcessRecord proc = uids.valueAt(j);
6938                    if (proc.userId != tr.userId) {
6939                        continue;
6940                    }
6941                    if (!proc.pkgList.containsKey(pkg)) {
6942                        continue;
6943                    }
6944                    procs.add(proc);
6945                }
6946            }
6947
6948            // Kill the running processes.
6949            for (int i=0; i<procs.size(); i++) {
6950                ProcessRecord pr = procs.get(i);
6951                if (pr == mHomeProcess) {
6952                    // Don't kill the home process along with tasks from the same package.
6953                    continue;
6954                }
6955                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6956                    killUnneededProcessLocked(pr, "remove task");
6957                } else {
6958                    pr.waitingToKill = "remove task";
6959                }
6960            }
6961        }
6962    }
6963
6964    @Override
6965    public boolean removeTask(int taskId, int flags) {
6966        synchronized (this) {
6967            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6968                    "removeTask()");
6969            long ident = Binder.clearCallingIdentity();
6970            try {
6971                TaskRecord tr = recentTaskForIdLocked(taskId);
6972                if (tr != null) {
6973                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
6974                    if (r != null) {
6975                        cleanUpRemovedTaskLocked(tr, flags);
6976                        return true;
6977                    }
6978                    if (tr.mActivities.size() == 0) {
6979                        // Caller is just removing a recent task that is
6980                        // not actively running.  That is easy!
6981                        cleanUpRemovedTaskLocked(tr, flags);
6982                        return true;
6983                    }
6984                    Slog.w(TAG, "removeTask: task " + taskId
6985                            + " does not have activities to remove, "
6986                            + " but numActivities=" + tr.numActivities
6987                            + ": " + tr);
6988                }
6989            } finally {
6990                Binder.restoreCallingIdentity(ident);
6991            }
6992        }
6993        return false;
6994    }
6995
6996    /**
6997     * TODO: Add mController hook
6998     */
6999    @Override
7000    public void moveTaskToFront(int task, int flags, Bundle options) {
7001        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7002                "moveTaskToFront()");
7003
7004        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
7005        synchronized(this) {
7006            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7007                    Binder.getCallingUid(), "Task to front")) {
7008                ActivityOptions.abort(options);
7009                return;
7010            }
7011            final long origId = Binder.clearCallingIdentity();
7012            try {
7013                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7014            } finally {
7015                Binder.restoreCallingIdentity(origId);
7016            }
7017            ActivityOptions.abort(options);
7018        }
7019    }
7020
7021    @Override
7022    public void moveTaskToBack(int taskId) {
7023        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7024                "moveTaskToBack()");
7025
7026        synchronized(this) {
7027            TaskRecord tr = recentTaskForIdLocked(taskId);
7028            if (tr != null) {
7029                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7030                ActivityStack stack = tr.stack;
7031                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7032                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7033                            Binder.getCallingUid(), "Task to back")) {
7034                        return;
7035                    }
7036                }
7037                final long origId = Binder.clearCallingIdentity();
7038                try {
7039                    stack.moveTaskToBackLocked(taskId, null);
7040                } finally {
7041                    Binder.restoreCallingIdentity(origId);
7042                }
7043            }
7044        }
7045    }
7046
7047    /**
7048     * Moves an activity, and all of the other activities within the same task, to the bottom
7049     * of the history stack.  The activity's order within the task is unchanged.
7050     *
7051     * @param token A reference to the activity we wish to move
7052     * @param nonRoot If false then this only works if the activity is the root
7053     *                of a task; if true it will work for any activity in a task.
7054     * @return Returns true if the move completed, false if not.
7055     */
7056    @Override
7057    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7058        enforceNotIsolatedCaller("moveActivityTaskToBack");
7059        synchronized(this) {
7060            final long origId = Binder.clearCallingIdentity();
7061            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7062            if (taskId >= 0) {
7063                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7064            }
7065            Binder.restoreCallingIdentity(origId);
7066        }
7067        return false;
7068    }
7069
7070    @Override
7071    public void moveTaskBackwards(int task) {
7072        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7073                "moveTaskBackwards()");
7074
7075        synchronized(this) {
7076            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7077                    Binder.getCallingUid(), "Task backwards")) {
7078                return;
7079            }
7080            final long origId = Binder.clearCallingIdentity();
7081            moveTaskBackwardsLocked(task);
7082            Binder.restoreCallingIdentity(origId);
7083        }
7084    }
7085
7086    private final void moveTaskBackwardsLocked(int task) {
7087        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7088    }
7089
7090    @Override
7091    public IBinder getHomeActivityToken() throws RemoteException {
7092        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7093                "getHomeActivityToken()");
7094        synchronized (this) {
7095            return mStackSupervisor.getHomeActivityToken();
7096        }
7097    }
7098
7099    @Override
7100    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7101            IActivityContainerCallback callback) throws RemoteException {
7102        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7103                "createActivityContainer()");
7104        synchronized (this) {
7105            if (parentActivityToken == null) {
7106                throw new IllegalArgumentException("parent token must not be null");
7107            }
7108            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7109            if (r == null) {
7110                return null;
7111            }
7112            if (callback == null) {
7113                throw new IllegalArgumentException("callback must not be null");
7114            }
7115            return mStackSupervisor.createActivityContainer(r, callback);
7116        }
7117    }
7118
7119    @Override
7120    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7121        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7122                "deleteActivityContainer()");
7123        synchronized (this) {
7124            mStackSupervisor.deleteActivityContainer(container);
7125        }
7126    }
7127
7128    @Override
7129    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7130            throws RemoteException {
7131        synchronized (this) {
7132            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7133            if (stack != null) {
7134                return stack.mActivityContainer;
7135            }
7136            return null;
7137        }
7138    }
7139
7140    @Override
7141    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7142        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7143                "moveTaskToStack()");
7144        if (stackId == HOME_STACK_ID) {
7145            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7146                    new RuntimeException("here").fillInStackTrace());
7147        }
7148        synchronized (this) {
7149            long ident = Binder.clearCallingIdentity();
7150            try {
7151                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7152                        + stackId + " toTop=" + toTop);
7153                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7154            } finally {
7155                Binder.restoreCallingIdentity(ident);
7156            }
7157        }
7158    }
7159
7160    @Override
7161    public void resizeStack(int stackBoxId, Rect bounds) {
7162        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7163                "resizeStackBox()");
7164        long ident = Binder.clearCallingIdentity();
7165        try {
7166            mWindowManager.resizeStack(stackBoxId, bounds);
7167        } finally {
7168            Binder.restoreCallingIdentity(ident);
7169        }
7170    }
7171
7172    @Override
7173    public List<StackInfo> getAllStackInfos() {
7174        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7175                "getAllStackInfos()");
7176        long ident = Binder.clearCallingIdentity();
7177        try {
7178            synchronized (this) {
7179                return mStackSupervisor.getAllStackInfosLocked();
7180            }
7181        } finally {
7182            Binder.restoreCallingIdentity(ident);
7183        }
7184    }
7185
7186    @Override
7187    public StackInfo getStackInfo(int stackId) {
7188        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7189                "getStackInfo()");
7190        long ident = Binder.clearCallingIdentity();
7191        try {
7192            synchronized (this) {
7193                return mStackSupervisor.getStackInfoLocked(stackId);
7194            }
7195        } finally {
7196            Binder.restoreCallingIdentity(ident);
7197        }
7198    }
7199
7200    @Override
7201    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7202        synchronized(this) {
7203            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7204        }
7205    }
7206
7207    // =========================================================
7208    // THUMBNAILS
7209    // =========================================================
7210
7211    public void reportThumbnail(IBinder token,
7212            Bitmap thumbnail, CharSequence description) {
7213        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7214        final long origId = Binder.clearCallingIdentity();
7215        sendPendingThumbnail(null, token, thumbnail, description, true);
7216        Binder.restoreCallingIdentity(origId);
7217    }
7218
7219    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7220            Bitmap thumbnail, CharSequence description, boolean always) {
7221        TaskRecord task;
7222        ArrayList<PendingThumbnailsRecord> receivers = null;
7223
7224        //System.out.println("Send pending thumbnail: " + r);
7225
7226        synchronized(this) {
7227            if (r == null) {
7228                r = ActivityRecord.isInStackLocked(token);
7229                if (r == null) {
7230                    return;
7231                }
7232            }
7233            if (thumbnail == null && r.thumbHolder != null) {
7234                thumbnail = r.thumbHolder.lastThumbnail;
7235                description = r.thumbHolder.lastDescription;
7236            }
7237            if (thumbnail == null && !always) {
7238                // If there is no thumbnail, and this entry is not actually
7239                // going away, then abort for now and pick up the next
7240                // thumbnail we get.
7241                return;
7242            }
7243            task = r.task;
7244
7245            int N = mPendingThumbnails.size();
7246            int i=0;
7247            while (i<N) {
7248                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7249                //System.out.println("Looking in " + pr.pendingRecords);
7250                if (pr.pendingRecords.remove(r)) {
7251                    if (receivers == null) {
7252                        receivers = new ArrayList<PendingThumbnailsRecord>();
7253                    }
7254                    receivers.add(pr);
7255                    if (pr.pendingRecords.size() == 0) {
7256                        pr.finished = true;
7257                        mPendingThumbnails.remove(i);
7258                        N--;
7259                        continue;
7260                    }
7261                }
7262                i++;
7263            }
7264        }
7265
7266        if (receivers != null) {
7267            final int N = receivers.size();
7268            for (int i=0; i<N; i++) {
7269                try {
7270                    PendingThumbnailsRecord pr = receivers.get(i);
7271                    pr.receiver.newThumbnail(
7272                        task != null ? task.taskId : -1, thumbnail, description);
7273                    if (pr.finished) {
7274                        pr.receiver.finished();
7275                    }
7276                } catch (Exception e) {
7277                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7278                }
7279            }
7280        }
7281    }
7282
7283    // =========================================================
7284    // CONTENT PROVIDERS
7285    // =========================================================
7286
7287    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7288        List<ProviderInfo> providers = null;
7289        try {
7290            providers = AppGlobals.getPackageManager().
7291                queryContentProviders(app.processName, app.uid,
7292                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7293        } catch (RemoteException ex) {
7294        }
7295        if (DEBUG_MU)
7296            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7297        int userId = app.userId;
7298        if (providers != null) {
7299            int N = providers.size();
7300            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7301            for (int i=0; i<N; i++) {
7302                ProviderInfo cpi =
7303                    (ProviderInfo)providers.get(i);
7304                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7305                        cpi.name, cpi.flags);
7306                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7307                    // This is a singleton provider, but a user besides the
7308                    // default user is asking to initialize a process it runs
7309                    // in...  well, no, it doesn't actually run in this process,
7310                    // it runs in the process of the default user.  Get rid of it.
7311                    providers.remove(i);
7312                    N--;
7313                    i--;
7314                    continue;
7315                }
7316
7317                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7318                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7319                if (cpr == null) {
7320                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7321                    mProviderMap.putProviderByClass(comp, cpr);
7322                }
7323                if (DEBUG_MU)
7324                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7325                app.pubProviders.put(cpi.name, cpr);
7326                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7327                    // Don't add this if it is a platform component that is marked
7328                    // to run in multiple processes, because this is actually
7329                    // part of the framework so doesn't make sense to track as a
7330                    // separate apk in the process.
7331                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7332                }
7333                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7334            }
7335        }
7336        return providers;
7337    }
7338
7339    /**
7340     * Check if {@link ProcessRecord} has a possible chance at accessing the
7341     * given {@link ProviderInfo}. Final permission checking is always done
7342     * in {@link ContentProvider}.
7343     */
7344    private final String checkContentProviderPermissionLocked(
7345            ProviderInfo cpi, ProcessRecord r) {
7346        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7347        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7348        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7349                cpi.applicationInfo.uid, cpi.exported)
7350                == PackageManager.PERMISSION_GRANTED) {
7351            return null;
7352        }
7353        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7354                cpi.applicationInfo.uid, cpi.exported)
7355                == PackageManager.PERMISSION_GRANTED) {
7356            return null;
7357        }
7358
7359        PathPermission[] pps = cpi.pathPermissions;
7360        if (pps != null) {
7361            int i = pps.length;
7362            while (i > 0) {
7363                i--;
7364                PathPermission pp = pps[i];
7365                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7366                        cpi.applicationInfo.uid, cpi.exported)
7367                        == PackageManager.PERMISSION_GRANTED) {
7368                    return null;
7369                }
7370                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7371                        cpi.applicationInfo.uid, cpi.exported)
7372                        == PackageManager.PERMISSION_GRANTED) {
7373                    return null;
7374                }
7375            }
7376        }
7377
7378        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7379        if (perms != null) {
7380            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7381                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7382                    return null;
7383                }
7384            }
7385        }
7386
7387        String msg;
7388        if (!cpi.exported) {
7389            msg = "Permission Denial: opening provider " + cpi.name
7390                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7391                    + ", uid=" + callingUid + ") that is not exported from uid "
7392                    + cpi.applicationInfo.uid;
7393        } else {
7394            msg = "Permission Denial: opening provider " + cpi.name
7395                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7396                    + ", uid=" + callingUid + ") requires "
7397                    + cpi.readPermission + " or " + cpi.writePermission;
7398        }
7399        Slog.w(TAG, msg);
7400        return msg;
7401    }
7402
7403    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7404            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7405        if (r != null) {
7406            for (int i=0; i<r.conProviders.size(); i++) {
7407                ContentProviderConnection conn = r.conProviders.get(i);
7408                if (conn.provider == cpr) {
7409                    if (DEBUG_PROVIDER) Slog.v(TAG,
7410                            "Adding provider requested by "
7411                            + r.processName + " from process "
7412                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7413                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7414                    if (stable) {
7415                        conn.stableCount++;
7416                        conn.numStableIncs++;
7417                    } else {
7418                        conn.unstableCount++;
7419                        conn.numUnstableIncs++;
7420                    }
7421                    return conn;
7422                }
7423            }
7424            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7425            if (stable) {
7426                conn.stableCount = 1;
7427                conn.numStableIncs = 1;
7428            } else {
7429                conn.unstableCount = 1;
7430                conn.numUnstableIncs = 1;
7431            }
7432            cpr.connections.add(conn);
7433            r.conProviders.add(conn);
7434            return conn;
7435        }
7436        cpr.addExternalProcessHandleLocked(externalProcessToken);
7437        return null;
7438    }
7439
7440    boolean decProviderCountLocked(ContentProviderConnection conn,
7441            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7442        if (conn != null) {
7443            cpr = conn.provider;
7444            if (DEBUG_PROVIDER) Slog.v(TAG,
7445                    "Removing provider requested by "
7446                    + conn.client.processName + " from process "
7447                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7448                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7449            if (stable) {
7450                conn.stableCount--;
7451            } else {
7452                conn.unstableCount--;
7453            }
7454            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7455                cpr.connections.remove(conn);
7456                conn.client.conProviders.remove(conn);
7457                return true;
7458            }
7459            return false;
7460        }
7461        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7462        return false;
7463    }
7464
7465    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7466            String name, IBinder token, boolean stable, int userId) {
7467        ContentProviderRecord cpr;
7468        ContentProviderConnection conn = null;
7469        ProviderInfo cpi = null;
7470
7471        synchronized(this) {
7472            ProcessRecord r = null;
7473            if (caller != null) {
7474                r = getRecordForAppLocked(caller);
7475                if (r == null) {
7476                    throw new SecurityException(
7477                            "Unable to find app for caller " + caller
7478                          + " (pid=" + Binder.getCallingPid()
7479                          + ") when getting content provider " + name);
7480                }
7481            }
7482
7483            // First check if this content provider has been published...
7484            cpr = mProviderMap.getProviderByName(name, userId);
7485            boolean providerRunning = cpr != null;
7486            if (providerRunning) {
7487                cpi = cpr.info;
7488                String msg;
7489                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7490                    throw new SecurityException(msg);
7491                }
7492
7493                if (r != null && cpr.canRunHere(r)) {
7494                    // This provider has been published or is in the process
7495                    // of being published...  but it is also allowed to run
7496                    // in the caller's process, so don't make a connection
7497                    // and just let the caller instantiate its own instance.
7498                    ContentProviderHolder holder = cpr.newHolder(null);
7499                    // don't give caller the provider object, it needs
7500                    // to make its own.
7501                    holder.provider = null;
7502                    return holder;
7503                }
7504
7505                final long origId = Binder.clearCallingIdentity();
7506
7507                // In this case the provider instance already exists, so we can
7508                // return it right away.
7509                conn = incProviderCountLocked(r, cpr, token, stable);
7510                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7511                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7512                        // If this is a perceptible app accessing the provider,
7513                        // make sure to count it as being accessed and thus
7514                        // back up on the LRU list.  This is good because
7515                        // content providers are often expensive to start.
7516                        updateLruProcessLocked(cpr.proc, false, null);
7517                    }
7518                }
7519
7520                if (cpr.proc != null) {
7521                    if (false) {
7522                        if (cpr.name.flattenToShortString().equals(
7523                                "com.android.providers.calendar/.CalendarProvider2")) {
7524                            Slog.v(TAG, "****************** KILLING "
7525                                + cpr.name.flattenToShortString());
7526                            Process.killProcess(cpr.proc.pid);
7527                        }
7528                    }
7529                    boolean success = updateOomAdjLocked(cpr.proc);
7530                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7531                    // NOTE: there is still a race here where a signal could be
7532                    // pending on the process even though we managed to update its
7533                    // adj level.  Not sure what to do about this, but at least
7534                    // the race is now smaller.
7535                    if (!success) {
7536                        // Uh oh...  it looks like the provider's process
7537                        // has been killed on us.  We need to wait for a new
7538                        // process to be started, and make sure its death
7539                        // doesn't kill our process.
7540                        Slog.i(TAG,
7541                                "Existing provider " + cpr.name.flattenToShortString()
7542                                + " is crashing; detaching " + r);
7543                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7544                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7545                        if (!lastRef) {
7546                            // This wasn't the last ref our process had on
7547                            // the provider...  we have now been killed, bail.
7548                            return null;
7549                        }
7550                        providerRunning = false;
7551                        conn = null;
7552                    }
7553                }
7554
7555                Binder.restoreCallingIdentity(origId);
7556            }
7557
7558            boolean singleton;
7559            if (!providerRunning) {
7560                try {
7561                    cpi = AppGlobals.getPackageManager().
7562                        resolveContentProvider(name,
7563                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7564                } catch (RemoteException ex) {
7565                }
7566                if (cpi == null) {
7567                    return null;
7568                }
7569                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7570                        cpi.name, cpi.flags);
7571                if (singleton) {
7572                    userId = 0;
7573                }
7574                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7575
7576                String msg;
7577                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7578                    throw new SecurityException(msg);
7579                }
7580
7581                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7582                        && !cpi.processName.equals("system")) {
7583                    // If this content provider does not run in the system
7584                    // process, and the system is not yet ready to run other
7585                    // processes, then fail fast instead of hanging.
7586                    throw new IllegalArgumentException(
7587                            "Attempt to launch content provider before system ready");
7588                }
7589
7590                // Make sure that the user who owns this provider is started.  If not,
7591                // we don't want to allow it to run.
7592                if (mStartedUsers.get(userId) == null) {
7593                    Slog.w(TAG, "Unable to launch app "
7594                            + cpi.applicationInfo.packageName + "/"
7595                            + cpi.applicationInfo.uid + " for provider "
7596                            + name + ": user " + userId + " is stopped");
7597                    return null;
7598                }
7599
7600                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7601                cpr = mProviderMap.getProviderByClass(comp, userId);
7602                final boolean firstClass = cpr == null;
7603                if (firstClass) {
7604                    try {
7605                        ApplicationInfo ai =
7606                            AppGlobals.getPackageManager().
7607                                getApplicationInfo(
7608                                        cpi.applicationInfo.packageName,
7609                                        STOCK_PM_FLAGS, userId);
7610                        if (ai == null) {
7611                            Slog.w(TAG, "No package info for content provider "
7612                                    + cpi.name);
7613                            return null;
7614                        }
7615                        ai = getAppInfoForUser(ai, userId);
7616                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7617                    } catch (RemoteException ex) {
7618                        // pm is in same process, this will never happen.
7619                    }
7620                }
7621
7622                if (r != null && cpr.canRunHere(r)) {
7623                    // If this is a multiprocess provider, then just return its
7624                    // info and allow the caller to instantiate it.  Only do
7625                    // this if the provider is the same user as the caller's
7626                    // process, or can run as root (so can be in any process).
7627                    return cpr.newHolder(null);
7628                }
7629
7630                if (DEBUG_PROVIDER) {
7631                    RuntimeException e = new RuntimeException("here");
7632                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7633                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7634                }
7635
7636                // This is single process, and our app is now connecting to it.
7637                // See if we are already in the process of launching this
7638                // provider.
7639                final int N = mLaunchingProviders.size();
7640                int i;
7641                for (i=0; i<N; i++) {
7642                    if (mLaunchingProviders.get(i) == cpr) {
7643                        break;
7644                    }
7645                }
7646
7647                // If the provider is not already being launched, then get it
7648                // started.
7649                if (i >= N) {
7650                    final long origId = Binder.clearCallingIdentity();
7651
7652                    try {
7653                        // Content provider is now in use, its package can't be stopped.
7654                        try {
7655                            AppGlobals.getPackageManager().setPackageStoppedState(
7656                                    cpr.appInfo.packageName, false, userId);
7657                        } catch (RemoteException e) {
7658                        } catch (IllegalArgumentException e) {
7659                            Slog.w(TAG, "Failed trying to unstop package "
7660                                    + cpr.appInfo.packageName + ": " + e);
7661                        }
7662
7663                        // Use existing process if already started
7664                        ProcessRecord proc = getProcessRecordLocked(
7665                                cpi.processName, cpr.appInfo.uid, false);
7666                        if (proc != null && proc.thread != null) {
7667                            if (DEBUG_PROVIDER) {
7668                                Slog.d(TAG, "Installing in existing process " + proc);
7669                            }
7670                            proc.pubProviders.put(cpi.name, cpr);
7671                            try {
7672                                proc.thread.scheduleInstallProvider(cpi);
7673                            } catch (RemoteException e) {
7674                            }
7675                        } else {
7676                            proc = startProcessLocked(cpi.processName,
7677                                    cpr.appInfo, false, 0, "content provider",
7678                                    new ComponentName(cpi.applicationInfo.packageName,
7679                                            cpi.name), false, false, false);
7680                            if (proc == null) {
7681                                Slog.w(TAG, "Unable to launch app "
7682                                        + cpi.applicationInfo.packageName + "/"
7683                                        + cpi.applicationInfo.uid + " for provider "
7684                                        + name + ": process is bad");
7685                                return null;
7686                            }
7687                        }
7688                        cpr.launchingApp = proc;
7689                        mLaunchingProviders.add(cpr);
7690                    } finally {
7691                        Binder.restoreCallingIdentity(origId);
7692                    }
7693                }
7694
7695                // Make sure the provider is published (the same provider class
7696                // may be published under multiple names).
7697                if (firstClass) {
7698                    mProviderMap.putProviderByClass(comp, cpr);
7699                }
7700
7701                mProviderMap.putProviderByName(name, cpr);
7702                conn = incProviderCountLocked(r, cpr, token, stable);
7703                if (conn != null) {
7704                    conn.waiting = true;
7705                }
7706            }
7707        }
7708
7709        // Wait for the provider to be published...
7710        synchronized (cpr) {
7711            while (cpr.provider == null) {
7712                if (cpr.launchingApp == null) {
7713                    Slog.w(TAG, "Unable to launch app "
7714                            + cpi.applicationInfo.packageName + "/"
7715                            + cpi.applicationInfo.uid + " for provider "
7716                            + name + ": launching app became null");
7717                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7718                            UserHandle.getUserId(cpi.applicationInfo.uid),
7719                            cpi.applicationInfo.packageName,
7720                            cpi.applicationInfo.uid, name);
7721                    return null;
7722                }
7723                try {
7724                    if (DEBUG_MU) {
7725                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7726                                + cpr.launchingApp);
7727                    }
7728                    if (conn != null) {
7729                        conn.waiting = true;
7730                    }
7731                    cpr.wait();
7732                } catch (InterruptedException ex) {
7733                } finally {
7734                    if (conn != null) {
7735                        conn.waiting = false;
7736                    }
7737                }
7738            }
7739        }
7740        return cpr != null ? cpr.newHolder(conn) : null;
7741    }
7742
7743    public final ContentProviderHolder getContentProvider(
7744            IApplicationThread caller, String name, int userId, boolean stable) {
7745        enforceNotIsolatedCaller("getContentProvider");
7746        if (caller == null) {
7747            String msg = "null IApplicationThread when getting content provider "
7748                    + name;
7749            Slog.w(TAG, msg);
7750            throw new SecurityException(msg);
7751        }
7752
7753        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7754                false, true, "getContentProvider", null);
7755        return getContentProviderImpl(caller, name, null, stable, userId);
7756    }
7757
7758    public ContentProviderHolder getContentProviderExternal(
7759            String name, int userId, IBinder token) {
7760        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7761            "Do not have permission in call getContentProviderExternal()");
7762        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7763                false, true, "getContentProvider", null);
7764        return getContentProviderExternalUnchecked(name, token, userId);
7765    }
7766
7767    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7768            IBinder token, int userId) {
7769        return getContentProviderImpl(null, name, token, true, userId);
7770    }
7771
7772    /**
7773     * Drop a content provider from a ProcessRecord's bookkeeping
7774     */
7775    public void removeContentProvider(IBinder connection, boolean stable) {
7776        enforceNotIsolatedCaller("removeContentProvider");
7777        synchronized (this) {
7778            ContentProviderConnection conn;
7779            try {
7780                conn = (ContentProviderConnection)connection;
7781            } catch (ClassCastException e) {
7782                String msg ="removeContentProvider: " + connection
7783                        + " not a ContentProviderConnection";
7784                Slog.w(TAG, msg);
7785                throw new IllegalArgumentException(msg);
7786            }
7787            if (conn == null) {
7788                throw new NullPointerException("connection is null");
7789            }
7790            if (decProviderCountLocked(conn, null, null, stable)) {
7791                updateOomAdjLocked();
7792            }
7793        }
7794    }
7795
7796    public void removeContentProviderExternal(String name, IBinder token) {
7797        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7798            "Do not have permission in call removeContentProviderExternal()");
7799        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7800    }
7801
7802    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7803        synchronized (this) {
7804            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7805            if(cpr == null) {
7806                //remove from mProvidersByClass
7807                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7808                return;
7809            }
7810
7811            //update content provider record entry info
7812            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7813            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7814            if (localCpr.hasExternalProcessHandles()) {
7815                if (localCpr.removeExternalProcessHandleLocked(token)) {
7816                    updateOomAdjLocked();
7817                } else {
7818                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7819                            + " with no external reference for token: "
7820                            + token + ".");
7821                }
7822            } else {
7823                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7824                        + " with no external references.");
7825            }
7826        }
7827    }
7828
7829    public final void publishContentProviders(IApplicationThread caller,
7830            List<ContentProviderHolder> providers) {
7831        if (providers == null) {
7832            return;
7833        }
7834
7835        enforceNotIsolatedCaller("publishContentProviders");
7836        synchronized (this) {
7837            final ProcessRecord r = getRecordForAppLocked(caller);
7838            if (DEBUG_MU)
7839                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7840            if (r == null) {
7841                throw new SecurityException(
7842                        "Unable to find app for caller " + caller
7843                      + " (pid=" + Binder.getCallingPid()
7844                      + ") when publishing content providers");
7845            }
7846
7847            final long origId = Binder.clearCallingIdentity();
7848
7849            final int N = providers.size();
7850            for (int i=0; i<N; i++) {
7851                ContentProviderHolder src = providers.get(i);
7852                if (src == null || src.info == null || src.provider == null) {
7853                    continue;
7854                }
7855                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7856                if (DEBUG_MU)
7857                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7858                if (dst != null) {
7859                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7860                    mProviderMap.putProviderByClass(comp, dst);
7861                    String names[] = dst.info.authority.split(";");
7862                    for (int j = 0; j < names.length; j++) {
7863                        mProviderMap.putProviderByName(names[j], dst);
7864                    }
7865
7866                    int NL = mLaunchingProviders.size();
7867                    int j;
7868                    for (j=0; j<NL; j++) {
7869                        if (mLaunchingProviders.get(j) == dst) {
7870                            mLaunchingProviders.remove(j);
7871                            j--;
7872                            NL--;
7873                        }
7874                    }
7875                    synchronized (dst) {
7876                        dst.provider = src.provider;
7877                        dst.proc = r;
7878                        dst.notifyAll();
7879                    }
7880                    updateOomAdjLocked(r);
7881                }
7882            }
7883
7884            Binder.restoreCallingIdentity(origId);
7885        }
7886    }
7887
7888    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7889        ContentProviderConnection conn;
7890        try {
7891            conn = (ContentProviderConnection)connection;
7892        } catch (ClassCastException e) {
7893            String msg ="refContentProvider: " + connection
7894                    + " not a ContentProviderConnection";
7895            Slog.w(TAG, msg);
7896            throw new IllegalArgumentException(msg);
7897        }
7898        if (conn == null) {
7899            throw new NullPointerException("connection is null");
7900        }
7901
7902        synchronized (this) {
7903            if (stable > 0) {
7904                conn.numStableIncs += stable;
7905            }
7906            stable = conn.stableCount + stable;
7907            if (stable < 0) {
7908                throw new IllegalStateException("stableCount < 0: " + stable);
7909            }
7910
7911            if (unstable > 0) {
7912                conn.numUnstableIncs += unstable;
7913            }
7914            unstable = conn.unstableCount + unstable;
7915            if (unstable < 0) {
7916                throw new IllegalStateException("unstableCount < 0: " + unstable);
7917            }
7918
7919            if ((stable+unstable) <= 0) {
7920                throw new IllegalStateException("ref counts can't go to zero here: stable="
7921                        + stable + " unstable=" + unstable);
7922            }
7923            conn.stableCount = stable;
7924            conn.unstableCount = unstable;
7925            return !conn.dead;
7926        }
7927    }
7928
7929    public void unstableProviderDied(IBinder connection) {
7930        ContentProviderConnection conn;
7931        try {
7932            conn = (ContentProviderConnection)connection;
7933        } catch (ClassCastException e) {
7934            String msg ="refContentProvider: " + connection
7935                    + " not a ContentProviderConnection";
7936            Slog.w(TAG, msg);
7937            throw new IllegalArgumentException(msg);
7938        }
7939        if (conn == null) {
7940            throw new NullPointerException("connection is null");
7941        }
7942
7943        // Safely retrieve the content provider associated with the connection.
7944        IContentProvider provider;
7945        synchronized (this) {
7946            provider = conn.provider.provider;
7947        }
7948
7949        if (provider == null) {
7950            // Um, yeah, we're way ahead of you.
7951            return;
7952        }
7953
7954        // Make sure the caller is being honest with us.
7955        if (provider.asBinder().pingBinder()) {
7956            // Er, no, still looks good to us.
7957            synchronized (this) {
7958                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7959                        + " says " + conn + " died, but we don't agree");
7960                return;
7961            }
7962        }
7963
7964        // Well look at that!  It's dead!
7965        synchronized (this) {
7966            if (conn.provider.provider != provider) {
7967                // But something changed...  good enough.
7968                return;
7969            }
7970
7971            ProcessRecord proc = conn.provider.proc;
7972            if (proc == null || proc.thread == null) {
7973                // Seems like the process is already cleaned up.
7974                return;
7975            }
7976
7977            // As far as we're concerned, this is just like receiving a
7978            // death notification...  just a bit prematurely.
7979            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
7980                    + ") early provider death");
7981            final long ident = Binder.clearCallingIdentity();
7982            try {
7983                appDiedLocked(proc, proc.pid, proc.thread);
7984            } finally {
7985                Binder.restoreCallingIdentity(ident);
7986            }
7987        }
7988    }
7989
7990    @Override
7991    public void appNotRespondingViaProvider(IBinder connection) {
7992        enforceCallingPermission(
7993                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
7994
7995        final ContentProviderConnection conn = (ContentProviderConnection) connection;
7996        if (conn == null) {
7997            Slog.w(TAG, "ContentProviderConnection is null");
7998            return;
7999        }
8000
8001        final ProcessRecord host = conn.provider.proc;
8002        if (host == null) {
8003            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8004            return;
8005        }
8006
8007        final long token = Binder.clearCallingIdentity();
8008        try {
8009            appNotResponding(host, null, null, false, "ContentProvider not responding");
8010        } finally {
8011            Binder.restoreCallingIdentity(token);
8012        }
8013    }
8014
8015    public final void installSystemProviders() {
8016        List<ProviderInfo> providers;
8017        synchronized (this) {
8018            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8019            providers = generateApplicationProvidersLocked(app);
8020            if (providers != null) {
8021                for (int i=providers.size()-1; i>=0; i--) {
8022                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8023                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8024                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8025                                + ": not system .apk");
8026                        providers.remove(i);
8027                    }
8028                }
8029            }
8030        }
8031        if (providers != null) {
8032            mSystemThread.installSystemProviders(providers);
8033        }
8034
8035        mCoreSettingsObserver = new CoreSettingsObserver(this);
8036
8037        mUsageStatsService.monitorPackages();
8038    }
8039
8040    /**
8041     * Allows app to retrieve the MIME type of a URI without having permission
8042     * to access its content provider.
8043     *
8044     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8045     *
8046     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8047     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8048     */
8049    public String getProviderMimeType(Uri uri, int userId) {
8050        enforceNotIsolatedCaller("getProviderMimeType");
8051        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8052                userId, false, true, "getProviderMimeType", null);
8053        final String name = uri.getAuthority();
8054        final long ident = Binder.clearCallingIdentity();
8055        ContentProviderHolder holder = null;
8056
8057        try {
8058            holder = getContentProviderExternalUnchecked(name, null, userId);
8059            if (holder != null) {
8060                return holder.provider.getType(uri);
8061            }
8062        } catch (RemoteException e) {
8063            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8064            return null;
8065        } finally {
8066            if (holder != null) {
8067                removeContentProviderExternalUnchecked(name, null, userId);
8068            }
8069            Binder.restoreCallingIdentity(ident);
8070        }
8071
8072        return null;
8073    }
8074
8075    // =========================================================
8076    // GLOBAL MANAGEMENT
8077    // =========================================================
8078
8079    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8080            boolean isolated) {
8081        String proc = customProcess != null ? customProcess : info.processName;
8082        BatteryStatsImpl.Uid.Proc ps = null;
8083        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8084        int uid = info.uid;
8085        if (isolated) {
8086            int userId = UserHandle.getUserId(uid);
8087            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8088            while (true) {
8089                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8090                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8091                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8092                }
8093                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8094                mNextIsolatedProcessUid++;
8095                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8096                    // No process for this uid, use it.
8097                    break;
8098                }
8099                stepsLeft--;
8100                if (stepsLeft <= 0) {
8101                    return null;
8102                }
8103            }
8104        }
8105        return new ProcessRecord(stats, info, proc, uid);
8106    }
8107
8108    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8109            String abiOverride) {
8110        ProcessRecord app;
8111        if (!isolated) {
8112            app = getProcessRecordLocked(info.processName, info.uid, true);
8113        } else {
8114            app = null;
8115        }
8116
8117        if (app == null) {
8118            app = newProcessRecordLocked(info, null, isolated);
8119            mProcessNames.put(info.processName, app.uid, app);
8120            if (isolated) {
8121                mIsolatedProcesses.put(app.uid, app);
8122            }
8123            updateLruProcessLocked(app, false, null);
8124            updateOomAdjLocked();
8125        }
8126
8127        // This package really, really can not be stopped.
8128        try {
8129            AppGlobals.getPackageManager().setPackageStoppedState(
8130                    info.packageName, false, UserHandle.getUserId(app.uid));
8131        } catch (RemoteException e) {
8132        } catch (IllegalArgumentException e) {
8133            Slog.w(TAG, "Failed trying to unstop package "
8134                    + info.packageName + ": " + e);
8135        }
8136
8137        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8138                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8139            app.persistent = true;
8140            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8141        }
8142        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8143            mPersistentStartingProcesses.add(app);
8144            startProcessLocked(app, "added application", app.processName,
8145                    abiOverride);
8146        }
8147
8148        return app;
8149    }
8150
8151    public void unhandledBack() {
8152        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8153                "unhandledBack()");
8154
8155        synchronized(this) {
8156            final long origId = Binder.clearCallingIdentity();
8157            try {
8158                getFocusedStack().unhandledBackLocked();
8159            } finally {
8160                Binder.restoreCallingIdentity(origId);
8161            }
8162        }
8163    }
8164
8165    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8166        enforceNotIsolatedCaller("openContentUri");
8167        final int userId = UserHandle.getCallingUserId();
8168        String name = uri.getAuthority();
8169        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8170        ParcelFileDescriptor pfd = null;
8171        if (cph != null) {
8172            // We record the binder invoker's uid in thread-local storage before
8173            // going to the content provider to open the file.  Later, in the code
8174            // that handles all permissions checks, we look for this uid and use
8175            // that rather than the Activity Manager's own uid.  The effect is that
8176            // we do the check against the caller's permissions even though it looks
8177            // to the content provider like the Activity Manager itself is making
8178            // the request.
8179            sCallerIdentity.set(new Identity(
8180                    Binder.getCallingPid(), Binder.getCallingUid()));
8181            try {
8182                pfd = cph.provider.openFile(null, uri, "r", null);
8183            } catch (FileNotFoundException e) {
8184                // do nothing; pfd will be returned null
8185            } finally {
8186                // Ensure that whatever happens, we clean up the identity state
8187                sCallerIdentity.remove();
8188            }
8189
8190            // We've got the fd now, so we're done with the provider.
8191            removeContentProviderExternalUnchecked(name, null, userId);
8192        } else {
8193            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8194        }
8195        return pfd;
8196    }
8197
8198    // Actually is sleeping or shutting down or whatever else in the future
8199    // is an inactive state.
8200    public boolean isSleepingOrShuttingDown() {
8201        return mSleeping || mShuttingDown;
8202    }
8203
8204    void goingToSleep() {
8205        synchronized(this) {
8206            mWentToSleep = true;
8207            updateEventDispatchingLocked();
8208
8209            if (!mSleeping) {
8210                mSleeping = true;
8211                mStackSupervisor.goingToSleepLocked();
8212
8213                // Initialize the wake times of all processes.
8214                checkExcessivePowerUsageLocked(false);
8215                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8216                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8217                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8218            }
8219        }
8220    }
8221
8222    @Override
8223    public boolean shutdown(int timeout) {
8224        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8225                != PackageManager.PERMISSION_GRANTED) {
8226            throw new SecurityException("Requires permission "
8227                    + android.Manifest.permission.SHUTDOWN);
8228        }
8229
8230        boolean timedout = false;
8231
8232        synchronized(this) {
8233            mShuttingDown = true;
8234            updateEventDispatchingLocked();
8235            timedout = mStackSupervisor.shutdownLocked(timeout);
8236        }
8237
8238        mAppOpsService.shutdown();
8239        mUsageStatsService.shutdown();
8240        mBatteryStatsService.shutdown();
8241        synchronized (this) {
8242            mProcessStats.shutdownLocked();
8243        }
8244
8245        return timedout;
8246    }
8247
8248    public final void activitySlept(IBinder token) {
8249        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8250
8251        final long origId = Binder.clearCallingIdentity();
8252
8253        synchronized (this) {
8254            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8255            if (r != null) {
8256                mStackSupervisor.activitySleptLocked(r);
8257            }
8258        }
8259
8260        Binder.restoreCallingIdentity(origId);
8261    }
8262
8263    void logLockScreen(String msg) {
8264        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8265                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8266                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8267                mStackSupervisor.mDismissKeyguardOnNextActivity);
8268    }
8269
8270    private void comeOutOfSleepIfNeededLocked() {
8271        if (!mWentToSleep && !mLockScreenShown) {
8272            if (mSleeping) {
8273                mSleeping = false;
8274                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8275            }
8276        }
8277    }
8278
8279    void wakingUp() {
8280        synchronized(this) {
8281            mWentToSleep = false;
8282            updateEventDispatchingLocked();
8283            comeOutOfSleepIfNeededLocked();
8284        }
8285    }
8286
8287    private void updateEventDispatchingLocked() {
8288        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8289    }
8290
8291    public void setLockScreenShown(boolean shown) {
8292        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8293                != PackageManager.PERMISSION_GRANTED) {
8294            throw new SecurityException("Requires permission "
8295                    + android.Manifest.permission.DEVICE_POWER);
8296        }
8297
8298        synchronized(this) {
8299            long ident = Binder.clearCallingIdentity();
8300            try {
8301                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8302                mLockScreenShown = shown;
8303                comeOutOfSleepIfNeededLocked();
8304            } finally {
8305                Binder.restoreCallingIdentity(ident);
8306            }
8307        }
8308    }
8309
8310    public void stopAppSwitches() {
8311        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8312                != PackageManager.PERMISSION_GRANTED) {
8313            throw new SecurityException("Requires permission "
8314                    + android.Manifest.permission.STOP_APP_SWITCHES);
8315        }
8316
8317        synchronized(this) {
8318            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8319                    + APP_SWITCH_DELAY_TIME;
8320            mDidAppSwitch = false;
8321            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8322            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8323            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8324        }
8325    }
8326
8327    public void resumeAppSwitches() {
8328        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8329                != PackageManager.PERMISSION_GRANTED) {
8330            throw new SecurityException("Requires permission "
8331                    + android.Manifest.permission.STOP_APP_SWITCHES);
8332        }
8333
8334        synchronized(this) {
8335            // Note that we don't execute any pending app switches... we will
8336            // let those wait until either the timeout, or the next start
8337            // activity request.
8338            mAppSwitchesAllowedTime = 0;
8339        }
8340    }
8341
8342    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8343            String name) {
8344        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8345            return true;
8346        }
8347
8348        final int perm = checkComponentPermission(
8349                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8350                callingUid, -1, true);
8351        if (perm == PackageManager.PERMISSION_GRANTED) {
8352            return true;
8353        }
8354
8355        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8356        return false;
8357    }
8358
8359    public void setDebugApp(String packageName, boolean waitForDebugger,
8360            boolean persistent) {
8361        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8362                "setDebugApp()");
8363
8364        long ident = Binder.clearCallingIdentity();
8365        try {
8366            // Note that this is not really thread safe if there are multiple
8367            // callers into it at the same time, but that's not a situation we
8368            // care about.
8369            if (persistent) {
8370                final ContentResolver resolver = mContext.getContentResolver();
8371                Settings.Global.putString(
8372                    resolver, Settings.Global.DEBUG_APP,
8373                    packageName);
8374                Settings.Global.putInt(
8375                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8376                    waitForDebugger ? 1 : 0);
8377            }
8378
8379            synchronized (this) {
8380                if (!persistent) {
8381                    mOrigDebugApp = mDebugApp;
8382                    mOrigWaitForDebugger = mWaitForDebugger;
8383                }
8384                mDebugApp = packageName;
8385                mWaitForDebugger = waitForDebugger;
8386                mDebugTransient = !persistent;
8387                if (packageName != null) {
8388                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8389                            UserHandle.USER_ALL, "set debug app");
8390                }
8391            }
8392        } finally {
8393            Binder.restoreCallingIdentity(ident);
8394        }
8395    }
8396
8397    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8398        synchronized (this) {
8399            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8400            if (!isDebuggable) {
8401                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8402                    throw new SecurityException("Process not debuggable: " + app.packageName);
8403                }
8404            }
8405
8406            mOpenGlTraceApp = processName;
8407        }
8408    }
8409
8410    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8411            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8412        synchronized (this) {
8413            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8414            if (!isDebuggable) {
8415                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8416                    throw new SecurityException("Process not debuggable: " + app.packageName);
8417                }
8418            }
8419            mProfileApp = processName;
8420            mProfileFile = profileFile;
8421            if (mProfileFd != null) {
8422                try {
8423                    mProfileFd.close();
8424                } catch (IOException e) {
8425                }
8426                mProfileFd = null;
8427            }
8428            mProfileFd = profileFd;
8429            mProfileType = 0;
8430            mAutoStopProfiler = autoStopProfiler;
8431        }
8432    }
8433
8434    @Override
8435    public void setAlwaysFinish(boolean enabled) {
8436        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8437                "setAlwaysFinish()");
8438
8439        Settings.Global.putInt(
8440                mContext.getContentResolver(),
8441                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8442
8443        synchronized (this) {
8444            mAlwaysFinishActivities = enabled;
8445        }
8446    }
8447
8448    @Override
8449    public void setActivityController(IActivityController controller) {
8450        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8451                "setActivityController()");
8452        synchronized (this) {
8453            mController = controller;
8454            Watchdog.getInstance().setActivityController(controller);
8455        }
8456    }
8457
8458    @Override
8459    public void setUserIsMonkey(boolean userIsMonkey) {
8460        synchronized (this) {
8461            synchronized (mPidsSelfLocked) {
8462                final int callingPid = Binder.getCallingPid();
8463                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8464                if (precessRecord == null) {
8465                    throw new SecurityException("Unknown process: " + callingPid);
8466                }
8467                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8468                    throw new SecurityException("Only an instrumentation process "
8469                            + "with a UiAutomation can call setUserIsMonkey");
8470                }
8471            }
8472            mUserIsMonkey = userIsMonkey;
8473        }
8474    }
8475
8476    @Override
8477    public boolean isUserAMonkey() {
8478        synchronized (this) {
8479            // If there is a controller also implies the user is a monkey.
8480            return (mUserIsMonkey || mController != null);
8481        }
8482    }
8483
8484    public void requestBugReport() {
8485        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8486        SystemProperties.set("ctl.start", "bugreport");
8487    }
8488
8489    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8490        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8491    }
8492
8493    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8494        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8495            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8496        }
8497        return KEY_DISPATCHING_TIMEOUT;
8498    }
8499
8500    @Override
8501    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8502        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8503                != PackageManager.PERMISSION_GRANTED) {
8504            throw new SecurityException("Requires permission "
8505                    + android.Manifest.permission.FILTER_EVENTS);
8506        }
8507        ProcessRecord proc;
8508        long timeout;
8509        synchronized (this) {
8510            synchronized (mPidsSelfLocked) {
8511                proc = mPidsSelfLocked.get(pid);
8512            }
8513            timeout = getInputDispatchingTimeoutLocked(proc);
8514        }
8515
8516        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8517            return -1;
8518        }
8519
8520        return timeout;
8521    }
8522
8523    /**
8524     * Handle input dispatching timeouts.
8525     * Returns whether input dispatching should be aborted or not.
8526     */
8527    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8528            final ActivityRecord activity, final ActivityRecord parent,
8529            final boolean aboveSystem, String reason) {
8530        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8531                != PackageManager.PERMISSION_GRANTED) {
8532            throw new SecurityException("Requires permission "
8533                    + android.Manifest.permission.FILTER_EVENTS);
8534        }
8535
8536        final String annotation;
8537        if (reason == null) {
8538            annotation = "Input dispatching timed out";
8539        } else {
8540            annotation = "Input dispatching timed out (" + reason + ")";
8541        }
8542
8543        if (proc != null) {
8544            synchronized (this) {
8545                if (proc.debugging) {
8546                    return false;
8547                }
8548
8549                if (mDidDexOpt) {
8550                    // Give more time since we were dexopting.
8551                    mDidDexOpt = false;
8552                    return false;
8553                }
8554
8555                if (proc.instrumentationClass != null) {
8556                    Bundle info = new Bundle();
8557                    info.putString("shortMsg", "keyDispatchingTimedOut");
8558                    info.putString("longMsg", annotation);
8559                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8560                    return true;
8561                }
8562            }
8563            mHandler.post(new Runnable() {
8564                @Override
8565                public void run() {
8566                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8567                }
8568            });
8569        }
8570
8571        return true;
8572    }
8573
8574    public Bundle getAssistContextExtras(int requestType) {
8575        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8576                "getAssistContextExtras()");
8577        PendingAssistExtras pae;
8578        Bundle extras = new Bundle();
8579        synchronized (this) {
8580            ActivityRecord activity = getFocusedStack().mResumedActivity;
8581            if (activity == null) {
8582                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8583                return null;
8584            }
8585            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8586            if (activity.app == null || activity.app.thread == null) {
8587                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8588                return extras;
8589            }
8590            if (activity.app.pid == Binder.getCallingPid()) {
8591                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8592                return extras;
8593            }
8594            pae = new PendingAssistExtras(activity);
8595            try {
8596                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8597                        requestType);
8598                mPendingAssistExtras.add(pae);
8599                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8600            } catch (RemoteException e) {
8601                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8602                return extras;
8603            }
8604        }
8605        synchronized (pae) {
8606            while (!pae.haveResult) {
8607                try {
8608                    pae.wait();
8609                } catch (InterruptedException e) {
8610                }
8611            }
8612            if (pae.result != null) {
8613                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8614            }
8615        }
8616        synchronized (this) {
8617            mPendingAssistExtras.remove(pae);
8618            mHandler.removeCallbacks(pae);
8619        }
8620        return extras;
8621    }
8622
8623    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8624        PendingAssistExtras pae = (PendingAssistExtras)token;
8625        synchronized (pae) {
8626            pae.result = extras;
8627            pae.haveResult = true;
8628            pae.notifyAll();
8629        }
8630    }
8631
8632    public void registerProcessObserver(IProcessObserver observer) {
8633        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8634                "registerProcessObserver()");
8635        synchronized (this) {
8636            mProcessObservers.register(observer);
8637        }
8638    }
8639
8640    @Override
8641    public void unregisterProcessObserver(IProcessObserver observer) {
8642        synchronized (this) {
8643            mProcessObservers.unregister(observer);
8644        }
8645    }
8646
8647    @Override
8648    public boolean convertFromTranslucent(IBinder token) {
8649        final long origId = Binder.clearCallingIdentity();
8650        try {
8651            synchronized (this) {
8652                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8653                if (r == null) {
8654                    return false;
8655                }
8656                if (r.changeWindowTranslucency(true)) {
8657                    mWindowManager.setAppFullscreen(token, true);
8658                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8659                    return true;
8660                }
8661                return false;
8662            }
8663        } finally {
8664            Binder.restoreCallingIdentity(origId);
8665        }
8666    }
8667
8668    @Override
8669    public boolean convertToTranslucent(IBinder token) {
8670        final long origId = Binder.clearCallingIdentity();
8671        try {
8672            synchronized (this) {
8673                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8674                if (r == null) {
8675                    return false;
8676                }
8677                if (r.changeWindowTranslucency(false)) {
8678                    r.task.stack.convertToTranslucent(r);
8679                    mWindowManager.setAppFullscreen(token, false);
8680                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8681                    return true;
8682                }
8683                return false;
8684            }
8685        } finally {
8686            Binder.restoreCallingIdentity(origId);
8687        }
8688    }
8689
8690    @Override
8691    public void setImmersive(IBinder token, boolean immersive) {
8692        synchronized(this) {
8693            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8694            if (r == null) {
8695                throw new IllegalArgumentException();
8696            }
8697            r.immersive = immersive;
8698
8699            // update associated state if we're frontmost
8700            if (r == mFocusedActivity) {
8701                if (DEBUG_IMMERSIVE) {
8702                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8703                }
8704                applyUpdateLockStateLocked(r);
8705            }
8706        }
8707    }
8708
8709    @Override
8710    public boolean isImmersive(IBinder token) {
8711        synchronized (this) {
8712            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8713            if (r == null) {
8714                throw new IllegalArgumentException();
8715            }
8716            return r.immersive;
8717        }
8718    }
8719
8720    public boolean isTopActivityImmersive() {
8721        enforceNotIsolatedCaller("startActivity");
8722        synchronized (this) {
8723            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8724            return (r != null) ? r.immersive : false;
8725        }
8726    }
8727
8728    public final void enterSafeMode() {
8729        synchronized(this) {
8730            // It only makes sense to do this before the system is ready
8731            // and started launching other packages.
8732            if (!mSystemReady) {
8733                try {
8734                    AppGlobals.getPackageManager().enterSafeMode();
8735                } catch (RemoteException e) {
8736                }
8737            }
8738
8739            mSafeMode = true;
8740        }
8741    }
8742
8743    public final void showSafeModeOverlay() {
8744        View v = LayoutInflater.from(mContext).inflate(
8745                com.android.internal.R.layout.safe_mode, null);
8746        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8747        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8748        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8749        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8750        lp.gravity = Gravity.BOTTOM | Gravity.START;
8751        lp.format = v.getBackground().getOpacity();
8752        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8753                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8754        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8755        ((WindowManager)mContext.getSystemService(
8756                Context.WINDOW_SERVICE)).addView(v, lp);
8757    }
8758
8759    public void noteWakeupAlarm(IIntentSender sender) {
8760        if (!(sender instanceof PendingIntentRecord)) {
8761            return;
8762        }
8763        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8764        synchronized (stats) {
8765            if (mBatteryStatsService.isOnBattery()) {
8766                mBatteryStatsService.enforceCallingPermission();
8767                PendingIntentRecord rec = (PendingIntentRecord)sender;
8768                int MY_UID = Binder.getCallingUid();
8769                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8770                BatteryStatsImpl.Uid.Pkg pkg =
8771                    stats.getPackageStatsLocked(uid, rec.key.packageName);
8772                pkg.incWakeupsLocked();
8773            }
8774        }
8775    }
8776
8777    public boolean killPids(int[] pids, String pReason, boolean secure) {
8778        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8779            throw new SecurityException("killPids only available to the system");
8780        }
8781        String reason = (pReason == null) ? "Unknown" : pReason;
8782        // XXX Note: don't acquire main activity lock here, because the window
8783        // manager calls in with its locks held.
8784
8785        boolean killed = false;
8786        synchronized (mPidsSelfLocked) {
8787            int[] types = new int[pids.length];
8788            int worstType = 0;
8789            for (int i=0; i<pids.length; i++) {
8790                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8791                if (proc != null) {
8792                    int type = proc.setAdj;
8793                    types[i] = type;
8794                    if (type > worstType) {
8795                        worstType = type;
8796                    }
8797                }
8798            }
8799
8800            // If the worst oom_adj is somewhere in the cached proc LRU range,
8801            // then constrain it so we will kill all cached procs.
8802            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8803                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8804                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8805            }
8806
8807            // If this is not a secure call, don't let it kill processes that
8808            // are important.
8809            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8810                worstType = ProcessList.SERVICE_ADJ;
8811            }
8812
8813            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8814            for (int i=0; i<pids.length; i++) {
8815                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8816                if (proc == null) {
8817                    continue;
8818                }
8819                int adj = proc.setAdj;
8820                if (adj >= worstType && !proc.killedByAm) {
8821                    killUnneededProcessLocked(proc, reason);
8822                    killed = true;
8823                }
8824            }
8825        }
8826        return killed;
8827    }
8828
8829    @Override
8830    public void killUid(int uid, String reason) {
8831        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8832            throw new SecurityException("killUid only available to the system");
8833        }
8834        synchronized (this) {
8835            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8836                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8837                    reason != null ? reason : "kill uid");
8838        }
8839    }
8840
8841    @Override
8842    public boolean killProcessesBelowForeground(String reason) {
8843        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8844            throw new SecurityException("killProcessesBelowForeground() only available to system");
8845        }
8846
8847        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8848    }
8849
8850    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8851        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8852            throw new SecurityException("killProcessesBelowAdj() only available to system");
8853        }
8854
8855        boolean killed = false;
8856        synchronized (mPidsSelfLocked) {
8857            final int size = mPidsSelfLocked.size();
8858            for (int i = 0; i < size; i++) {
8859                final int pid = mPidsSelfLocked.keyAt(i);
8860                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8861                if (proc == null) continue;
8862
8863                final int adj = proc.setAdj;
8864                if (adj > belowAdj && !proc.killedByAm) {
8865                    killUnneededProcessLocked(proc, reason);
8866                    killed = true;
8867                }
8868            }
8869        }
8870        return killed;
8871    }
8872
8873    @Override
8874    public void hang(final IBinder who, boolean allowRestart) {
8875        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8876                != PackageManager.PERMISSION_GRANTED) {
8877            throw new SecurityException("Requires permission "
8878                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8879        }
8880
8881        final IBinder.DeathRecipient death = new DeathRecipient() {
8882            @Override
8883            public void binderDied() {
8884                synchronized (this) {
8885                    notifyAll();
8886                }
8887            }
8888        };
8889
8890        try {
8891            who.linkToDeath(death, 0);
8892        } catch (RemoteException e) {
8893            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8894            return;
8895        }
8896
8897        synchronized (this) {
8898            Watchdog.getInstance().setAllowRestart(allowRestart);
8899            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8900            synchronized (death) {
8901                while (who.isBinderAlive()) {
8902                    try {
8903                        death.wait();
8904                    } catch (InterruptedException e) {
8905                    }
8906                }
8907            }
8908            Watchdog.getInstance().setAllowRestart(true);
8909        }
8910    }
8911
8912    @Override
8913    public void restart() {
8914        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8915                != PackageManager.PERMISSION_GRANTED) {
8916            throw new SecurityException("Requires permission "
8917                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8918        }
8919
8920        Log.i(TAG, "Sending shutdown broadcast...");
8921
8922        BroadcastReceiver br = new BroadcastReceiver() {
8923            @Override public void onReceive(Context context, Intent intent) {
8924                // Now the broadcast is done, finish up the low-level shutdown.
8925                Log.i(TAG, "Shutting down activity manager...");
8926                shutdown(10000);
8927                Log.i(TAG, "Shutdown complete, restarting!");
8928                Process.killProcess(Process.myPid());
8929                System.exit(10);
8930            }
8931        };
8932
8933        // First send the high-level shut down broadcast.
8934        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8935        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8936        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8937        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8938        mContext.sendOrderedBroadcastAsUser(intent,
8939                UserHandle.ALL, null, br, mHandler, 0, null, null);
8940        */
8941        br.onReceive(mContext, intent);
8942    }
8943
8944    private long getLowRamTimeSinceIdle(long now) {
8945        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8946    }
8947
8948    @Override
8949    public void performIdleMaintenance() {
8950        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8951                != PackageManager.PERMISSION_GRANTED) {
8952            throw new SecurityException("Requires permission "
8953                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8954        }
8955
8956        synchronized (this) {
8957            final long now = SystemClock.uptimeMillis();
8958            final long timeSinceLastIdle = now - mLastIdleTime;
8959            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
8960            mLastIdleTime = now;
8961            mLowRamTimeSinceLastIdle = 0;
8962            if (mLowRamStartTime != 0) {
8963                mLowRamStartTime = now;
8964            }
8965
8966            StringBuilder sb = new StringBuilder(128);
8967            sb.append("Idle maintenance over ");
8968            TimeUtils.formatDuration(timeSinceLastIdle, sb);
8969            sb.append(" low RAM for ");
8970            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
8971            Slog.i(TAG, sb.toString());
8972
8973            // If at least 1/3 of our time since the last idle period has been spent
8974            // with RAM low, then we want to kill processes.
8975            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
8976
8977            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
8978                ProcessRecord proc = mLruProcesses.get(i);
8979                if (proc.notCachedSinceIdle) {
8980                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
8981                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
8982                        if (doKilling && proc.initialIdlePss != 0
8983                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
8984                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
8985                                    + " from " + proc.initialIdlePss + ")");
8986                        }
8987                    }
8988                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
8989                    proc.notCachedSinceIdle = true;
8990                    proc.initialIdlePss = 0;
8991                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
8992                            mSleeping, now);
8993                }
8994            }
8995
8996            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
8997            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
8998        }
8999    }
9000
9001    private void retrieveSettings() {
9002        final ContentResolver resolver = mContext.getContentResolver();
9003        String debugApp = Settings.Global.getString(
9004            resolver, Settings.Global.DEBUG_APP);
9005        boolean waitForDebugger = Settings.Global.getInt(
9006            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9007        boolean alwaysFinishActivities = Settings.Global.getInt(
9008            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9009        boolean forceRtl = Settings.Global.getInt(
9010                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9011        // Transfer any global setting for forcing RTL layout, into a System Property
9012        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9013
9014        Configuration configuration = new Configuration();
9015        Settings.System.getConfiguration(resolver, configuration);
9016        if (forceRtl) {
9017            // This will take care of setting the correct layout direction flags
9018            configuration.setLayoutDirection(configuration.locale);
9019        }
9020
9021        synchronized (this) {
9022            mDebugApp = mOrigDebugApp = debugApp;
9023            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9024            mAlwaysFinishActivities = alwaysFinishActivities;
9025            // This happens before any activities are started, so we can
9026            // change mConfiguration in-place.
9027            updateConfigurationLocked(configuration, null, false, true);
9028            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9029        }
9030    }
9031
9032    public boolean testIsSystemReady() {
9033        // no need to synchronize(this) just to read & return the value
9034        return mSystemReady;
9035    }
9036
9037    private static File getCalledPreBootReceiversFile() {
9038        File dataDir = Environment.getDataDirectory();
9039        File systemDir = new File(dataDir, "system");
9040        File fname = new File(systemDir, "called_pre_boots.dat");
9041        return fname;
9042    }
9043
9044    static final int LAST_DONE_VERSION = 10000;
9045
9046    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9047        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9048        File file = getCalledPreBootReceiversFile();
9049        FileInputStream fis = null;
9050        try {
9051            fis = new FileInputStream(file);
9052            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9053            int fvers = dis.readInt();
9054            if (fvers == LAST_DONE_VERSION) {
9055                String vers = dis.readUTF();
9056                String codename = dis.readUTF();
9057                String build = dis.readUTF();
9058                if (android.os.Build.VERSION.RELEASE.equals(vers)
9059                        && android.os.Build.VERSION.CODENAME.equals(codename)
9060                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9061                    int num = dis.readInt();
9062                    while (num > 0) {
9063                        num--;
9064                        String pkg = dis.readUTF();
9065                        String cls = dis.readUTF();
9066                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9067                    }
9068                }
9069            }
9070        } catch (FileNotFoundException e) {
9071        } catch (IOException e) {
9072            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9073        } finally {
9074            if (fis != null) {
9075                try {
9076                    fis.close();
9077                } catch (IOException e) {
9078                }
9079            }
9080        }
9081        return lastDoneReceivers;
9082    }
9083
9084    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9085        File file = getCalledPreBootReceiversFile();
9086        FileOutputStream fos = null;
9087        DataOutputStream dos = null;
9088        try {
9089            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9090            fos = new FileOutputStream(file);
9091            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9092            dos.writeInt(LAST_DONE_VERSION);
9093            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9094            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9095            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9096            dos.writeInt(list.size());
9097            for (int i=0; i<list.size(); i++) {
9098                dos.writeUTF(list.get(i).getPackageName());
9099                dos.writeUTF(list.get(i).getClassName());
9100            }
9101        } catch (IOException e) {
9102            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9103            file.delete();
9104        } finally {
9105            FileUtils.sync(fos);
9106            if (dos != null) {
9107                try {
9108                    dos.close();
9109                } catch (IOException e) {
9110                    // TODO Auto-generated catch block
9111                    e.printStackTrace();
9112                }
9113            }
9114        }
9115    }
9116
9117    public void systemReady(final Runnable goingCallback) {
9118        synchronized(this) {
9119            if (mSystemReady) {
9120                if (goingCallback != null) goingCallback.run();
9121                return;
9122            }
9123
9124            // Check to see if there are any update receivers to run.
9125            if (!mDidUpdate) {
9126                if (mWaitingUpdate) {
9127                    return;
9128                }
9129                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9130                List<ResolveInfo> ris = null;
9131                try {
9132                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9133                            intent, null, 0, 0);
9134                } catch (RemoteException e) {
9135                }
9136                if (ris != null) {
9137                    for (int i=ris.size()-1; i>=0; i--) {
9138                        if ((ris.get(i).activityInfo.applicationInfo.flags
9139                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9140                            ris.remove(i);
9141                        }
9142                    }
9143                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9144
9145                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9146
9147                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9148                    for (int i=0; i<ris.size(); i++) {
9149                        ActivityInfo ai = ris.get(i).activityInfo;
9150                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9151                        if (lastDoneReceivers.contains(comp)) {
9152                            // We already did the pre boot receiver for this app with the current
9153                            // platform version, so don't do it again...
9154                            ris.remove(i);
9155                            i--;
9156                            // ...however, do keep it as one that has been done, so we don't
9157                            // forget about it when rewriting the file of last done receivers.
9158                            doneReceivers.add(comp);
9159                        }
9160                    }
9161
9162                    final int[] users = getUsersLocked();
9163                    for (int i=0; i<ris.size(); i++) {
9164                        ActivityInfo ai = ris.get(i).activityInfo;
9165                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9166                        doneReceivers.add(comp);
9167                        intent.setComponent(comp);
9168                        for (int j=0; j<users.length; j++) {
9169                            IIntentReceiver finisher = null;
9170                            if (i == ris.size()-1 && j == users.length-1) {
9171                                finisher = new IIntentReceiver.Stub() {
9172                                    public void performReceive(Intent intent, int resultCode,
9173                                            String data, Bundle extras, boolean ordered,
9174                                            boolean sticky, int sendingUser) {
9175                                        // The raw IIntentReceiver interface is called
9176                                        // with the AM lock held, so redispatch to
9177                                        // execute our code without the lock.
9178                                        mHandler.post(new Runnable() {
9179                                            public void run() {
9180                                                synchronized (ActivityManagerService.this) {
9181                                                    mDidUpdate = true;
9182                                                }
9183                                                writeLastDonePreBootReceivers(doneReceivers);
9184                                                showBootMessage(mContext.getText(
9185                                                        R.string.android_upgrading_complete),
9186                                                        false);
9187                                                systemReady(goingCallback);
9188                                            }
9189                                        });
9190                                    }
9191                                };
9192                            }
9193                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9194                                    + " for user " + users[j]);
9195                            broadcastIntentLocked(null, null, intent, null, finisher,
9196                                    0, null, null, null, AppOpsManager.OP_NONE,
9197                                    true, false, MY_PID, Process.SYSTEM_UID,
9198                                    users[j]);
9199                            if (finisher != null) {
9200                                mWaitingUpdate = true;
9201                            }
9202                        }
9203                    }
9204                }
9205                if (mWaitingUpdate) {
9206                    return;
9207                }
9208                mDidUpdate = true;
9209            }
9210
9211            mAppOpsService.systemReady();
9212            mSystemReady = true;
9213        }
9214
9215        ArrayList<ProcessRecord> procsToKill = null;
9216        synchronized(mPidsSelfLocked) {
9217            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9218                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9219                if (!isAllowedWhileBooting(proc.info)){
9220                    if (procsToKill == null) {
9221                        procsToKill = new ArrayList<ProcessRecord>();
9222                    }
9223                    procsToKill.add(proc);
9224                }
9225            }
9226        }
9227
9228        synchronized(this) {
9229            if (procsToKill != null) {
9230                for (int i=procsToKill.size()-1; i>=0; i--) {
9231                    ProcessRecord proc = procsToKill.get(i);
9232                    Slog.i(TAG, "Removing system update proc: " + proc);
9233                    removeProcessLocked(proc, true, false, "system update done");
9234                }
9235            }
9236
9237            // Now that we have cleaned up any update processes, we
9238            // are ready to start launching real processes and know that
9239            // we won't trample on them any more.
9240            mProcessesReady = true;
9241        }
9242
9243        Slog.i(TAG, "System now ready");
9244        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9245            SystemClock.uptimeMillis());
9246
9247        synchronized(this) {
9248            // Make sure we have no pre-ready processes sitting around.
9249
9250            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9251                ResolveInfo ri = mContext.getPackageManager()
9252                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9253                                STOCK_PM_FLAGS);
9254                CharSequence errorMsg = null;
9255                if (ri != null) {
9256                    ActivityInfo ai = ri.activityInfo;
9257                    ApplicationInfo app = ai.applicationInfo;
9258                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9259                        mTopAction = Intent.ACTION_FACTORY_TEST;
9260                        mTopData = null;
9261                        mTopComponent = new ComponentName(app.packageName,
9262                                ai.name);
9263                    } else {
9264                        errorMsg = mContext.getResources().getText(
9265                                com.android.internal.R.string.factorytest_not_system);
9266                    }
9267                } else {
9268                    errorMsg = mContext.getResources().getText(
9269                            com.android.internal.R.string.factorytest_no_action);
9270                }
9271                if (errorMsg != null) {
9272                    mTopAction = null;
9273                    mTopData = null;
9274                    mTopComponent = null;
9275                    Message msg = Message.obtain();
9276                    msg.what = SHOW_FACTORY_ERROR_MSG;
9277                    msg.getData().putCharSequence("msg", errorMsg);
9278                    mHandler.sendMessage(msg);
9279                }
9280            }
9281        }
9282
9283        retrieveSettings();
9284
9285        synchronized (this) {
9286            readGrantedUriPermissionsLocked();
9287        }
9288
9289        if (goingCallback != null) goingCallback.run();
9290
9291        synchronized (this) {
9292            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9293                try {
9294                    List apps = AppGlobals.getPackageManager().
9295                        getPersistentApplications(STOCK_PM_FLAGS);
9296                    if (apps != null) {
9297                        int N = apps.size();
9298                        int i;
9299                        for (i=0; i<N; i++) {
9300                            ApplicationInfo info
9301                                = (ApplicationInfo)apps.get(i);
9302                            if (info != null &&
9303                                    !info.packageName.equals("android")) {
9304                                addAppLocked(info, false, null /* ABI override */);
9305                            }
9306                        }
9307                    }
9308                } catch (RemoteException ex) {
9309                    // pm is in same process, this will never happen.
9310                }
9311            }
9312
9313            // Start up initial activity.
9314            mBooting = true;
9315
9316            try {
9317                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9318                    Message msg = Message.obtain();
9319                    msg.what = SHOW_UID_ERROR_MSG;
9320                    mHandler.sendMessage(msg);
9321                }
9322            } catch (RemoteException e) {
9323            }
9324
9325            long ident = Binder.clearCallingIdentity();
9326            try {
9327                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9328                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9329                        | Intent.FLAG_RECEIVER_FOREGROUND);
9330                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9331                broadcastIntentLocked(null, null, intent,
9332                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9333                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9334                intent = new Intent(Intent.ACTION_USER_STARTING);
9335                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9336                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9337                broadcastIntentLocked(null, null, intent,
9338                        null, new IIntentReceiver.Stub() {
9339                            @Override
9340                            public void performReceive(Intent intent, int resultCode, String data,
9341                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9342                                    throws RemoteException {
9343                            }
9344                        }, 0, null, null,
9345                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9346                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9347            } finally {
9348                Binder.restoreCallingIdentity(ident);
9349            }
9350            mStackSupervisor.resumeTopActivitiesLocked();
9351            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9352        }
9353    }
9354
9355    private boolean makeAppCrashingLocked(ProcessRecord app,
9356            String shortMsg, String longMsg, String stackTrace) {
9357        app.crashing = true;
9358        app.crashingReport = generateProcessError(app,
9359                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9360        startAppProblemLocked(app);
9361        app.stopFreezingAllLocked();
9362        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9363    }
9364
9365    private void makeAppNotRespondingLocked(ProcessRecord app,
9366            String activity, String shortMsg, String longMsg) {
9367        app.notResponding = true;
9368        app.notRespondingReport = generateProcessError(app,
9369                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9370                activity, shortMsg, longMsg, null);
9371        startAppProblemLocked(app);
9372        app.stopFreezingAllLocked();
9373    }
9374
9375    /**
9376     * Generate a process error record, suitable for attachment to a ProcessRecord.
9377     *
9378     * @param app The ProcessRecord in which the error occurred.
9379     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9380     *                      ActivityManager.AppErrorStateInfo
9381     * @param activity The activity associated with the crash, if known.
9382     * @param shortMsg Short message describing the crash.
9383     * @param longMsg Long message describing the crash.
9384     * @param stackTrace Full crash stack trace, may be null.
9385     *
9386     * @return Returns a fully-formed AppErrorStateInfo record.
9387     */
9388    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9389            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9390        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9391
9392        report.condition = condition;
9393        report.processName = app.processName;
9394        report.pid = app.pid;
9395        report.uid = app.info.uid;
9396        report.tag = activity;
9397        report.shortMsg = shortMsg;
9398        report.longMsg = longMsg;
9399        report.stackTrace = stackTrace;
9400
9401        return report;
9402    }
9403
9404    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9405        synchronized (this) {
9406            app.crashing = false;
9407            app.crashingReport = null;
9408            app.notResponding = false;
9409            app.notRespondingReport = null;
9410            if (app.anrDialog == fromDialog) {
9411                app.anrDialog = null;
9412            }
9413            if (app.waitDialog == fromDialog) {
9414                app.waitDialog = null;
9415            }
9416            if (app.pid > 0 && app.pid != MY_PID) {
9417                handleAppCrashLocked(app, null, null, null);
9418                killUnneededProcessLocked(app, "user request after error");
9419            }
9420        }
9421    }
9422
9423    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9424            String stackTrace) {
9425        long now = SystemClock.uptimeMillis();
9426
9427        Long crashTime;
9428        if (!app.isolated) {
9429            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9430        } else {
9431            crashTime = null;
9432        }
9433        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9434            // This process loses!
9435            Slog.w(TAG, "Process " + app.info.processName
9436                    + " has crashed too many times: killing!");
9437            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9438                    app.userId, app.info.processName, app.uid);
9439            mStackSupervisor.handleAppCrashLocked(app);
9440            if (!app.persistent) {
9441                // We don't want to start this process again until the user
9442                // explicitly does so...  but for persistent process, we really
9443                // need to keep it running.  If a persistent process is actually
9444                // repeatedly crashing, then badness for everyone.
9445                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9446                        app.info.processName);
9447                if (!app.isolated) {
9448                    // XXX We don't have a way to mark isolated processes
9449                    // as bad, since they don't have a peristent identity.
9450                    mBadProcesses.put(app.info.processName, app.uid,
9451                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9452                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9453                }
9454                app.bad = true;
9455                app.removed = true;
9456                // Don't let services in this process be restarted and potentially
9457                // annoy the user repeatedly.  Unless it is persistent, since those
9458                // processes run critical code.
9459                removeProcessLocked(app, false, false, "crash");
9460                mStackSupervisor.resumeTopActivitiesLocked();
9461                return false;
9462            }
9463            mStackSupervisor.resumeTopActivitiesLocked();
9464        } else {
9465            mStackSupervisor.finishTopRunningActivityLocked(app);
9466        }
9467
9468        // Bump up the crash count of any services currently running in the proc.
9469        for (int i=app.services.size()-1; i>=0; i--) {
9470            // Any services running in the application need to be placed
9471            // back in the pending list.
9472            ServiceRecord sr = app.services.valueAt(i);
9473            sr.crashCount++;
9474        }
9475
9476        // If the crashing process is what we consider to be the "home process" and it has been
9477        // replaced by a third-party app, clear the package preferred activities from packages
9478        // with a home activity running in the process to prevent a repeatedly crashing app
9479        // from blocking the user to manually clear the list.
9480        final ArrayList<ActivityRecord> activities = app.activities;
9481        if (app == mHomeProcess && activities.size() > 0
9482                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9483            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9484                final ActivityRecord r = activities.get(activityNdx);
9485                if (r.isHomeActivity()) {
9486                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9487                    try {
9488                        ActivityThread.getPackageManager()
9489                                .clearPackagePreferredActivities(r.packageName);
9490                    } catch (RemoteException c) {
9491                        // pm is in same process, this will never happen.
9492                    }
9493                }
9494            }
9495        }
9496
9497        if (!app.isolated) {
9498            // XXX Can't keep track of crash times for isolated processes,
9499            // because they don't have a perisistent identity.
9500            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9501        }
9502
9503        return true;
9504    }
9505
9506    void startAppProblemLocked(ProcessRecord app) {
9507        if (app.userId == mCurrentUserId) {
9508            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9509                    mContext, app.info.packageName, app.info.flags);
9510        } else {
9511            // If this app is not running under the current user, then we
9512            // can't give it a report button because that would require
9513            // launching the report UI under a different user.
9514            app.errorReportReceiver = null;
9515        }
9516        skipCurrentReceiverLocked(app);
9517    }
9518
9519    void skipCurrentReceiverLocked(ProcessRecord app) {
9520        for (BroadcastQueue queue : mBroadcastQueues) {
9521            queue.skipCurrentReceiverLocked(app);
9522        }
9523    }
9524
9525    /**
9526     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9527     * The application process will exit immediately after this call returns.
9528     * @param app object of the crashing app, null for the system server
9529     * @param crashInfo describing the exception
9530     */
9531    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9532        ProcessRecord r = findAppProcess(app, "Crash");
9533        final String processName = app == null ? "system_server"
9534                : (r == null ? "unknown" : r.processName);
9535
9536        handleApplicationCrashInner("crash", r, processName, crashInfo);
9537    }
9538
9539    /* Native crash reporting uses this inner version because it needs to be somewhat
9540     * decoupled from the AM-managed cleanup lifecycle
9541     */
9542    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9543            ApplicationErrorReport.CrashInfo crashInfo) {
9544        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9545                UserHandle.getUserId(Binder.getCallingUid()), processName,
9546                r == null ? -1 : r.info.flags,
9547                crashInfo.exceptionClassName,
9548                crashInfo.exceptionMessage,
9549                crashInfo.throwFileName,
9550                crashInfo.throwLineNumber);
9551
9552        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9553
9554        crashApplication(r, crashInfo);
9555    }
9556
9557    public void handleApplicationStrictModeViolation(
9558            IBinder app,
9559            int violationMask,
9560            StrictMode.ViolationInfo info) {
9561        ProcessRecord r = findAppProcess(app, "StrictMode");
9562        if (r == null) {
9563            return;
9564        }
9565
9566        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9567            Integer stackFingerprint = info.hashCode();
9568            boolean logIt = true;
9569            synchronized (mAlreadyLoggedViolatedStacks) {
9570                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9571                    logIt = false;
9572                    // TODO: sub-sample into EventLog for these, with
9573                    // the info.durationMillis?  Then we'd get
9574                    // the relative pain numbers, without logging all
9575                    // the stack traces repeatedly.  We'd want to do
9576                    // likewise in the client code, which also does
9577                    // dup suppression, before the Binder call.
9578                } else {
9579                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9580                        mAlreadyLoggedViolatedStacks.clear();
9581                    }
9582                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9583                }
9584            }
9585            if (logIt) {
9586                logStrictModeViolationToDropBox(r, info);
9587            }
9588        }
9589
9590        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9591            AppErrorResult result = new AppErrorResult();
9592            synchronized (this) {
9593                final long origId = Binder.clearCallingIdentity();
9594
9595                Message msg = Message.obtain();
9596                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9597                HashMap<String, Object> data = new HashMap<String, Object>();
9598                data.put("result", result);
9599                data.put("app", r);
9600                data.put("violationMask", violationMask);
9601                data.put("info", info);
9602                msg.obj = data;
9603                mHandler.sendMessage(msg);
9604
9605                Binder.restoreCallingIdentity(origId);
9606            }
9607            int res = result.get();
9608            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9609        }
9610    }
9611
9612    // Depending on the policy in effect, there could be a bunch of
9613    // these in quick succession so we try to batch these together to
9614    // minimize disk writes, number of dropbox entries, and maximize
9615    // compression, by having more fewer, larger records.
9616    private void logStrictModeViolationToDropBox(
9617            ProcessRecord process,
9618            StrictMode.ViolationInfo info) {
9619        if (info == null) {
9620            return;
9621        }
9622        final boolean isSystemApp = process == null ||
9623                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9624                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9625        final String processName = process == null ? "unknown" : process.processName;
9626        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9627        final DropBoxManager dbox = (DropBoxManager)
9628                mContext.getSystemService(Context.DROPBOX_SERVICE);
9629
9630        // Exit early if the dropbox isn't configured to accept this report type.
9631        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9632
9633        boolean bufferWasEmpty;
9634        boolean needsFlush;
9635        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9636        synchronized (sb) {
9637            bufferWasEmpty = sb.length() == 0;
9638            appendDropBoxProcessHeaders(process, processName, sb);
9639            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9640            sb.append("System-App: ").append(isSystemApp).append("\n");
9641            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9642            if (info.violationNumThisLoop != 0) {
9643                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9644            }
9645            if (info.numAnimationsRunning != 0) {
9646                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9647            }
9648            if (info.broadcastIntentAction != null) {
9649                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9650            }
9651            if (info.durationMillis != -1) {
9652                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9653            }
9654            if (info.numInstances != -1) {
9655                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9656            }
9657            if (info.tags != null) {
9658                for (String tag : info.tags) {
9659                    sb.append("Span-Tag: ").append(tag).append("\n");
9660                }
9661            }
9662            sb.append("\n");
9663            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9664                sb.append(info.crashInfo.stackTrace);
9665            }
9666            sb.append("\n");
9667
9668            // Only buffer up to ~64k.  Various logging bits truncate
9669            // things at 128k.
9670            needsFlush = (sb.length() > 64 * 1024);
9671        }
9672
9673        // Flush immediately if the buffer's grown too large, or this
9674        // is a non-system app.  Non-system apps are isolated with a
9675        // different tag & policy and not batched.
9676        //
9677        // Batching is useful during internal testing with
9678        // StrictMode settings turned up high.  Without batching,
9679        // thousands of separate files could be created on boot.
9680        if (!isSystemApp || needsFlush) {
9681            new Thread("Error dump: " + dropboxTag) {
9682                @Override
9683                public void run() {
9684                    String report;
9685                    synchronized (sb) {
9686                        report = sb.toString();
9687                        sb.delete(0, sb.length());
9688                        sb.trimToSize();
9689                    }
9690                    if (report.length() != 0) {
9691                        dbox.addText(dropboxTag, report);
9692                    }
9693                }
9694            }.start();
9695            return;
9696        }
9697
9698        // System app batching:
9699        if (!bufferWasEmpty) {
9700            // An existing dropbox-writing thread is outstanding, so
9701            // we don't need to start it up.  The existing thread will
9702            // catch the buffer appends we just did.
9703            return;
9704        }
9705
9706        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9707        // (After this point, we shouldn't access AMS internal data structures.)
9708        new Thread("Error dump: " + dropboxTag) {
9709            @Override
9710            public void run() {
9711                // 5 second sleep to let stacks arrive and be batched together
9712                try {
9713                    Thread.sleep(5000);  // 5 seconds
9714                } catch (InterruptedException e) {}
9715
9716                String errorReport;
9717                synchronized (mStrictModeBuffer) {
9718                    errorReport = mStrictModeBuffer.toString();
9719                    if (errorReport.length() == 0) {
9720                        return;
9721                    }
9722                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9723                    mStrictModeBuffer.trimToSize();
9724                }
9725                dbox.addText(dropboxTag, errorReport);
9726            }
9727        }.start();
9728    }
9729
9730    /**
9731     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9732     * @param app object of the crashing app, null for the system server
9733     * @param tag reported by the caller
9734     * @param crashInfo describing the context of the error
9735     * @return true if the process should exit immediately (WTF is fatal)
9736     */
9737    public boolean handleApplicationWtf(IBinder app, String tag,
9738            ApplicationErrorReport.CrashInfo crashInfo) {
9739        ProcessRecord r = findAppProcess(app, "WTF");
9740        final String processName = app == null ? "system_server"
9741                : (r == null ? "unknown" : r.processName);
9742
9743        EventLog.writeEvent(EventLogTags.AM_WTF,
9744                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9745                processName,
9746                r == null ? -1 : r.info.flags,
9747                tag, crashInfo.exceptionMessage);
9748
9749        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9750
9751        if (r != null && r.pid != Process.myPid() &&
9752                Settings.Global.getInt(mContext.getContentResolver(),
9753                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9754            crashApplication(r, crashInfo);
9755            return true;
9756        } else {
9757            return false;
9758        }
9759    }
9760
9761    /**
9762     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9763     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9764     */
9765    private ProcessRecord findAppProcess(IBinder app, String reason) {
9766        if (app == null) {
9767            return null;
9768        }
9769
9770        synchronized (this) {
9771            final int NP = mProcessNames.getMap().size();
9772            for (int ip=0; ip<NP; ip++) {
9773                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9774                final int NA = apps.size();
9775                for (int ia=0; ia<NA; ia++) {
9776                    ProcessRecord p = apps.valueAt(ia);
9777                    if (p.thread != null && p.thread.asBinder() == app) {
9778                        return p;
9779                    }
9780                }
9781            }
9782
9783            Slog.w(TAG, "Can't find mystery application for " + reason
9784                    + " from pid=" + Binder.getCallingPid()
9785                    + " uid=" + Binder.getCallingUid() + ": " + app);
9786            return null;
9787        }
9788    }
9789
9790    /**
9791     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9792     * to append various headers to the dropbox log text.
9793     */
9794    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9795            StringBuilder sb) {
9796        // Watchdog thread ends up invoking this function (with
9797        // a null ProcessRecord) to add the stack file to dropbox.
9798        // Do not acquire a lock on this (am) in such cases, as it
9799        // could cause a potential deadlock, if and when watchdog
9800        // is invoked due to unavailability of lock on am and it
9801        // would prevent watchdog from killing system_server.
9802        if (process == null) {
9803            sb.append("Process: ").append(processName).append("\n");
9804            return;
9805        }
9806        // Note: ProcessRecord 'process' is guarded by the service
9807        // instance.  (notably process.pkgList, which could otherwise change
9808        // concurrently during execution of this method)
9809        synchronized (this) {
9810            sb.append("Process: ").append(processName).append("\n");
9811            int flags = process.info.flags;
9812            IPackageManager pm = AppGlobals.getPackageManager();
9813            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9814            for (int ip=0; ip<process.pkgList.size(); ip++) {
9815                String pkg = process.pkgList.keyAt(ip);
9816                sb.append("Package: ").append(pkg);
9817                try {
9818                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9819                    if (pi != null) {
9820                        sb.append(" v").append(pi.versionCode);
9821                        if (pi.versionName != null) {
9822                            sb.append(" (").append(pi.versionName).append(")");
9823                        }
9824                    }
9825                } catch (RemoteException e) {
9826                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9827                }
9828                sb.append("\n");
9829            }
9830        }
9831    }
9832
9833    private static String processClass(ProcessRecord process) {
9834        if (process == null || process.pid == MY_PID) {
9835            return "system_server";
9836        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9837            return "system_app";
9838        } else {
9839            return "data_app";
9840        }
9841    }
9842
9843    /**
9844     * Write a description of an error (crash, WTF, ANR) to the drop box.
9845     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9846     * @param process which caused the error, null means the system server
9847     * @param activity which triggered the error, null if unknown
9848     * @param parent activity related to the error, null if unknown
9849     * @param subject line related to the error, null if absent
9850     * @param report in long form describing the error, null if absent
9851     * @param logFile to include in the report, null if none
9852     * @param crashInfo giving an application stack trace, null if absent
9853     */
9854    public void addErrorToDropBox(String eventType,
9855            ProcessRecord process, String processName, ActivityRecord activity,
9856            ActivityRecord parent, String subject,
9857            final String report, final File logFile,
9858            final ApplicationErrorReport.CrashInfo crashInfo) {
9859        // NOTE -- this must never acquire the ActivityManagerService lock,
9860        // otherwise the watchdog may be prevented from resetting the system.
9861
9862        final String dropboxTag = processClass(process) + "_" + eventType;
9863        final DropBoxManager dbox = (DropBoxManager)
9864                mContext.getSystemService(Context.DROPBOX_SERVICE);
9865
9866        // Exit early if the dropbox isn't configured to accept this report type.
9867        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9868
9869        final StringBuilder sb = new StringBuilder(1024);
9870        appendDropBoxProcessHeaders(process, processName, sb);
9871        if (activity != null) {
9872            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9873        }
9874        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9875            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9876        }
9877        if (parent != null && parent != activity) {
9878            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9879        }
9880        if (subject != null) {
9881            sb.append("Subject: ").append(subject).append("\n");
9882        }
9883        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9884        if (Debug.isDebuggerConnected()) {
9885            sb.append("Debugger: Connected\n");
9886        }
9887        sb.append("\n");
9888
9889        // Do the rest in a worker thread to avoid blocking the caller on I/O
9890        // (After this point, we shouldn't access AMS internal data structures.)
9891        Thread worker = new Thread("Error dump: " + dropboxTag) {
9892            @Override
9893            public void run() {
9894                if (report != null) {
9895                    sb.append(report);
9896                }
9897                if (logFile != null) {
9898                    try {
9899                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9900                                    "\n\n[[TRUNCATED]]"));
9901                    } catch (IOException e) {
9902                        Slog.e(TAG, "Error reading " + logFile, e);
9903                    }
9904                }
9905                if (crashInfo != null && crashInfo.stackTrace != null) {
9906                    sb.append(crashInfo.stackTrace);
9907                }
9908
9909                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9910                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9911                if (lines > 0) {
9912                    sb.append("\n");
9913
9914                    // Merge several logcat streams, and take the last N lines
9915                    InputStreamReader input = null;
9916                    try {
9917                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9918                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9919                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9920
9921                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9922                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9923                        input = new InputStreamReader(logcat.getInputStream());
9924
9925                        int num;
9926                        char[] buf = new char[8192];
9927                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9928                    } catch (IOException e) {
9929                        Slog.e(TAG, "Error running logcat", e);
9930                    } finally {
9931                        if (input != null) try { input.close(); } catch (IOException e) {}
9932                    }
9933                }
9934
9935                dbox.addText(dropboxTag, sb.toString());
9936            }
9937        };
9938
9939        if (process == null) {
9940            // If process is null, we are being called from some internal code
9941            // and may be about to die -- run this synchronously.
9942            worker.run();
9943        } else {
9944            worker.start();
9945        }
9946    }
9947
9948    /**
9949     * Bring up the "unexpected error" dialog box for a crashing app.
9950     * Deal with edge cases (intercepts from instrumented applications,
9951     * ActivityController, error intent receivers, that sort of thing).
9952     * @param r the application crashing
9953     * @param crashInfo describing the failure
9954     */
9955    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
9956        long timeMillis = System.currentTimeMillis();
9957        String shortMsg = crashInfo.exceptionClassName;
9958        String longMsg = crashInfo.exceptionMessage;
9959        String stackTrace = crashInfo.stackTrace;
9960        if (shortMsg != null && longMsg != null) {
9961            longMsg = shortMsg + ": " + longMsg;
9962        } else if (shortMsg != null) {
9963            longMsg = shortMsg;
9964        }
9965
9966        AppErrorResult result = new AppErrorResult();
9967        synchronized (this) {
9968            if (mController != null) {
9969                try {
9970                    String name = r != null ? r.processName : null;
9971                    int pid = r != null ? r.pid : Binder.getCallingPid();
9972                    if (!mController.appCrashed(name, pid,
9973                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
9974                        Slog.w(TAG, "Force-killing crashed app " + name
9975                                + " at watcher's request");
9976                        Process.killProcess(pid);
9977                        return;
9978                    }
9979                } catch (RemoteException e) {
9980                    mController = null;
9981                    Watchdog.getInstance().setActivityController(null);
9982                }
9983            }
9984
9985            final long origId = Binder.clearCallingIdentity();
9986
9987            // If this process is running instrumentation, finish it.
9988            if (r != null && r.instrumentationClass != null) {
9989                Slog.w(TAG, "Error in app " + r.processName
9990                      + " running instrumentation " + r.instrumentationClass + ":");
9991                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
9992                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
9993                Bundle info = new Bundle();
9994                info.putString("shortMsg", shortMsg);
9995                info.putString("longMsg", longMsg);
9996                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
9997                Binder.restoreCallingIdentity(origId);
9998                return;
9999            }
10000
10001            // If we can't identify the process or it's already exceeded its crash quota,
10002            // quit right away without showing a crash dialog.
10003            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10004                Binder.restoreCallingIdentity(origId);
10005                return;
10006            }
10007
10008            Message msg = Message.obtain();
10009            msg.what = SHOW_ERROR_MSG;
10010            HashMap data = new HashMap();
10011            data.put("result", result);
10012            data.put("app", r);
10013            msg.obj = data;
10014            mHandler.sendMessage(msg);
10015
10016            Binder.restoreCallingIdentity(origId);
10017        }
10018
10019        int res = result.get();
10020
10021        Intent appErrorIntent = null;
10022        synchronized (this) {
10023            if (r != null && !r.isolated) {
10024                // XXX Can't keep track of crash time for isolated processes,
10025                // since they don't have a persistent identity.
10026                mProcessCrashTimes.put(r.info.processName, r.uid,
10027                        SystemClock.uptimeMillis());
10028            }
10029            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10030                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10031            }
10032        }
10033
10034        if (appErrorIntent != null) {
10035            try {
10036                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10037            } catch (ActivityNotFoundException e) {
10038                Slog.w(TAG, "bug report receiver dissappeared", e);
10039            }
10040        }
10041    }
10042
10043    Intent createAppErrorIntentLocked(ProcessRecord r,
10044            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10045        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10046        if (report == null) {
10047            return null;
10048        }
10049        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10050        result.setComponent(r.errorReportReceiver);
10051        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10052        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10053        return result;
10054    }
10055
10056    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10057            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10058        if (r.errorReportReceiver == null) {
10059            return null;
10060        }
10061
10062        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10063            return null;
10064        }
10065
10066        ApplicationErrorReport report = new ApplicationErrorReport();
10067        report.packageName = r.info.packageName;
10068        report.installerPackageName = r.errorReportReceiver.getPackageName();
10069        report.processName = r.processName;
10070        report.time = timeMillis;
10071        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10072
10073        if (r.crashing || r.forceCrashReport) {
10074            report.type = ApplicationErrorReport.TYPE_CRASH;
10075            report.crashInfo = crashInfo;
10076        } else if (r.notResponding) {
10077            report.type = ApplicationErrorReport.TYPE_ANR;
10078            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10079
10080            report.anrInfo.activity = r.notRespondingReport.tag;
10081            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10082            report.anrInfo.info = r.notRespondingReport.longMsg;
10083        }
10084
10085        return report;
10086    }
10087
10088    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10089        enforceNotIsolatedCaller("getProcessesInErrorState");
10090        // assume our apps are happy - lazy create the list
10091        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10092
10093        final boolean allUsers = ActivityManager.checkUidPermission(
10094                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10095                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10096        int userId = UserHandle.getUserId(Binder.getCallingUid());
10097
10098        synchronized (this) {
10099
10100            // iterate across all processes
10101            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10102                ProcessRecord app = mLruProcesses.get(i);
10103                if (!allUsers && app.userId != userId) {
10104                    continue;
10105                }
10106                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10107                    // This one's in trouble, so we'll generate a report for it
10108                    // crashes are higher priority (in case there's a crash *and* an anr)
10109                    ActivityManager.ProcessErrorStateInfo report = null;
10110                    if (app.crashing) {
10111                        report = app.crashingReport;
10112                    } else if (app.notResponding) {
10113                        report = app.notRespondingReport;
10114                    }
10115
10116                    if (report != null) {
10117                        if (errList == null) {
10118                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10119                        }
10120                        errList.add(report);
10121                    } else {
10122                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10123                                " crashing = " + app.crashing +
10124                                " notResponding = " + app.notResponding);
10125                    }
10126                }
10127            }
10128        }
10129
10130        return errList;
10131    }
10132
10133    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10134        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10135            if (currApp != null) {
10136                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10137            }
10138            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10139        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10140            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10141        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10142            if (currApp != null) {
10143                currApp.lru = 0;
10144            }
10145            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10146        } else if (adj >= ProcessList.SERVICE_ADJ) {
10147            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10148        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10149            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10150        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10151            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10152        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10153            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10154        } else {
10155            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10156        }
10157    }
10158
10159    private void fillInProcMemInfo(ProcessRecord app,
10160            ActivityManager.RunningAppProcessInfo outInfo) {
10161        outInfo.pid = app.pid;
10162        outInfo.uid = app.info.uid;
10163        if (mHeavyWeightProcess == app) {
10164            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10165        }
10166        if (app.persistent) {
10167            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10168        }
10169        if (app.activities.size() > 0) {
10170            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10171        }
10172        outInfo.lastTrimLevel = app.trimMemoryLevel;
10173        int adj = app.curAdj;
10174        outInfo.importance = oomAdjToImportance(adj, outInfo);
10175        outInfo.importanceReasonCode = app.adjTypeCode;
10176    }
10177
10178    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10179        enforceNotIsolatedCaller("getRunningAppProcesses");
10180        // Lazy instantiation of list
10181        List<ActivityManager.RunningAppProcessInfo> runList = null;
10182        final boolean allUsers = ActivityManager.checkUidPermission(
10183                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10184                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10185        int userId = UserHandle.getUserId(Binder.getCallingUid());
10186        synchronized (this) {
10187            // Iterate across all processes
10188            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10189                ProcessRecord app = mLruProcesses.get(i);
10190                if (!allUsers && app.userId != userId) {
10191                    continue;
10192                }
10193                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10194                    // Generate process state info for running application
10195                    ActivityManager.RunningAppProcessInfo currApp =
10196                        new ActivityManager.RunningAppProcessInfo(app.processName,
10197                                app.pid, app.getPackageList());
10198                    fillInProcMemInfo(app, currApp);
10199                    if (app.adjSource instanceof ProcessRecord) {
10200                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10201                        currApp.importanceReasonImportance = oomAdjToImportance(
10202                                app.adjSourceOom, null);
10203                    } else if (app.adjSource instanceof ActivityRecord) {
10204                        ActivityRecord r = (ActivityRecord)app.adjSource;
10205                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10206                    }
10207                    if (app.adjTarget instanceof ComponentName) {
10208                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10209                    }
10210                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10211                    //        + " lru=" + currApp.lru);
10212                    if (runList == null) {
10213                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10214                    }
10215                    runList.add(currApp);
10216                }
10217            }
10218        }
10219        return runList;
10220    }
10221
10222    public List<ApplicationInfo> getRunningExternalApplications() {
10223        enforceNotIsolatedCaller("getRunningExternalApplications");
10224        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10225        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10226        if (runningApps != null && runningApps.size() > 0) {
10227            Set<String> extList = new HashSet<String>();
10228            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10229                if (app.pkgList != null) {
10230                    for (String pkg : app.pkgList) {
10231                        extList.add(pkg);
10232                    }
10233                }
10234            }
10235            IPackageManager pm = AppGlobals.getPackageManager();
10236            for (String pkg : extList) {
10237                try {
10238                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10239                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10240                        retList.add(info);
10241                    }
10242                } catch (RemoteException e) {
10243                }
10244            }
10245        }
10246        return retList;
10247    }
10248
10249    @Override
10250    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10251        enforceNotIsolatedCaller("getMyMemoryState");
10252        synchronized (this) {
10253            ProcessRecord proc;
10254            synchronized (mPidsSelfLocked) {
10255                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10256            }
10257            fillInProcMemInfo(proc, outInfo);
10258        }
10259    }
10260
10261    @Override
10262    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10263        if (checkCallingPermission(android.Manifest.permission.DUMP)
10264                != PackageManager.PERMISSION_GRANTED) {
10265            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10266                    + Binder.getCallingPid()
10267                    + ", uid=" + Binder.getCallingUid()
10268                    + " without permission "
10269                    + android.Manifest.permission.DUMP);
10270            return;
10271        }
10272
10273        boolean dumpAll = false;
10274        boolean dumpClient = false;
10275        String dumpPackage = null;
10276
10277        int opti = 0;
10278        while (opti < args.length) {
10279            String opt = args[opti];
10280            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10281                break;
10282            }
10283            opti++;
10284            if ("-a".equals(opt)) {
10285                dumpAll = true;
10286            } else if ("-c".equals(opt)) {
10287                dumpClient = true;
10288            } else if ("-h".equals(opt)) {
10289                pw.println("Activity manager dump options:");
10290                pw.println("  [-a] [-c] [-h] [cmd] ...");
10291                pw.println("  cmd may be one of:");
10292                pw.println("    a[ctivities]: activity stack state");
10293                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10294                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10295                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10296                pw.println("    o[om]: out of memory management");
10297                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10298                pw.println("    provider [COMP_SPEC]: provider client-side state");
10299                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10300                pw.println("    service [COMP_SPEC]: service client-side state");
10301                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10302                pw.println("    all: dump all activities");
10303                pw.println("    top: dump the top activity");
10304                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10305                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10306                pw.println("    a partial substring in a component name, a");
10307                pw.println("    hex object identifier.");
10308                pw.println("  -a: include all available server state.");
10309                pw.println("  -c: include client state.");
10310                return;
10311            } else {
10312                pw.println("Unknown argument: " + opt + "; use -h for help");
10313            }
10314        }
10315
10316        long origId = Binder.clearCallingIdentity();
10317        boolean more = false;
10318        // Is the caller requesting to dump a particular piece of data?
10319        if (opti < args.length) {
10320            String cmd = args[opti];
10321            opti++;
10322            if ("activities".equals(cmd) || "a".equals(cmd)) {
10323                synchronized (this) {
10324                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10325                }
10326            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10327                String[] newArgs;
10328                String name;
10329                if (opti >= args.length) {
10330                    name = null;
10331                    newArgs = EMPTY_STRING_ARRAY;
10332                } else {
10333                    name = args[opti];
10334                    opti++;
10335                    newArgs = new String[args.length - opti];
10336                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10337                            args.length - opti);
10338                }
10339                synchronized (this) {
10340                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10341                }
10342            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10343                String[] newArgs;
10344                String name;
10345                if (opti >= args.length) {
10346                    name = null;
10347                    newArgs = EMPTY_STRING_ARRAY;
10348                } else {
10349                    name = args[opti];
10350                    opti++;
10351                    newArgs = new String[args.length - opti];
10352                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10353                            args.length - opti);
10354                }
10355                synchronized (this) {
10356                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10357                }
10358            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10359                String[] newArgs;
10360                String name;
10361                if (opti >= args.length) {
10362                    name = null;
10363                    newArgs = EMPTY_STRING_ARRAY;
10364                } else {
10365                    name = args[opti];
10366                    opti++;
10367                    newArgs = new String[args.length - opti];
10368                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10369                            args.length - opti);
10370                }
10371                synchronized (this) {
10372                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10373                }
10374            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10375                synchronized (this) {
10376                    dumpOomLocked(fd, pw, args, opti, true);
10377                }
10378            } else if ("provider".equals(cmd)) {
10379                String[] newArgs;
10380                String name;
10381                if (opti >= args.length) {
10382                    name = null;
10383                    newArgs = EMPTY_STRING_ARRAY;
10384                } else {
10385                    name = args[opti];
10386                    opti++;
10387                    newArgs = new String[args.length - opti];
10388                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10389                }
10390                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10391                    pw.println("No providers match: " + name);
10392                    pw.println("Use -h for help.");
10393                }
10394            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10395                synchronized (this) {
10396                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10397                }
10398            } else if ("service".equals(cmd)) {
10399                String[] newArgs;
10400                String name;
10401                if (opti >= args.length) {
10402                    name = null;
10403                    newArgs = EMPTY_STRING_ARRAY;
10404                } else {
10405                    name = args[opti];
10406                    opti++;
10407                    newArgs = new String[args.length - opti];
10408                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10409                            args.length - opti);
10410                }
10411                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10412                    pw.println("No services match: " + name);
10413                    pw.println("Use -h for help.");
10414                }
10415            } else if ("package".equals(cmd)) {
10416                String[] newArgs;
10417                if (opti >= args.length) {
10418                    pw.println("package: no package name specified");
10419                    pw.println("Use -h for help.");
10420                } else {
10421                    dumpPackage = args[opti];
10422                    opti++;
10423                    newArgs = new String[args.length - opti];
10424                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10425                            args.length - opti);
10426                    args = newArgs;
10427                    opti = 0;
10428                    more = true;
10429                }
10430            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10431                synchronized (this) {
10432                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10433                }
10434            } else {
10435                // Dumping a single activity?
10436                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10437                    pw.println("Bad activity command, or no activities match: " + cmd);
10438                    pw.println("Use -h for help.");
10439                }
10440            }
10441            if (!more) {
10442                Binder.restoreCallingIdentity(origId);
10443                return;
10444            }
10445        }
10446
10447        // No piece of data specified, dump everything.
10448        synchronized (this) {
10449            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10450            pw.println();
10451            if (dumpAll) {
10452                pw.println("-------------------------------------------------------------------------------");
10453            }
10454            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10455            pw.println();
10456            if (dumpAll) {
10457                pw.println("-------------------------------------------------------------------------------");
10458            }
10459            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10460            pw.println();
10461            if (dumpAll) {
10462                pw.println("-------------------------------------------------------------------------------");
10463            }
10464            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10465            pw.println();
10466            if (dumpAll) {
10467                pw.println("-------------------------------------------------------------------------------");
10468            }
10469            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10470            pw.println();
10471            if (dumpAll) {
10472                pw.println("-------------------------------------------------------------------------------");
10473            }
10474            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10475        }
10476        Binder.restoreCallingIdentity(origId);
10477    }
10478
10479    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10480            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10481        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10482
10483        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10484                dumpPackage);
10485        boolean needSep = printedAnything;
10486
10487        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10488                dumpPackage, needSep, "  mFocusedActivity: ");
10489        if (printed) {
10490            printedAnything = true;
10491            needSep = false;
10492        }
10493
10494        if (dumpPackage == null) {
10495            if (needSep) {
10496                pw.println();
10497            }
10498            needSep = true;
10499            printedAnything = true;
10500            mStackSupervisor.dump(pw, "  ");
10501        }
10502
10503        if (mRecentTasks.size() > 0) {
10504            boolean printedHeader = false;
10505
10506            final int N = mRecentTasks.size();
10507            for (int i=0; i<N; i++) {
10508                TaskRecord tr = mRecentTasks.get(i);
10509                if (dumpPackage != null) {
10510                    if (tr.realActivity == null ||
10511                            !dumpPackage.equals(tr.realActivity)) {
10512                        continue;
10513                    }
10514                }
10515                if (!printedHeader) {
10516                    if (needSep) {
10517                        pw.println();
10518                    }
10519                    pw.println("  Recent tasks:");
10520                    printedHeader = true;
10521                    printedAnything = true;
10522                }
10523                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10524                        pw.println(tr);
10525                if (dumpAll) {
10526                    mRecentTasks.get(i).dump(pw, "    ");
10527                }
10528            }
10529        }
10530
10531        if (!printedAnything) {
10532            pw.println("  (nothing)");
10533        }
10534    }
10535
10536    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10537            int opti, boolean dumpAll, String dumpPackage) {
10538        boolean needSep = false;
10539        boolean printedAnything = false;
10540        int numPers = 0;
10541
10542        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10543
10544        if (dumpAll) {
10545            final int NP = mProcessNames.getMap().size();
10546            for (int ip=0; ip<NP; ip++) {
10547                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10548                final int NA = procs.size();
10549                for (int ia=0; ia<NA; ia++) {
10550                    ProcessRecord r = procs.valueAt(ia);
10551                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10552                        continue;
10553                    }
10554                    if (!needSep) {
10555                        pw.println("  All known processes:");
10556                        needSep = true;
10557                        printedAnything = true;
10558                    }
10559                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10560                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10561                        pw.print(" "); pw.println(r);
10562                    r.dump(pw, "    ");
10563                    if (r.persistent) {
10564                        numPers++;
10565                    }
10566                }
10567            }
10568        }
10569
10570        if (mIsolatedProcesses.size() > 0) {
10571            boolean printed = false;
10572            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10573                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10574                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10575                    continue;
10576                }
10577                if (!printed) {
10578                    if (needSep) {
10579                        pw.println();
10580                    }
10581                    pw.println("  Isolated process list (sorted by uid):");
10582                    printedAnything = true;
10583                    printed = true;
10584                    needSep = true;
10585                }
10586                pw.println(String.format("%sIsolated #%2d: %s",
10587                        "    ", i, r.toString()));
10588            }
10589        }
10590
10591        if (mLruProcesses.size() > 0) {
10592            if (needSep) {
10593                pw.println();
10594            }
10595            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10596                    pw.print(" total, non-act at ");
10597                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10598                    pw.print(", non-svc at ");
10599                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10600                    pw.println("):");
10601            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10602            needSep = true;
10603            printedAnything = true;
10604        }
10605
10606        if (dumpAll || dumpPackage != null) {
10607            synchronized (mPidsSelfLocked) {
10608                boolean printed = false;
10609                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10610                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10611                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10612                        continue;
10613                    }
10614                    if (!printed) {
10615                        if (needSep) pw.println();
10616                        needSep = true;
10617                        pw.println("  PID mappings:");
10618                        printed = true;
10619                        printedAnything = true;
10620                    }
10621                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10622                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10623                }
10624            }
10625        }
10626
10627        if (mForegroundProcesses.size() > 0) {
10628            synchronized (mPidsSelfLocked) {
10629                boolean printed = false;
10630                for (int i=0; i<mForegroundProcesses.size(); i++) {
10631                    ProcessRecord r = mPidsSelfLocked.get(
10632                            mForegroundProcesses.valueAt(i).pid);
10633                    if (dumpPackage != null && (r == null
10634                            || !r.pkgList.containsKey(dumpPackage))) {
10635                        continue;
10636                    }
10637                    if (!printed) {
10638                        if (needSep) pw.println();
10639                        needSep = true;
10640                        pw.println("  Foreground Processes:");
10641                        printed = true;
10642                        printedAnything = true;
10643                    }
10644                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10645                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10646                }
10647            }
10648        }
10649
10650        if (mPersistentStartingProcesses.size() > 0) {
10651            if (needSep) pw.println();
10652            needSep = true;
10653            printedAnything = true;
10654            pw.println("  Persisent processes that are starting:");
10655            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10656                    "Starting Norm", "Restarting PERS", dumpPackage);
10657        }
10658
10659        if (mRemovedProcesses.size() > 0) {
10660            if (needSep) pw.println();
10661            needSep = true;
10662            printedAnything = true;
10663            pw.println("  Processes that are being removed:");
10664            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10665                    "Removed Norm", "Removed PERS", dumpPackage);
10666        }
10667
10668        if (mProcessesOnHold.size() > 0) {
10669            if (needSep) pw.println();
10670            needSep = true;
10671            printedAnything = true;
10672            pw.println("  Processes that are on old until the system is ready:");
10673            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10674                    "OnHold Norm", "OnHold PERS", dumpPackage);
10675        }
10676
10677        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10678
10679        if (mProcessCrashTimes.getMap().size() > 0) {
10680            boolean printed = false;
10681            long now = SystemClock.uptimeMillis();
10682            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10683            final int NP = pmap.size();
10684            for (int ip=0; ip<NP; ip++) {
10685                String pname = pmap.keyAt(ip);
10686                SparseArray<Long> uids = pmap.valueAt(ip);
10687                final int N = uids.size();
10688                for (int i=0; i<N; i++) {
10689                    int puid = uids.keyAt(i);
10690                    ProcessRecord r = mProcessNames.get(pname, puid);
10691                    if (dumpPackage != null && (r == null
10692                            || !r.pkgList.containsKey(dumpPackage))) {
10693                        continue;
10694                    }
10695                    if (!printed) {
10696                        if (needSep) pw.println();
10697                        needSep = true;
10698                        pw.println("  Time since processes crashed:");
10699                        printed = true;
10700                        printedAnything = true;
10701                    }
10702                    pw.print("    Process "); pw.print(pname);
10703                            pw.print(" uid "); pw.print(puid);
10704                            pw.print(": last crashed ");
10705                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10706                            pw.println(" ago");
10707                }
10708            }
10709        }
10710
10711        if (mBadProcesses.getMap().size() > 0) {
10712            boolean printed = false;
10713            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10714            final int NP = pmap.size();
10715            for (int ip=0; ip<NP; ip++) {
10716                String pname = pmap.keyAt(ip);
10717                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10718                final int N = uids.size();
10719                for (int i=0; i<N; i++) {
10720                    int puid = uids.keyAt(i);
10721                    ProcessRecord r = mProcessNames.get(pname, puid);
10722                    if (dumpPackage != null && (r == null
10723                            || !r.pkgList.containsKey(dumpPackage))) {
10724                        continue;
10725                    }
10726                    if (!printed) {
10727                        if (needSep) pw.println();
10728                        needSep = true;
10729                        pw.println("  Bad processes:");
10730                        printedAnything = true;
10731                    }
10732                    BadProcessInfo info = uids.valueAt(i);
10733                    pw.print("    Bad process "); pw.print(pname);
10734                            pw.print(" uid "); pw.print(puid);
10735                            pw.print(": crashed at time "); pw.println(info.time);
10736                    if (info.shortMsg != null) {
10737                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10738                    }
10739                    if (info.longMsg != null) {
10740                        pw.print("      Long msg: "); pw.println(info.longMsg);
10741                    }
10742                    if (info.stack != null) {
10743                        pw.println("      Stack:");
10744                        int lastPos = 0;
10745                        for (int pos=0; pos<info.stack.length(); pos++) {
10746                            if (info.stack.charAt(pos) == '\n') {
10747                                pw.print("        ");
10748                                pw.write(info.stack, lastPos, pos-lastPos);
10749                                pw.println();
10750                                lastPos = pos+1;
10751                            }
10752                        }
10753                        if (lastPos < info.stack.length()) {
10754                            pw.print("        ");
10755                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10756                            pw.println();
10757                        }
10758                    }
10759                }
10760            }
10761        }
10762
10763        if (dumpPackage == null) {
10764            pw.println();
10765            needSep = false;
10766            pw.println("  mStartedUsers:");
10767            for (int i=0; i<mStartedUsers.size(); i++) {
10768                UserStartedState uss = mStartedUsers.valueAt(i);
10769                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10770                        pw.print(": "); uss.dump("", pw);
10771            }
10772            pw.print("  mStartedUserArray: [");
10773            for (int i=0; i<mStartedUserArray.length; i++) {
10774                if (i > 0) pw.print(", ");
10775                pw.print(mStartedUserArray[i]);
10776            }
10777            pw.println("]");
10778            pw.print("  mUserLru: [");
10779            for (int i=0; i<mUserLru.size(); i++) {
10780                if (i > 0) pw.print(", ");
10781                pw.print(mUserLru.get(i));
10782            }
10783            pw.println("]");
10784            if (dumpAll) {
10785                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10786            }
10787        }
10788        if (mHomeProcess != null && (dumpPackage == null
10789                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10790            if (needSep) {
10791                pw.println();
10792                needSep = false;
10793            }
10794            pw.println("  mHomeProcess: " + mHomeProcess);
10795        }
10796        if (mPreviousProcess != null && (dumpPackage == null
10797                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10798            if (needSep) {
10799                pw.println();
10800                needSep = false;
10801            }
10802            pw.println("  mPreviousProcess: " + mPreviousProcess);
10803        }
10804        if (dumpAll) {
10805            StringBuilder sb = new StringBuilder(128);
10806            sb.append("  mPreviousProcessVisibleTime: ");
10807            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10808            pw.println(sb);
10809        }
10810        if (mHeavyWeightProcess != null && (dumpPackage == null
10811                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10812            if (needSep) {
10813                pw.println();
10814                needSep = false;
10815            }
10816            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10817        }
10818        if (dumpPackage == null) {
10819            pw.println("  mConfiguration: " + mConfiguration);
10820        }
10821        if (dumpAll) {
10822            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10823            if (mCompatModePackages.getPackages().size() > 0) {
10824                boolean printed = false;
10825                for (Map.Entry<String, Integer> entry
10826                        : mCompatModePackages.getPackages().entrySet()) {
10827                    String pkg = entry.getKey();
10828                    int mode = entry.getValue();
10829                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10830                        continue;
10831                    }
10832                    if (!printed) {
10833                        pw.println("  mScreenCompatPackages:");
10834                        printed = true;
10835                    }
10836                    pw.print("    "); pw.print(pkg); pw.print(": ");
10837                            pw.print(mode); pw.println();
10838                }
10839            }
10840        }
10841        if (dumpPackage == null) {
10842            if (mSleeping || mWentToSleep || mLockScreenShown) {
10843                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10844                        + " mLockScreenShown " + mLockScreenShown);
10845            }
10846            if (mShuttingDown) {
10847                pw.println("  mShuttingDown=" + mShuttingDown);
10848            }
10849        }
10850        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10851                || mOrigWaitForDebugger) {
10852            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10853                    || dumpPackage.equals(mOrigDebugApp)) {
10854                if (needSep) {
10855                    pw.println();
10856                    needSep = false;
10857                }
10858                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10859                        + " mDebugTransient=" + mDebugTransient
10860                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10861            }
10862        }
10863        if (mOpenGlTraceApp != null) {
10864            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10865                if (needSep) {
10866                    pw.println();
10867                    needSep = false;
10868                }
10869                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10870            }
10871        }
10872        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10873                || mProfileFd != null) {
10874            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10875                if (needSep) {
10876                    pw.println();
10877                    needSep = false;
10878                }
10879                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10880                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10881                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10882                        + mAutoStopProfiler);
10883            }
10884        }
10885        if (dumpPackage == null) {
10886            if (mAlwaysFinishActivities || mController != null) {
10887                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10888                        + " mController=" + mController);
10889            }
10890            if (dumpAll) {
10891                pw.println("  Total persistent processes: " + numPers);
10892                pw.println("  mProcessesReady=" + mProcessesReady
10893                        + " mSystemReady=" + mSystemReady);
10894                pw.println("  mBooting=" + mBooting
10895                        + " mBooted=" + mBooted
10896                        + " mFactoryTest=" + mFactoryTest);
10897                pw.print("  mLastPowerCheckRealtime=");
10898                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10899                        pw.println("");
10900                pw.print("  mLastPowerCheckUptime=");
10901                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10902                        pw.println("");
10903                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10904                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10905                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10906                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10907                        + " (" + mLruProcesses.size() + " total)"
10908                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10909                        + " mNumServiceProcs=" + mNumServiceProcs
10910                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10911                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10912                        + " mLastMemoryLevel" + mLastMemoryLevel
10913                        + " mLastNumProcesses" + mLastNumProcesses);
10914                long now = SystemClock.uptimeMillis();
10915                pw.print("  mLastIdleTime=");
10916                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10917                        pw.print(" mLowRamSinceLastIdle=");
10918                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10919                        pw.println();
10920            }
10921        }
10922
10923        if (!printedAnything) {
10924            pw.println("  (nothing)");
10925        }
10926    }
10927
10928    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10929            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10930        if (mProcessesToGc.size() > 0) {
10931            boolean printed = false;
10932            long now = SystemClock.uptimeMillis();
10933            for (int i=0; i<mProcessesToGc.size(); i++) {
10934                ProcessRecord proc = mProcessesToGc.get(i);
10935                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10936                    continue;
10937                }
10938                if (!printed) {
10939                    if (needSep) pw.println();
10940                    needSep = true;
10941                    pw.println("  Processes that are waiting to GC:");
10942                    printed = true;
10943                }
10944                pw.print("    Process "); pw.println(proc);
10945                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
10946                        pw.print(", last gced=");
10947                        pw.print(now-proc.lastRequestedGc);
10948                        pw.print(" ms ago, last lowMem=");
10949                        pw.print(now-proc.lastLowMemory);
10950                        pw.println(" ms ago");
10951
10952            }
10953        }
10954        return needSep;
10955    }
10956
10957    void printOomLevel(PrintWriter pw, String name, int adj) {
10958        pw.print("    ");
10959        if (adj >= 0) {
10960            pw.print(' ');
10961            if (adj < 10) pw.print(' ');
10962        } else {
10963            if (adj > -10) pw.print(' ');
10964        }
10965        pw.print(adj);
10966        pw.print(": ");
10967        pw.print(name);
10968        pw.print(" (");
10969        pw.print(mProcessList.getMemLevel(adj)/1024);
10970        pw.println(" kB)");
10971    }
10972
10973    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10974            int opti, boolean dumpAll) {
10975        boolean needSep = false;
10976
10977        if (mLruProcesses.size() > 0) {
10978            if (needSep) pw.println();
10979            needSep = true;
10980            pw.println("  OOM levels:");
10981            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
10982            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
10983            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
10984            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
10985            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
10986            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
10987            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
10988            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
10989            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
10990            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
10991            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
10992            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
10993            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
10994
10995            if (needSep) pw.println();
10996            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
10997                    pw.print(" total, non-act at ");
10998                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10999                    pw.print(", non-svc at ");
11000                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11001                    pw.println("):");
11002            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11003            needSep = true;
11004        }
11005
11006        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11007
11008        pw.println();
11009        pw.println("  mHomeProcess: " + mHomeProcess);
11010        pw.println("  mPreviousProcess: " + mPreviousProcess);
11011        if (mHeavyWeightProcess != null) {
11012            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11013        }
11014
11015        return true;
11016    }
11017
11018    /**
11019     * There are three ways to call this:
11020     *  - no provider specified: dump all the providers
11021     *  - a flattened component name that matched an existing provider was specified as the
11022     *    first arg: dump that one provider
11023     *  - the first arg isn't the flattened component name of an existing provider:
11024     *    dump all providers whose component contains the first arg as a substring
11025     */
11026    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11027            int opti, boolean dumpAll) {
11028        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11029    }
11030
11031    static class ItemMatcher {
11032        ArrayList<ComponentName> components;
11033        ArrayList<String> strings;
11034        ArrayList<Integer> objects;
11035        boolean all;
11036
11037        ItemMatcher() {
11038            all = true;
11039        }
11040
11041        void build(String name) {
11042            ComponentName componentName = ComponentName.unflattenFromString(name);
11043            if (componentName != null) {
11044                if (components == null) {
11045                    components = new ArrayList<ComponentName>();
11046                }
11047                components.add(componentName);
11048                all = false;
11049            } else {
11050                int objectId = 0;
11051                // Not a '/' separated full component name; maybe an object ID?
11052                try {
11053                    objectId = Integer.parseInt(name, 16);
11054                    if (objects == null) {
11055                        objects = new ArrayList<Integer>();
11056                    }
11057                    objects.add(objectId);
11058                    all = false;
11059                } catch (RuntimeException e) {
11060                    // Not an integer; just do string match.
11061                    if (strings == null) {
11062                        strings = new ArrayList<String>();
11063                    }
11064                    strings.add(name);
11065                    all = false;
11066                }
11067            }
11068        }
11069
11070        int build(String[] args, int opti) {
11071            for (; opti<args.length; opti++) {
11072                String name = args[opti];
11073                if ("--".equals(name)) {
11074                    return opti+1;
11075                }
11076                build(name);
11077            }
11078            return opti;
11079        }
11080
11081        boolean match(Object object, ComponentName comp) {
11082            if (all) {
11083                return true;
11084            }
11085            if (components != null) {
11086                for (int i=0; i<components.size(); i++) {
11087                    if (components.get(i).equals(comp)) {
11088                        return true;
11089                    }
11090                }
11091            }
11092            if (objects != null) {
11093                for (int i=0; i<objects.size(); i++) {
11094                    if (System.identityHashCode(object) == objects.get(i)) {
11095                        return true;
11096                    }
11097                }
11098            }
11099            if (strings != null) {
11100                String flat = comp.flattenToString();
11101                for (int i=0; i<strings.size(); i++) {
11102                    if (flat.contains(strings.get(i))) {
11103                        return true;
11104                    }
11105                }
11106            }
11107            return false;
11108        }
11109    }
11110
11111    /**
11112     * There are three things that cmd can be:
11113     *  - a flattened component name that matches an existing activity
11114     *  - the cmd arg isn't the flattened component name of an existing activity:
11115     *    dump all activity whose component contains the cmd as a substring
11116     *  - A hex number of the ActivityRecord object instance.
11117     */
11118    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11119            int opti, boolean dumpAll) {
11120        ArrayList<ActivityRecord> activities;
11121
11122        synchronized (this) {
11123            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11124        }
11125
11126        if (activities.size() <= 0) {
11127            return false;
11128        }
11129
11130        String[] newArgs = new String[args.length - opti];
11131        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11132
11133        TaskRecord lastTask = null;
11134        boolean needSep = false;
11135        for (int i=activities.size()-1; i>=0; i--) {
11136            ActivityRecord r = activities.get(i);
11137            if (needSep) {
11138                pw.println();
11139            }
11140            needSep = true;
11141            synchronized (this) {
11142                if (lastTask != r.task) {
11143                    lastTask = r.task;
11144                    pw.print("TASK "); pw.print(lastTask.affinity);
11145                            pw.print(" id="); pw.println(lastTask.taskId);
11146                    if (dumpAll) {
11147                        lastTask.dump(pw, "  ");
11148                    }
11149                }
11150            }
11151            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11152        }
11153        return true;
11154    }
11155
11156    /**
11157     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11158     * there is a thread associated with the activity.
11159     */
11160    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11161            final ActivityRecord r, String[] args, boolean dumpAll) {
11162        String innerPrefix = prefix + "  ";
11163        synchronized (this) {
11164            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11165                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11166                    pw.print(" pid=");
11167                    if (r.app != null) pw.println(r.app.pid);
11168                    else pw.println("(not running)");
11169            if (dumpAll) {
11170                r.dump(pw, innerPrefix);
11171            }
11172        }
11173        if (r.app != null && r.app.thread != null) {
11174            // flush anything that is already in the PrintWriter since the thread is going
11175            // to write to the file descriptor directly
11176            pw.flush();
11177            try {
11178                TransferPipe tp = new TransferPipe();
11179                try {
11180                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11181                            r.appToken, innerPrefix, args);
11182                    tp.go(fd);
11183                } finally {
11184                    tp.kill();
11185                }
11186            } catch (IOException e) {
11187                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11188            } catch (RemoteException e) {
11189                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11190            }
11191        }
11192    }
11193
11194    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11195            int opti, boolean dumpAll, String dumpPackage) {
11196        boolean needSep = false;
11197        boolean onlyHistory = false;
11198        boolean printedAnything = false;
11199
11200        if ("history".equals(dumpPackage)) {
11201            if (opti < args.length && "-s".equals(args[opti])) {
11202                dumpAll = false;
11203            }
11204            onlyHistory = true;
11205            dumpPackage = null;
11206        }
11207
11208        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11209        if (!onlyHistory && dumpAll) {
11210            if (mRegisteredReceivers.size() > 0) {
11211                boolean printed = false;
11212                Iterator it = mRegisteredReceivers.values().iterator();
11213                while (it.hasNext()) {
11214                    ReceiverList r = (ReceiverList)it.next();
11215                    if (dumpPackage != null && (r.app == null ||
11216                            !dumpPackage.equals(r.app.info.packageName))) {
11217                        continue;
11218                    }
11219                    if (!printed) {
11220                        pw.println("  Registered Receivers:");
11221                        needSep = true;
11222                        printed = true;
11223                        printedAnything = true;
11224                    }
11225                    pw.print("  * "); pw.println(r);
11226                    r.dump(pw, "    ");
11227                }
11228            }
11229
11230            if (mReceiverResolver.dump(pw, needSep ?
11231                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11232                    "    ", dumpPackage, false)) {
11233                needSep = true;
11234                printedAnything = true;
11235            }
11236        }
11237
11238        for (BroadcastQueue q : mBroadcastQueues) {
11239            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11240            printedAnything |= needSep;
11241        }
11242
11243        needSep = true;
11244
11245        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11246            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11247                if (needSep) {
11248                    pw.println();
11249                }
11250                needSep = true;
11251                printedAnything = true;
11252                pw.print("  Sticky broadcasts for user ");
11253                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11254                StringBuilder sb = new StringBuilder(128);
11255                for (Map.Entry<String, ArrayList<Intent>> ent
11256                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11257                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11258                    if (dumpAll) {
11259                        pw.println(":");
11260                        ArrayList<Intent> intents = ent.getValue();
11261                        final int N = intents.size();
11262                        for (int i=0; i<N; i++) {
11263                            sb.setLength(0);
11264                            sb.append("    Intent: ");
11265                            intents.get(i).toShortString(sb, false, true, false, false);
11266                            pw.println(sb.toString());
11267                            Bundle bundle = intents.get(i).getExtras();
11268                            if (bundle != null) {
11269                                pw.print("      ");
11270                                pw.println(bundle.toString());
11271                            }
11272                        }
11273                    } else {
11274                        pw.println("");
11275                    }
11276                }
11277            }
11278        }
11279
11280        if (!onlyHistory && dumpAll) {
11281            pw.println();
11282            for (BroadcastQueue queue : mBroadcastQueues) {
11283                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11284                        + queue.mBroadcastsScheduled);
11285            }
11286            pw.println("  mHandler:");
11287            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11288            needSep = true;
11289            printedAnything = true;
11290        }
11291
11292        if (!printedAnything) {
11293            pw.println("  (nothing)");
11294        }
11295    }
11296
11297    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11298            int opti, boolean dumpAll, String dumpPackage) {
11299        boolean needSep;
11300        boolean printedAnything = false;
11301
11302        ItemMatcher matcher = new ItemMatcher();
11303        matcher.build(args, opti);
11304
11305        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11306
11307        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11308        printedAnything |= needSep;
11309
11310        if (mLaunchingProviders.size() > 0) {
11311            boolean printed = false;
11312            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11313                ContentProviderRecord r = mLaunchingProviders.get(i);
11314                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11315                    continue;
11316                }
11317                if (!printed) {
11318                    if (needSep) pw.println();
11319                    needSep = true;
11320                    pw.println("  Launching content providers:");
11321                    printed = true;
11322                    printedAnything = true;
11323                }
11324                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11325                        pw.println(r);
11326            }
11327        }
11328
11329        if (mGrantedUriPermissions.size() > 0) {
11330            boolean printed = false;
11331            int dumpUid = -2;
11332            if (dumpPackage != null) {
11333                try {
11334                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11335                } catch (NameNotFoundException e) {
11336                    dumpUid = -1;
11337                }
11338            }
11339            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11340                int uid = mGrantedUriPermissions.keyAt(i);
11341                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11342                    continue;
11343                }
11344                ArrayMap<Uri, UriPermission> perms
11345                        = mGrantedUriPermissions.valueAt(i);
11346                if (!printed) {
11347                    if (needSep) pw.println();
11348                    needSep = true;
11349                    pw.println("  Granted Uri Permissions:");
11350                    printed = true;
11351                    printedAnything = true;
11352                }
11353                pw.print("  * UID "); pw.print(uid);
11354                        pw.println(" holds:");
11355                for (UriPermission perm : perms.values()) {
11356                    pw.print("    "); pw.println(perm);
11357                    if (dumpAll) {
11358                        perm.dump(pw, "      ");
11359                    }
11360                }
11361            }
11362        }
11363
11364        if (!printedAnything) {
11365            pw.println("  (nothing)");
11366        }
11367    }
11368
11369    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11370            int opti, boolean dumpAll, String dumpPackage) {
11371        boolean printed = false;
11372
11373        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11374
11375        if (mIntentSenderRecords.size() > 0) {
11376            Iterator<WeakReference<PendingIntentRecord>> it
11377                    = mIntentSenderRecords.values().iterator();
11378            while (it.hasNext()) {
11379                WeakReference<PendingIntentRecord> ref = it.next();
11380                PendingIntentRecord rec = ref != null ? ref.get(): null;
11381                if (dumpPackage != null && (rec == null
11382                        || !dumpPackage.equals(rec.key.packageName))) {
11383                    continue;
11384                }
11385                printed = true;
11386                if (rec != null) {
11387                    pw.print("  * "); pw.println(rec);
11388                    if (dumpAll) {
11389                        rec.dump(pw, "    ");
11390                    }
11391                } else {
11392                    pw.print("  * "); pw.println(ref);
11393                }
11394            }
11395        }
11396
11397        if (!printed) {
11398            pw.println("  (nothing)");
11399        }
11400    }
11401
11402    private static final int dumpProcessList(PrintWriter pw,
11403            ActivityManagerService service, List list,
11404            String prefix, String normalLabel, String persistentLabel,
11405            String dumpPackage) {
11406        int numPers = 0;
11407        final int N = list.size()-1;
11408        for (int i=N; i>=0; i--) {
11409            ProcessRecord r = (ProcessRecord)list.get(i);
11410            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11411                continue;
11412            }
11413            pw.println(String.format("%s%s #%2d: %s",
11414                    prefix, (r.persistent ? persistentLabel : normalLabel),
11415                    i, r.toString()));
11416            if (r.persistent) {
11417                numPers++;
11418            }
11419        }
11420        return numPers;
11421    }
11422
11423    private static final boolean dumpProcessOomList(PrintWriter pw,
11424            ActivityManagerService service, List<ProcessRecord> origList,
11425            String prefix, String normalLabel, String persistentLabel,
11426            boolean inclDetails, String dumpPackage) {
11427
11428        ArrayList<Pair<ProcessRecord, Integer>> list
11429                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11430        for (int i=0; i<origList.size(); i++) {
11431            ProcessRecord r = origList.get(i);
11432            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11433                continue;
11434            }
11435            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11436        }
11437
11438        if (list.size() <= 0) {
11439            return false;
11440        }
11441
11442        Comparator<Pair<ProcessRecord, Integer>> comparator
11443                = new Comparator<Pair<ProcessRecord, Integer>>() {
11444            @Override
11445            public int compare(Pair<ProcessRecord, Integer> object1,
11446                    Pair<ProcessRecord, Integer> object2) {
11447                if (object1.first.setAdj != object2.first.setAdj) {
11448                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11449                }
11450                if (object1.second.intValue() != object2.second.intValue()) {
11451                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11452                }
11453                return 0;
11454            }
11455        };
11456
11457        Collections.sort(list, comparator);
11458
11459        final long curRealtime = SystemClock.elapsedRealtime();
11460        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11461        final long curUptime = SystemClock.uptimeMillis();
11462        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11463
11464        for (int i=list.size()-1; i>=0; i--) {
11465            ProcessRecord r = list.get(i).first;
11466            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11467            char schedGroup;
11468            switch (r.setSchedGroup) {
11469                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11470                    schedGroup = 'B';
11471                    break;
11472                case Process.THREAD_GROUP_DEFAULT:
11473                    schedGroup = 'F';
11474                    break;
11475                default:
11476                    schedGroup = '?';
11477                    break;
11478            }
11479            char foreground;
11480            if (r.foregroundActivities) {
11481                foreground = 'A';
11482            } else if (r.foregroundServices) {
11483                foreground = 'S';
11484            } else {
11485                foreground = ' ';
11486            }
11487            String procState = ProcessList.makeProcStateString(r.curProcState);
11488            pw.print(prefix);
11489            pw.print(r.persistent ? persistentLabel : normalLabel);
11490            pw.print(" #");
11491            int num = (origList.size()-1)-list.get(i).second;
11492            if (num < 10) pw.print(' ');
11493            pw.print(num);
11494            pw.print(": ");
11495            pw.print(oomAdj);
11496            pw.print(' ');
11497            pw.print(schedGroup);
11498            pw.print('/');
11499            pw.print(foreground);
11500            pw.print('/');
11501            pw.print(procState);
11502            pw.print(" trm:");
11503            if (r.trimMemoryLevel < 10) pw.print(' ');
11504            pw.print(r.trimMemoryLevel);
11505            pw.print(' ');
11506            pw.print(r.toShortString());
11507            pw.print(" (");
11508            pw.print(r.adjType);
11509            pw.println(')');
11510            if (r.adjSource != null || r.adjTarget != null) {
11511                pw.print(prefix);
11512                pw.print("    ");
11513                if (r.adjTarget instanceof ComponentName) {
11514                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11515                } else if (r.adjTarget != null) {
11516                    pw.print(r.adjTarget.toString());
11517                } else {
11518                    pw.print("{null}");
11519                }
11520                pw.print("<=");
11521                if (r.adjSource instanceof ProcessRecord) {
11522                    pw.print("Proc{");
11523                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11524                    pw.println("}");
11525                } else if (r.adjSource != null) {
11526                    pw.println(r.adjSource.toString());
11527                } else {
11528                    pw.println("{null}");
11529                }
11530            }
11531            if (inclDetails) {
11532                pw.print(prefix);
11533                pw.print("    ");
11534                pw.print("oom: max="); pw.print(r.maxAdj);
11535                pw.print(" curRaw="); pw.print(r.curRawAdj);
11536                pw.print(" setRaw="); pw.print(r.setRawAdj);
11537                pw.print(" cur="); pw.print(r.curAdj);
11538                pw.print(" set="); pw.println(r.setAdj);
11539                pw.print(prefix);
11540                pw.print("    ");
11541                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11542                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11543                pw.print(" lastPss="); pw.print(r.lastPss);
11544                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11545                pw.print(prefix);
11546                pw.print("    ");
11547                pw.print("keeping="); pw.print(r.keeping);
11548                pw.print(" cached="); pw.print(r.cached);
11549                pw.print(" empty="); pw.print(r.empty);
11550                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11551
11552                if (!r.keeping) {
11553                    if (r.lastWakeTime != 0) {
11554                        long wtime;
11555                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11556                        synchronized (stats) {
11557                            wtime = stats.getProcessWakeTime(r.info.uid,
11558                                    r.pid, curRealtime);
11559                        }
11560                        long timeUsed = wtime - r.lastWakeTime;
11561                        pw.print(prefix);
11562                        pw.print("    ");
11563                        pw.print("keep awake over ");
11564                        TimeUtils.formatDuration(realtimeSince, pw);
11565                        pw.print(" used ");
11566                        TimeUtils.formatDuration(timeUsed, pw);
11567                        pw.print(" (");
11568                        pw.print((timeUsed*100)/realtimeSince);
11569                        pw.println("%)");
11570                    }
11571                    if (r.lastCpuTime != 0) {
11572                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11573                        pw.print(prefix);
11574                        pw.print("    ");
11575                        pw.print("run cpu over ");
11576                        TimeUtils.formatDuration(uptimeSince, pw);
11577                        pw.print(" used ");
11578                        TimeUtils.formatDuration(timeUsed, pw);
11579                        pw.print(" (");
11580                        pw.print((timeUsed*100)/uptimeSince);
11581                        pw.println("%)");
11582                    }
11583                }
11584            }
11585        }
11586        return true;
11587    }
11588
11589    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11590        ArrayList<ProcessRecord> procs;
11591        synchronized (this) {
11592            if (args != null && args.length > start
11593                    && args[start].charAt(0) != '-') {
11594                procs = new ArrayList<ProcessRecord>();
11595                int pid = -1;
11596                try {
11597                    pid = Integer.parseInt(args[start]);
11598                } catch (NumberFormatException e) {
11599                }
11600                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11601                    ProcessRecord proc = mLruProcesses.get(i);
11602                    if (proc.pid == pid) {
11603                        procs.add(proc);
11604                    } else if (proc.processName.equals(args[start])) {
11605                        procs.add(proc);
11606                    }
11607                }
11608                if (procs.size() <= 0) {
11609                    return null;
11610                }
11611            } else {
11612                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11613            }
11614        }
11615        return procs;
11616    }
11617
11618    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11619            PrintWriter pw, String[] args) {
11620        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11621        if (procs == null) {
11622            pw.println("No process found for: " + args[0]);
11623            return;
11624        }
11625
11626        long uptime = SystemClock.uptimeMillis();
11627        long realtime = SystemClock.elapsedRealtime();
11628        pw.println("Applications Graphics Acceleration Info:");
11629        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11630
11631        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11632            ProcessRecord r = procs.get(i);
11633            if (r.thread != null) {
11634                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11635                pw.flush();
11636                try {
11637                    TransferPipe tp = new TransferPipe();
11638                    try {
11639                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11640                        tp.go(fd);
11641                    } finally {
11642                        tp.kill();
11643                    }
11644                } catch (IOException e) {
11645                    pw.println("Failure while dumping the app: " + r);
11646                    pw.flush();
11647                } catch (RemoteException e) {
11648                    pw.println("Got a RemoteException while dumping the app " + r);
11649                    pw.flush();
11650                }
11651            }
11652        }
11653    }
11654
11655    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11656        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11657        if (procs == null) {
11658            pw.println("No process found for: " + args[0]);
11659            return;
11660        }
11661
11662        pw.println("Applications Database Info:");
11663
11664        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11665            ProcessRecord r = procs.get(i);
11666            if (r.thread != null) {
11667                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11668                pw.flush();
11669                try {
11670                    TransferPipe tp = new TransferPipe();
11671                    try {
11672                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11673                        tp.go(fd);
11674                    } finally {
11675                        tp.kill();
11676                    }
11677                } catch (IOException e) {
11678                    pw.println("Failure while dumping the app: " + r);
11679                    pw.flush();
11680                } catch (RemoteException e) {
11681                    pw.println("Got a RemoteException while dumping the app " + r);
11682                    pw.flush();
11683                }
11684            }
11685        }
11686    }
11687
11688    final static class MemItem {
11689        final boolean isProc;
11690        final String label;
11691        final String shortLabel;
11692        final long pss;
11693        final int id;
11694        final boolean hasActivities;
11695        ArrayList<MemItem> subitems;
11696
11697        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11698                boolean _hasActivities) {
11699            isProc = true;
11700            label = _label;
11701            shortLabel = _shortLabel;
11702            pss = _pss;
11703            id = _id;
11704            hasActivities = _hasActivities;
11705        }
11706
11707        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11708            isProc = false;
11709            label = _label;
11710            shortLabel = _shortLabel;
11711            pss = _pss;
11712            id = _id;
11713            hasActivities = false;
11714        }
11715    }
11716
11717    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11718            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11719        if (sort && !isCompact) {
11720            Collections.sort(items, new Comparator<MemItem>() {
11721                @Override
11722                public int compare(MemItem lhs, MemItem rhs) {
11723                    if (lhs.pss < rhs.pss) {
11724                        return 1;
11725                    } else if (lhs.pss > rhs.pss) {
11726                        return -1;
11727                    }
11728                    return 0;
11729                }
11730            });
11731        }
11732
11733        for (int i=0; i<items.size(); i++) {
11734            MemItem mi = items.get(i);
11735            if (!isCompact) {
11736                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11737            } else if (mi.isProc) {
11738                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11739                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11740                pw.println(mi.hasActivities ? ",a" : ",e");
11741            } else {
11742                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11743                pw.println(mi.pss);
11744            }
11745            if (mi.subitems != null) {
11746                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11747                        true, isCompact);
11748            }
11749        }
11750    }
11751
11752    // These are in KB.
11753    static final long[] DUMP_MEM_BUCKETS = new long[] {
11754        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11755        120*1024, 160*1024, 200*1024,
11756        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11757        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11758    };
11759
11760    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11761            boolean stackLike) {
11762        int start = label.lastIndexOf('.');
11763        if (start >= 0) start++;
11764        else start = 0;
11765        int end = label.length();
11766        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11767            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11768                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11769                out.append(bucket);
11770                out.append(stackLike ? "MB." : "MB ");
11771                out.append(label, start, end);
11772                return;
11773            }
11774        }
11775        out.append(memKB/1024);
11776        out.append(stackLike ? "MB." : "MB ");
11777        out.append(label, start, end);
11778    }
11779
11780    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11781            ProcessList.NATIVE_ADJ,
11782            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11783            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11784            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11785            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11786            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11787    };
11788    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11789            "Native",
11790            "System", "Persistent", "Foreground",
11791            "Visible", "Perceptible",
11792            "Heavy Weight", "Backup",
11793            "A Services", "Home",
11794            "Previous", "B Services", "Cached"
11795    };
11796    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11797            "native",
11798            "sys", "pers", "fore",
11799            "vis", "percept",
11800            "heavy", "backup",
11801            "servicea", "home",
11802            "prev", "serviceb", "cached"
11803    };
11804
11805    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11806            long realtime, boolean isCheckinRequest, boolean isCompact) {
11807        if (isCheckinRequest || isCompact) {
11808            // short checkin version
11809            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11810        } else {
11811            pw.println("Applications Memory Usage (kB):");
11812            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11813        }
11814    }
11815
11816    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11817            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11818        boolean dumpDetails = false;
11819        boolean dumpFullDetails = false;
11820        boolean dumpDalvik = false;
11821        boolean oomOnly = false;
11822        boolean isCompact = false;
11823        boolean localOnly = false;
11824
11825        int opti = 0;
11826        while (opti < args.length) {
11827            String opt = args[opti];
11828            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11829                break;
11830            }
11831            opti++;
11832            if ("-a".equals(opt)) {
11833                dumpDetails = true;
11834                dumpFullDetails = true;
11835                dumpDalvik = true;
11836            } else if ("-d".equals(opt)) {
11837                dumpDalvik = true;
11838            } else if ("-c".equals(opt)) {
11839                isCompact = true;
11840            } else if ("--oom".equals(opt)) {
11841                oomOnly = true;
11842            } else if ("--local".equals(opt)) {
11843                localOnly = true;
11844            } else if ("-h".equals(opt)) {
11845                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11846                pw.println("  -a: include all available information for each process.");
11847                pw.println("  -d: include dalvik details when dumping process details.");
11848                pw.println("  -c: dump in a compact machine-parseable representation.");
11849                pw.println("  --oom: only show processes organized by oom adj.");
11850                pw.println("  --local: only collect details locally, don't call process.");
11851                pw.println("If [process] is specified it can be the name or ");
11852                pw.println("pid of a specific process to dump.");
11853                return;
11854            } else {
11855                pw.println("Unknown argument: " + opt + "; use -h for help");
11856            }
11857        }
11858
11859        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11860        long uptime = SystemClock.uptimeMillis();
11861        long realtime = SystemClock.elapsedRealtime();
11862        final long[] tmpLong = new long[1];
11863
11864        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11865        if (procs == null) {
11866            // No Java processes.  Maybe they want to print a native process.
11867            if (args != null && args.length > opti
11868                    && args[opti].charAt(0) != '-') {
11869                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11870                        = new ArrayList<ProcessCpuTracker.Stats>();
11871                updateCpuStatsNow();
11872                int findPid = -1;
11873                try {
11874                    findPid = Integer.parseInt(args[opti]);
11875                } catch (NumberFormatException e) {
11876                }
11877                synchronized (mProcessCpuThread) {
11878                    final int N = mProcessCpuTracker.countStats();
11879                    for (int i=0; i<N; i++) {
11880                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11881                        if (st.pid == findPid || (st.baseName != null
11882                                && st.baseName.equals(args[opti]))) {
11883                            nativeProcs.add(st);
11884                        }
11885                    }
11886                }
11887                if (nativeProcs.size() > 0) {
11888                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11889                            isCompact);
11890                    Debug.MemoryInfo mi = null;
11891                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11892                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11893                        final int pid = r.pid;
11894                        if (!isCheckinRequest && dumpDetails) {
11895                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11896                        }
11897                        if (mi == null) {
11898                            mi = new Debug.MemoryInfo();
11899                        }
11900                        if (dumpDetails || (!brief && !oomOnly)) {
11901                            Debug.getMemoryInfo(pid, mi);
11902                        } else {
11903                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11904                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11905                        }
11906                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11907                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11908                        if (isCheckinRequest) {
11909                            pw.println();
11910                        }
11911                    }
11912                    return;
11913                }
11914            }
11915            pw.println("No process found for: " + args[opti]);
11916            return;
11917        }
11918
11919        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11920            dumpDetails = true;
11921        }
11922
11923        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11924
11925        String[] innerArgs = new String[args.length-opti];
11926        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11927
11928        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11929        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11930        long nativePss=0, dalvikPss=0, otherPss=0;
11931        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11932
11933        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11934        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11935                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11936
11937        long totalPss = 0;
11938        long cachedPss = 0;
11939
11940        Debug.MemoryInfo mi = null;
11941        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11942            final ProcessRecord r = procs.get(i);
11943            final IApplicationThread thread;
11944            final int pid;
11945            final int oomAdj;
11946            final boolean hasActivities;
11947            synchronized (this) {
11948                thread = r.thread;
11949                pid = r.pid;
11950                oomAdj = r.getSetAdjWithServices();
11951                hasActivities = r.activities.size() > 0;
11952            }
11953            if (thread != null) {
11954                if (!isCheckinRequest && dumpDetails) {
11955                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
11956                }
11957                if (mi == null) {
11958                    mi = new Debug.MemoryInfo();
11959                }
11960                if (dumpDetails || (!brief && !oomOnly)) {
11961                    Debug.getMemoryInfo(pid, mi);
11962                } else {
11963                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11964                    mi.dalvikPrivateDirty = (int)tmpLong[0];
11965                }
11966                if (dumpDetails) {
11967                    if (localOnly) {
11968                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11969                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
11970                        if (isCheckinRequest) {
11971                            pw.println();
11972                        }
11973                    } else {
11974                        try {
11975                            pw.flush();
11976                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
11977                                    dumpDalvik, innerArgs);
11978                        } catch (RemoteException e) {
11979                            if (!isCheckinRequest) {
11980                                pw.println("Got RemoteException!");
11981                                pw.flush();
11982                            }
11983                        }
11984                    }
11985                }
11986
11987                final long myTotalPss = mi.getTotalPss();
11988                final long myTotalUss = mi.getTotalUss();
11989
11990                synchronized (this) {
11991                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
11992                        // Record this for posterity if the process has been stable.
11993                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
11994                    }
11995                }
11996
11997                if (!isCheckinRequest && mi != null) {
11998                    totalPss += myTotalPss;
11999                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12000                            (hasActivities ? " / activities)" : ")"),
12001                            r.processName, myTotalPss, pid, hasActivities);
12002                    procMems.add(pssItem);
12003                    procMemsMap.put(pid, pssItem);
12004
12005                    nativePss += mi.nativePss;
12006                    dalvikPss += mi.dalvikPss;
12007                    otherPss += mi.otherPss;
12008                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12009                        long mem = mi.getOtherPss(j);
12010                        miscPss[j] += mem;
12011                        otherPss -= mem;
12012                    }
12013
12014                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12015                        cachedPss += myTotalPss;
12016                    }
12017
12018                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12019                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12020                                || oomIndex == (oomPss.length-1)) {
12021                            oomPss[oomIndex] += myTotalPss;
12022                            if (oomProcs[oomIndex] == null) {
12023                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12024                            }
12025                            oomProcs[oomIndex].add(pssItem);
12026                            break;
12027                        }
12028                    }
12029                }
12030            }
12031        }
12032
12033        if (!isCheckinRequest && procs.size() > 1) {
12034            // If we are showing aggregations, also look for native processes to
12035            // include so that our aggregations are more accurate.
12036            updateCpuStatsNow();
12037            synchronized (mProcessCpuThread) {
12038                final int N = mProcessCpuTracker.countStats();
12039                for (int i=0; i<N; i++) {
12040                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12041                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12042                        if (mi == null) {
12043                            mi = new Debug.MemoryInfo();
12044                        }
12045                        if (!brief && !oomOnly) {
12046                            Debug.getMemoryInfo(st.pid, mi);
12047                        } else {
12048                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12049                            mi.nativePrivateDirty = (int)tmpLong[0];
12050                        }
12051
12052                        final long myTotalPss = mi.getTotalPss();
12053                        totalPss += myTotalPss;
12054
12055                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12056                                st.name, myTotalPss, st.pid, false);
12057                        procMems.add(pssItem);
12058
12059                        nativePss += mi.nativePss;
12060                        dalvikPss += mi.dalvikPss;
12061                        otherPss += mi.otherPss;
12062                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12063                            long mem = mi.getOtherPss(j);
12064                            miscPss[j] += mem;
12065                            otherPss -= mem;
12066                        }
12067                        oomPss[0] += myTotalPss;
12068                        if (oomProcs[0] == null) {
12069                            oomProcs[0] = new ArrayList<MemItem>();
12070                        }
12071                        oomProcs[0].add(pssItem);
12072                    }
12073                }
12074            }
12075
12076            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12077
12078            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12079            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12080            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12081            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12082                String label = Debug.MemoryInfo.getOtherLabel(j);
12083                catMems.add(new MemItem(label, label, miscPss[j], j));
12084            }
12085
12086            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12087            for (int j=0; j<oomPss.length; j++) {
12088                if (oomPss[j] != 0) {
12089                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12090                            : DUMP_MEM_OOM_LABEL[j];
12091                    MemItem item = new MemItem(label, label, oomPss[j],
12092                            DUMP_MEM_OOM_ADJ[j]);
12093                    item.subitems = oomProcs[j];
12094                    oomMems.add(item);
12095                }
12096            }
12097
12098            if (!brief && !oomOnly && !isCompact) {
12099                pw.println();
12100                pw.println("Total PSS by process:");
12101                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12102                pw.println();
12103            }
12104            if (!isCompact) {
12105                pw.println("Total PSS by OOM adjustment:");
12106            }
12107            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12108            if (!brief && !oomOnly) {
12109                PrintWriter out = categoryPw != null ? categoryPw : pw;
12110                if (!isCompact) {
12111                    out.println();
12112                    out.println("Total PSS by category:");
12113                }
12114                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12115            }
12116            if (!isCompact) {
12117                pw.println();
12118            }
12119            MemInfoReader memInfo = new MemInfoReader();
12120            memInfo.readMemInfo();
12121            if (!brief) {
12122                if (!isCompact) {
12123                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12124                    pw.println(" kB");
12125                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12126                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12127                            pw.print(cachedPss); pw.print(" cached pss + ");
12128                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12129                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12130                } else {
12131                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12132                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12133                            + memInfo.getFreeSizeKb()); pw.print(",");
12134                    pw.println(totalPss - cachedPss);
12135                }
12136            }
12137            if (!isCompact) {
12138                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12139                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12140                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12141                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12142                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12143                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12144                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12145                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12146                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12147                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12148                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12149            }
12150            if (!brief) {
12151                if (memInfo.getZramTotalSizeKb() != 0) {
12152                    if (!isCompact) {
12153                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12154                                pw.print(" kB physical used for ");
12155                                pw.print(memInfo.getSwapTotalSizeKb()
12156                                        - memInfo.getSwapFreeSizeKb());
12157                                pw.print(" kB in swap (");
12158                                pw.print(memInfo.getSwapTotalSizeKb());
12159                                pw.println(" kB total swap)");
12160                    } else {
12161                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12162                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12163                                pw.println(memInfo.getSwapFreeSizeKb());
12164                    }
12165                }
12166                final int[] SINGLE_LONG_FORMAT = new int[] {
12167                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12168                };
12169                long[] longOut = new long[1];
12170                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12171                        SINGLE_LONG_FORMAT, null, longOut, null);
12172                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12173                longOut[0] = 0;
12174                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12175                        SINGLE_LONG_FORMAT, null, longOut, null);
12176                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12177                longOut[0] = 0;
12178                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12179                        SINGLE_LONG_FORMAT, null, longOut, null);
12180                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12181                longOut[0] = 0;
12182                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12183                        SINGLE_LONG_FORMAT, null, longOut, null);
12184                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12185                if (!isCompact) {
12186                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12187                        pw.print("      KSM: "); pw.print(sharing);
12188                                pw.print(" kB saved from shared ");
12189                                pw.print(shared); pw.println(" kB");
12190                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12191                                pw.print(voltile); pw.println(" kB volatile");
12192                    }
12193                    pw.print("   Tuning: ");
12194                    pw.print(ActivityManager.staticGetMemoryClass());
12195                    pw.print(" (large ");
12196                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12197                    pw.print("), oom ");
12198                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12199                    pw.print(" kB");
12200                    pw.print(", restore limit ");
12201                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12202                    pw.print(" kB");
12203                    if (ActivityManager.isLowRamDeviceStatic()) {
12204                        pw.print(" (low-ram)");
12205                    }
12206                    if (ActivityManager.isHighEndGfx()) {
12207                        pw.print(" (high-end-gfx)");
12208                    }
12209                    pw.println();
12210                } else {
12211                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12212                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12213                    pw.println(voltile);
12214                    pw.print("tuning,");
12215                    pw.print(ActivityManager.staticGetMemoryClass());
12216                    pw.print(',');
12217                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12218                    pw.print(',');
12219                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12220                    if (ActivityManager.isLowRamDeviceStatic()) {
12221                        pw.print(",low-ram");
12222                    }
12223                    if (ActivityManager.isHighEndGfx()) {
12224                        pw.print(",high-end-gfx");
12225                    }
12226                    pw.println();
12227                }
12228            }
12229        }
12230    }
12231
12232    /**
12233     * Searches array of arguments for the specified string
12234     * @param args array of argument strings
12235     * @param value value to search for
12236     * @return true if the value is contained in the array
12237     */
12238    private static boolean scanArgs(String[] args, String value) {
12239        if (args != null) {
12240            for (String arg : args) {
12241                if (value.equals(arg)) {
12242                    return true;
12243                }
12244            }
12245        }
12246        return false;
12247    }
12248
12249    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12250            ContentProviderRecord cpr, boolean always) {
12251        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12252
12253        if (!inLaunching || always) {
12254            synchronized (cpr) {
12255                cpr.launchingApp = null;
12256                cpr.notifyAll();
12257            }
12258            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12259            String names[] = cpr.info.authority.split(";");
12260            for (int j = 0; j < names.length; j++) {
12261                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12262            }
12263        }
12264
12265        for (int i=0; i<cpr.connections.size(); i++) {
12266            ContentProviderConnection conn = cpr.connections.get(i);
12267            if (conn.waiting) {
12268                // If this connection is waiting for the provider, then we don't
12269                // need to mess with its process unless we are always removing
12270                // or for some reason the provider is not currently launching.
12271                if (inLaunching && !always) {
12272                    continue;
12273                }
12274            }
12275            ProcessRecord capp = conn.client;
12276            conn.dead = true;
12277            if (conn.stableCount > 0) {
12278                if (!capp.persistent && capp.thread != null
12279                        && capp.pid != 0
12280                        && capp.pid != MY_PID) {
12281                    killUnneededProcessLocked(capp, "depends on provider "
12282                            + cpr.name.flattenToShortString()
12283                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12284                }
12285            } else if (capp.thread != null && conn.provider.provider != null) {
12286                try {
12287                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12288                } catch (RemoteException e) {
12289                }
12290                // In the protocol here, we don't expect the client to correctly
12291                // clean up this connection, we'll just remove it.
12292                cpr.connections.remove(i);
12293                conn.client.conProviders.remove(conn);
12294            }
12295        }
12296
12297        if (inLaunching && always) {
12298            mLaunchingProviders.remove(cpr);
12299        }
12300        return inLaunching;
12301    }
12302
12303    /**
12304     * Main code for cleaning up a process when it has gone away.  This is
12305     * called both as a result of the process dying, or directly when stopping
12306     * a process when running in single process mode.
12307     */
12308    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12309            boolean restarting, boolean allowRestart, int index) {
12310        if (index >= 0) {
12311            removeLruProcessLocked(app);
12312            ProcessList.remove(app.pid);
12313        }
12314
12315        mProcessesToGc.remove(app);
12316        mPendingPssProcesses.remove(app);
12317
12318        // Dismiss any open dialogs.
12319        if (app.crashDialog != null && !app.forceCrashReport) {
12320            app.crashDialog.dismiss();
12321            app.crashDialog = null;
12322        }
12323        if (app.anrDialog != null) {
12324            app.anrDialog.dismiss();
12325            app.anrDialog = null;
12326        }
12327        if (app.waitDialog != null) {
12328            app.waitDialog.dismiss();
12329            app.waitDialog = null;
12330        }
12331
12332        app.crashing = false;
12333        app.notResponding = false;
12334
12335        app.resetPackageList(mProcessStats);
12336        app.unlinkDeathRecipient();
12337        app.makeInactive(mProcessStats);
12338        app.forcingToForeground = null;
12339        app.foregroundServices = false;
12340        app.foregroundActivities = false;
12341        app.hasShownUi = false;
12342        app.hasAboveClient = false;
12343        app.hasClientActivities = false;
12344
12345        mServices.killServicesLocked(app, allowRestart);
12346
12347        boolean restart = false;
12348
12349        // Remove published content providers.
12350        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12351            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12352            final boolean always = app.bad || !allowRestart;
12353            if (removeDyingProviderLocked(app, cpr, always) || always) {
12354                // We left the provider in the launching list, need to
12355                // restart it.
12356                restart = true;
12357            }
12358
12359            cpr.provider = null;
12360            cpr.proc = null;
12361        }
12362        app.pubProviders.clear();
12363
12364        // Take care of any launching providers waiting for this process.
12365        if (checkAppInLaunchingProvidersLocked(app, false)) {
12366            restart = true;
12367        }
12368
12369        // Unregister from connected content providers.
12370        if (!app.conProviders.isEmpty()) {
12371            for (int i=0; i<app.conProviders.size(); i++) {
12372                ContentProviderConnection conn = app.conProviders.get(i);
12373                conn.provider.connections.remove(conn);
12374            }
12375            app.conProviders.clear();
12376        }
12377
12378        // At this point there may be remaining entries in mLaunchingProviders
12379        // where we were the only one waiting, so they are no longer of use.
12380        // Look for these and clean up if found.
12381        // XXX Commented out for now.  Trying to figure out a way to reproduce
12382        // the actual situation to identify what is actually going on.
12383        if (false) {
12384            for (int i=0; i<mLaunchingProviders.size(); i++) {
12385                ContentProviderRecord cpr = (ContentProviderRecord)
12386                        mLaunchingProviders.get(i);
12387                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12388                    synchronized (cpr) {
12389                        cpr.launchingApp = null;
12390                        cpr.notifyAll();
12391                    }
12392                }
12393            }
12394        }
12395
12396        skipCurrentReceiverLocked(app);
12397
12398        // Unregister any receivers.
12399        for (int i=app.receivers.size()-1; i>=0; i--) {
12400            removeReceiverLocked(app.receivers.valueAt(i));
12401        }
12402        app.receivers.clear();
12403
12404        // If the app is undergoing backup, tell the backup manager about it
12405        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12406            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12407                    + mBackupTarget.appInfo + " died during backup");
12408            try {
12409                IBackupManager bm = IBackupManager.Stub.asInterface(
12410                        ServiceManager.getService(Context.BACKUP_SERVICE));
12411                bm.agentDisconnected(app.info.packageName);
12412            } catch (RemoteException e) {
12413                // can't happen; backup manager is local
12414            }
12415        }
12416
12417        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12418            ProcessChangeItem item = mPendingProcessChanges.get(i);
12419            if (item.pid == app.pid) {
12420                mPendingProcessChanges.remove(i);
12421                mAvailProcessChanges.add(item);
12422            }
12423        }
12424        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12425
12426        // If the caller is restarting this app, then leave it in its
12427        // current lists and let the caller take care of it.
12428        if (restarting) {
12429            return;
12430        }
12431
12432        if (!app.persistent || app.isolated) {
12433            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12434                    "Removing non-persistent process during cleanup: " + app);
12435            mProcessNames.remove(app.processName, app.uid);
12436            mIsolatedProcesses.remove(app.uid);
12437            if (mHeavyWeightProcess == app) {
12438                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12439                        mHeavyWeightProcess.userId, 0));
12440                mHeavyWeightProcess = null;
12441            }
12442        } else if (!app.removed) {
12443            // This app is persistent, so we need to keep its record around.
12444            // If it is not already on the pending app list, add it there
12445            // and start a new process for it.
12446            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12447                mPersistentStartingProcesses.add(app);
12448                restart = true;
12449            }
12450        }
12451        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12452                "Clean-up removing on hold: " + app);
12453        mProcessesOnHold.remove(app);
12454
12455        if (app == mHomeProcess) {
12456            mHomeProcess = null;
12457        }
12458        if (app == mPreviousProcess) {
12459            mPreviousProcess = null;
12460        }
12461
12462        if (restart && !app.isolated) {
12463            // We have components that still need to be running in the
12464            // process, so re-launch it.
12465            mProcessNames.put(app.processName, app.uid, app);
12466            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
12467        } else if (app.pid > 0 && app.pid != MY_PID) {
12468            // Goodbye!
12469            synchronized (mPidsSelfLocked) {
12470                mPidsSelfLocked.remove(app.pid);
12471                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12472            }
12473            app.setPid(0);
12474        }
12475    }
12476
12477    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12478        // Look through the content providers we are waiting to have launched,
12479        // and if any run in this process then either schedule a restart of
12480        // the process or kill the client waiting for it if this process has
12481        // gone bad.
12482        int NL = mLaunchingProviders.size();
12483        boolean restart = false;
12484        for (int i=0; i<NL; i++) {
12485            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12486            if (cpr.launchingApp == app) {
12487                if (!alwaysBad && !app.bad) {
12488                    restart = true;
12489                } else {
12490                    removeDyingProviderLocked(app, cpr, true);
12491                    // cpr should have been removed from mLaunchingProviders
12492                    NL = mLaunchingProviders.size();
12493                    i--;
12494                }
12495            }
12496        }
12497        return restart;
12498    }
12499
12500    // =========================================================
12501    // SERVICES
12502    // =========================================================
12503
12504    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12505            int flags) {
12506        enforceNotIsolatedCaller("getServices");
12507        synchronized (this) {
12508            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12509        }
12510    }
12511
12512    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12513        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12514        synchronized (this) {
12515            return mServices.getRunningServiceControlPanelLocked(name);
12516        }
12517    }
12518
12519    public ComponentName startService(IApplicationThread caller, Intent service,
12520            String resolvedType, int userId) {
12521        enforceNotIsolatedCaller("startService");
12522        // Refuse possible leaked file descriptors
12523        if (service != null && service.hasFileDescriptors() == true) {
12524            throw new IllegalArgumentException("File descriptors passed in Intent");
12525        }
12526
12527        if (DEBUG_SERVICE)
12528            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12529        synchronized(this) {
12530            final int callingPid = Binder.getCallingPid();
12531            final int callingUid = Binder.getCallingUid();
12532            final long origId = Binder.clearCallingIdentity();
12533            ComponentName res = mServices.startServiceLocked(caller, service,
12534                    resolvedType, callingPid, callingUid, userId);
12535            Binder.restoreCallingIdentity(origId);
12536            return res;
12537        }
12538    }
12539
12540    ComponentName startServiceInPackage(int uid,
12541            Intent service, String resolvedType, int userId) {
12542        synchronized(this) {
12543            if (DEBUG_SERVICE)
12544                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12545            final long origId = Binder.clearCallingIdentity();
12546            ComponentName res = mServices.startServiceLocked(null, service,
12547                    resolvedType, -1, uid, userId);
12548            Binder.restoreCallingIdentity(origId);
12549            return res;
12550        }
12551    }
12552
12553    public int stopService(IApplicationThread caller, Intent service,
12554            String resolvedType, int userId) {
12555        enforceNotIsolatedCaller("stopService");
12556        // Refuse possible leaked file descriptors
12557        if (service != null && service.hasFileDescriptors() == true) {
12558            throw new IllegalArgumentException("File descriptors passed in Intent");
12559        }
12560
12561        synchronized(this) {
12562            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12563        }
12564    }
12565
12566    public IBinder peekService(Intent service, String resolvedType) {
12567        enforceNotIsolatedCaller("peekService");
12568        // Refuse possible leaked file descriptors
12569        if (service != null && service.hasFileDescriptors() == true) {
12570            throw new IllegalArgumentException("File descriptors passed in Intent");
12571        }
12572        synchronized(this) {
12573            return mServices.peekServiceLocked(service, resolvedType);
12574        }
12575    }
12576
12577    public boolean stopServiceToken(ComponentName className, IBinder token,
12578            int startId) {
12579        synchronized(this) {
12580            return mServices.stopServiceTokenLocked(className, token, startId);
12581        }
12582    }
12583
12584    public void setServiceForeground(ComponentName className, IBinder token,
12585            int id, Notification notification, boolean removeNotification) {
12586        synchronized(this) {
12587            mServices.setServiceForegroundLocked(className, token, id, notification,
12588                    removeNotification);
12589        }
12590    }
12591
12592    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12593            boolean requireFull, String name, String callerPackage) {
12594        final int callingUserId = UserHandle.getUserId(callingUid);
12595        if (callingUserId != userId) {
12596            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12597                if ((requireFull || checkComponentPermission(
12598                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12599                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12600                        && checkComponentPermission(
12601                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12602                                callingPid, callingUid, -1, true)
12603                                != PackageManager.PERMISSION_GRANTED) {
12604                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12605                        // In this case, they would like to just execute as their
12606                        // owner user instead of failing.
12607                        userId = callingUserId;
12608                    } else {
12609                        StringBuilder builder = new StringBuilder(128);
12610                        builder.append("Permission Denial: ");
12611                        builder.append(name);
12612                        if (callerPackage != null) {
12613                            builder.append(" from ");
12614                            builder.append(callerPackage);
12615                        }
12616                        builder.append(" asks to run as user ");
12617                        builder.append(userId);
12618                        builder.append(" but is calling from user ");
12619                        builder.append(UserHandle.getUserId(callingUid));
12620                        builder.append("; this requires ");
12621                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12622                        if (!requireFull) {
12623                            builder.append(" or ");
12624                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12625                        }
12626                        String msg = builder.toString();
12627                        Slog.w(TAG, msg);
12628                        throw new SecurityException(msg);
12629                    }
12630                }
12631            }
12632            if (userId == UserHandle.USER_CURRENT
12633                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12634                // Note that we may be accessing this outside of a lock...
12635                // shouldn't be a big deal, if this is being called outside
12636                // of a locked context there is intrinsically a race with
12637                // the value the caller will receive and someone else changing it.
12638                userId = mCurrentUserId;
12639            }
12640            if (!allowAll && userId < 0) {
12641                throw new IllegalArgumentException(
12642                        "Call does not support special user #" + userId);
12643            }
12644        }
12645        return userId;
12646    }
12647
12648    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12649            String className, int flags) {
12650        boolean result = false;
12651        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12652            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12653                if (ActivityManager.checkUidPermission(
12654                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12655                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12656                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12657                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12658                            + " requests FLAG_SINGLE_USER, but app does not hold "
12659                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12660                    Slog.w(TAG, msg);
12661                    throw new SecurityException(msg);
12662                }
12663                result = true;
12664            }
12665        } else if (componentProcessName == aInfo.packageName) {
12666            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12667        } else if ("system".equals(componentProcessName)) {
12668            result = true;
12669        }
12670        if (DEBUG_MU) {
12671            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12672                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12673        }
12674        return result;
12675    }
12676
12677    public int bindService(IApplicationThread caller, IBinder token,
12678            Intent service, String resolvedType,
12679            IServiceConnection connection, int flags, int userId) {
12680        enforceNotIsolatedCaller("bindService");
12681        // Refuse possible leaked file descriptors
12682        if (service != null && service.hasFileDescriptors() == true) {
12683            throw new IllegalArgumentException("File descriptors passed in Intent");
12684        }
12685
12686        synchronized(this) {
12687            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12688                    connection, flags, userId);
12689        }
12690    }
12691
12692    public boolean unbindService(IServiceConnection connection) {
12693        synchronized (this) {
12694            return mServices.unbindServiceLocked(connection);
12695        }
12696    }
12697
12698    public void publishService(IBinder token, Intent intent, IBinder service) {
12699        // Refuse possible leaked file descriptors
12700        if (intent != null && intent.hasFileDescriptors() == true) {
12701            throw new IllegalArgumentException("File descriptors passed in Intent");
12702        }
12703
12704        synchronized(this) {
12705            if (!(token instanceof ServiceRecord)) {
12706                throw new IllegalArgumentException("Invalid service token");
12707            }
12708            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12709        }
12710    }
12711
12712    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12713        // Refuse possible leaked file descriptors
12714        if (intent != null && intent.hasFileDescriptors() == true) {
12715            throw new IllegalArgumentException("File descriptors passed in Intent");
12716        }
12717
12718        synchronized(this) {
12719            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12720        }
12721    }
12722
12723    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12724        synchronized(this) {
12725            if (!(token instanceof ServiceRecord)) {
12726                throw new IllegalArgumentException("Invalid service token");
12727            }
12728            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12729        }
12730    }
12731
12732    // =========================================================
12733    // BACKUP AND RESTORE
12734    // =========================================================
12735
12736    // Cause the target app to be launched if necessary and its backup agent
12737    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12738    // activity manager to announce its creation.
12739    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12740        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12741        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12742
12743        synchronized(this) {
12744            // !!! TODO: currently no check here that we're already bound
12745            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12746            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12747            synchronized (stats) {
12748                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12749            }
12750
12751            // Backup agent is now in use, its package can't be stopped.
12752            try {
12753                AppGlobals.getPackageManager().setPackageStoppedState(
12754                        app.packageName, false, UserHandle.getUserId(app.uid));
12755            } catch (RemoteException e) {
12756            } catch (IllegalArgumentException e) {
12757                Slog.w(TAG, "Failed trying to unstop package "
12758                        + app.packageName + ": " + e);
12759            }
12760
12761            BackupRecord r = new BackupRecord(ss, app, backupMode);
12762            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12763                    ? new ComponentName(app.packageName, app.backupAgentName)
12764                    : new ComponentName("android", "FullBackupAgent");
12765            // startProcessLocked() returns existing proc's record if it's already running
12766            ProcessRecord proc = startProcessLocked(app.processName, app,
12767                    false, 0, "backup", hostingName, false, false, false);
12768            if (proc == null) {
12769                Slog.e(TAG, "Unable to start backup agent process " + r);
12770                return false;
12771            }
12772
12773            r.app = proc;
12774            mBackupTarget = r;
12775            mBackupAppName = app.packageName;
12776
12777            // Try not to kill the process during backup
12778            updateOomAdjLocked(proc);
12779
12780            // If the process is already attached, schedule the creation of the backup agent now.
12781            // If it is not yet live, this will be done when it attaches to the framework.
12782            if (proc.thread != null) {
12783                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12784                try {
12785                    proc.thread.scheduleCreateBackupAgent(app,
12786                            compatibilityInfoForPackageLocked(app), backupMode);
12787                } catch (RemoteException e) {
12788                    // Will time out on the backup manager side
12789                }
12790            } else {
12791                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12792            }
12793            // Invariants: at this point, the target app process exists and the application
12794            // is either already running or in the process of coming up.  mBackupTarget and
12795            // mBackupAppName describe the app, so that when it binds back to the AM we
12796            // know that it's scheduled for a backup-agent operation.
12797        }
12798
12799        return true;
12800    }
12801
12802    @Override
12803    public void clearPendingBackup() {
12804        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12805        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12806
12807        synchronized (this) {
12808            mBackupTarget = null;
12809            mBackupAppName = null;
12810        }
12811    }
12812
12813    // A backup agent has just come up
12814    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12815        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12816                + " = " + agent);
12817
12818        synchronized(this) {
12819            if (!agentPackageName.equals(mBackupAppName)) {
12820                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12821                return;
12822            }
12823        }
12824
12825        long oldIdent = Binder.clearCallingIdentity();
12826        try {
12827            IBackupManager bm = IBackupManager.Stub.asInterface(
12828                    ServiceManager.getService(Context.BACKUP_SERVICE));
12829            bm.agentConnected(agentPackageName, agent);
12830        } catch (RemoteException e) {
12831            // can't happen; the backup manager service is local
12832        } catch (Exception e) {
12833            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12834            e.printStackTrace();
12835        } finally {
12836            Binder.restoreCallingIdentity(oldIdent);
12837        }
12838    }
12839
12840    // done with this agent
12841    public void unbindBackupAgent(ApplicationInfo appInfo) {
12842        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12843        if (appInfo == null) {
12844            Slog.w(TAG, "unbind backup agent for null app");
12845            return;
12846        }
12847
12848        synchronized(this) {
12849            try {
12850                if (mBackupAppName == null) {
12851                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12852                    return;
12853                }
12854
12855                if (!mBackupAppName.equals(appInfo.packageName)) {
12856                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12857                    return;
12858                }
12859
12860                // Not backing this app up any more; reset its OOM adjustment
12861                final ProcessRecord proc = mBackupTarget.app;
12862                updateOomAdjLocked(proc);
12863
12864                // If the app crashed during backup, 'thread' will be null here
12865                if (proc.thread != null) {
12866                    try {
12867                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12868                                compatibilityInfoForPackageLocked(appInfo));
12869                    } catch (Exception e) {
12870                        Slog.e(TAG, "Exception when unbinding backup agent:");
12871                        e.printStackTrace();
12872                    }
12873                }
12874            } finally {
12875                mBackupTarget = null;
12876                mBackupAppName = null;
12877            }
12878        }
12879    }
12880    // =========================================================
12881    // BROADCASTS
12882    // =========================================================
12883
12884    private final List getStickiesLocked(String action, IntentFilter filter,
12885            List cur, int userId) {
12886        final ContentResolver resolver = mContext.getContentResolver();
12887        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12888        if (stickies == null) {
12889            return cur;
12890        }
12891        final ArrayList<Intent> list = stickies.get(action);
12892        if (list == null) {
12893            return cur;
12894        }
12895        int N = list.size();
12896        for (int i=0; i<N; i++) {
12897            Intent intent = list.get(i);
12898            if (filter.match(resolver, intent, true, TAG) >= 0) {
12899                if (cur == null) {
12900                    cur = new ArrayList<Intent>();
12901                }
12902                cur.add(intent);
12903            }
12904        }
12905        return cur;
12906    }
12907
12908    boolean isPendingBroadcastProcessLocked(int pid) {
12909        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12910                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12911    }
12912
12913    void skipPendingBroadcastLocked(int pid) {
12914            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12915            for (BroadcastQueue queue : mBroadcastQueues) {
12916                queue.skipPendingBroadcastLocked(pid);
12917            }
12918    }
12919
12920    // The app just attached; send any pending broadcasts that it should receive
12921    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12922        boolean didSomething = false;
12923        for (BroadcastQueue queue : mBroadcastQueues) {
12924            didSomething |= queue.sendPendingBroadcastsLocked(app);
12925        }
12926        return didSomething;
12927    }
12928
12929    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12930            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
12931        enforceNotIsolatedCaller("registerReceiver");
12932        int callingUid;
12933        int callingPid;
12934        synchronized(this) {
12935            ProcessRecord callerApp = null;
12936            if (caller != null) {
12937                callerApp = getRecordForAppLocked(caller);
12938                if (callerApp == null) {
12939                    throw new SecurityException(
12940                            "Unable to find app for caller " + caller
12941                            + " (pid=" + Binder.getCallingPid()
12942                            + ") when registering receiver " + receiver);
12943                }
12944                if (callerApp.info.uid != Process.SYSTEM_UID &&
12945                        !callerApp.pkgList.containsKey(callerPackage) &&
12946                        !"android".equals(callerPackage)) {
12947                    throw new SecurityException("Given caller package " + callerPackage
12948                            + " is not running in process " + callerApp);
12949                }
12950                callingUid = callerApp.info.uid;
12951                callingPid = callerApp.pid;
12952            } else {
12953                callerPackage = null;
12954                callingUid = Binder.getCallingUid();
12955                callingPid = Binder.getCallingPid();
12956            }
12957
12958            userId = this.handleIncomingUser(callingPid, callingUid, userId,
12959                    true, true, "registerReceiver", callerPackage);
12960
12961            List allSticky = null;
12962
12963            // Look for any matching sticky broadcasts...
12964            Iterator actions = filter.actionsIterator();
12965            if (actions != null) {
12966                while (actions.hasNext()) {
12967                    String action = (String)actions.next();
12968                    allSticky = getStickiesLocked(action, filter, allSticky,
12969                            UserHandle.USER_ALL);
12970                    allSticky = getStickiesLocked(action, filter, allSticky,
12971                            UserHandle.getUserId(callingUid));
12972                }
12973            } else {
12974                allSticky = getStickiesLocked(null, filter, allSticky,
12975                        UserHandle.USER_ALL);
12976                allSticky = getStickiesLocked(null, filter, allSticky,
12977                        UserHandle.getUserId(callingUid));
12978            }
12979
12980            // The first sticky in the list is returned directly back to
12981            // the client.
12982            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12983
12984            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
12985                    + ": " + sticky);
12986
12987            if (receiver == null) {
12988                return sticky;
12989            }
12990
12991            ReceiverList rl
12992                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12993            if (rl == null) {
12994                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
12995                        userId, receiver);
12996                if (rl.app != null) {
12997                    rl.app.receivers.add(rl);
12998                } else {
12999                    try {
13000                        receiver.asBinder().linkToDeath(rl, 0);
13001                    } catch (RemoteException e) {
13002                        return sticky;
13003                    }
13004                    rl.linkedToDeath = true;
13005                }
13006                mRegisteredReceivers.put(receiver.asBinder(), rl);
13007            } else if (rl.uid != callingUid) {
13008                throw new IllegalArgumentException(
13009                        "Receiver requested to register for uid " + callingUid
13010                        + " was previously registered for uid " + rl.uid);
13011            } else if (rl.pid != callingPid) {
13012                throw new IllegalArgumentException(
13013                        "Receiver requested to register for pid " + callingPid
13014                        + " was previously registered for pid " + rl.pid);
13015            } else if (rl.userId != userId) {
13016                throw new IllegalArgumentException(
13017                        "Receiver requested to register for user " + userId
13018                        + " was previously registered for user " + rl.userId);
13019            }
13020            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13021                    permission, callingUid, userId);
13022            rl.add(bf);
13023            if (!bf.debugCheck()) {
13024                Slog.w(TAG, "==> For Dynamic broadast");
13025            }
13026            mReceiverResolver.addFilter(bf);
13027
13028            // Enqueue broadcasts for all existing stickies that match
13029            // this filter.
13030            if (allSticky != null) {
13031                ArrayList receivers = new ArrayList();
13032                receivers.add(bf);
13033
13034                int N = allSticky.size();
13035                for (int i=0; i<N; i++) {
13036                    Intent intent = (Intent)allSticky.get(i);
13037                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13038                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13039                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13040                            null, null, false, true, true, -1);
13041                    queue.enqueueParallelBroadcastLocked(r);
13042                    queue.scheduleBroadcastsLocked();
13043                }
13044            }
13045
13046            return sticky;
13047        }
13048    }
13049
13050    public void unregisterReceiver(IIntentReceiver receiver) {
13051        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13052
13053        final long origId = Binder.clearCallingIdentity();
13054        try {
13055            boolean doTrim = false;
13056
13057            synchronized(this) {
13058                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13059                if (rl != null) {
13060                    if (rl.curBroadcast != null) {
13061                        BroadcastRecord r = rl.curBroadcast;
13062                        final boolean doNext = finishReceiverLocked(
13063                                receiver.asBinder(), r.resultCode, r.resultData,
13064                                r.resultExtras, r.resultAbort);
13065                        if (doNext) {
13066                            doTrim = true;
13067                            r.queue.processNextBroadcast(false);
13068                        }
13069                    }
13070
13071                    if (rl.app != null) {
13072                        rl.app.receivers.remove(rl);
13073                    }
13074                    removeReceiverLocked(rl);
13075                    if (rl.linkedToDeath) {
13076                        rl.linkedToDeath = false;
13077                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13078                    }
13079                }
13080            }
13081
13082            // If we actually concluded any broadcasts, we might now be able
13083            // to trim the recipients' apps from our working set
13084            if (doTrim) {
13085                trimApplications();
13086                return;
13087            }
13088
13089        } finally {
13090            Binder.restoreCallingIdentity(origId);
13091        }
13092    }
13093
13094    void removeReceiverLocked(ReceiverList rl) {
13095        mRegisteredReceivers.remove(rl.receiver.asBinder());
13096        int N = rl.size();
13097        for (int i=0; i<N; i++) {
13098            mReceiverResolver.removeFilter(rl.get(i));
13099        }
13100    }
13101
13102    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13103        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13104            ProcessRecord r = mLruProcesses.get(i);
13105            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13106                try {
13107                    r.thread.dispatchPackageBroadcast(cmd, packages);
13108                } catch (RemoteException ex) {
13109                }
13110            }
13111        }
13112    }
13113
13114    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13115            int[] users) {
13116        List<ResolveInfo> receivers = null;
13117        try {
13118            HashSet<ComponentName> singleUserReceivers = null;
13119            boolean scannedFirstReceivers = false;
13120            for (int user : users) {
13121                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13122                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13123                if (user != 0 && newReceivers != null) {
13124                    // If this is not the primary user, we need to check for
13125                    // any receivers that should be filtered out.
13126                    for (int i=0; i<newReceivers.size(); i++) {
13127                        ResolveInfo ri = newReceivers.get(i);
13128                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13129                            newReceivers.remove(i);
13130                            i--;
13131                        }
13132                    }
13133                }
13134                if (newReceivers != null && newReceivers.size() == 0) {
13135                    newReceivers = null;
13136                }
13137                if (receivers == null) {
13138                    receivers = newReceivers;
13139                } else if (newReceivers != null) {
13140                    // We need to concatenate the additional receivers
13141                    // found with what we have do far.  This would be easy,
13142                    // but we also need to de-dup any receivers that are
13143                    // singleUser.
13144                    if (!scannedFirstReceivers) {
13145                        // Collect any single user receivers we had already retrieved.
13146                        scannedFirstReceivers = true;
13147                        for (int i=0; i<receivers.size(); i++) {
13148                            ResolveInfo ri = receivers.get(i);
13149                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13150                                ComponentName cn = new ComponentName(
13151                                        ri.activityInfo.packageName, ri.activityInfo.name);
13152                                if (singleUserReceivers == null) {
13153                                    singleUserReceivers = new HashSet<ComponentName>();
13154                                }
13155                                singleUserReceivers.add(cn);
13156                            }
13157                        }
13158                    }
13159                    // Add the new results to the existing results, tracking
13160                    // and de-dupping single user receivers.
13161                    for (int i=0; i<newReceivers.size(); i++) {
13162                        ResolveInfo ri = newReceivers.get(i);
13163                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13164                            ComponentName cn = new ComponentName(
13165                                    ri.activityInfo.packageName, ri.activityInfo.name);
13166                            if (singleUserReceivers == null) {
13167                                singleUserReceivers = new HashSet<ComponentName>();
13168                            }
13169                            if (!singleUserReceivers.contains(cn)) {
13170                                singleUserReceivers.add(cn);
13171                                receivers.add(ri);
13172                            }
13173                        } else {
13174                            receivers.add(ri);
13175                        }
13176                    }
13177                }
13178            }
13179        } catch (RemoteException ex) {
13180            // pm is in same process, this will never happen.
13181        }
13182        return receivers;
13183    }
13184
13185    private final int broadcastIntentLocked(ProcessRecord callerApp,
13186            String callerPackage, Intent intent, String resolvedType,
13187            IIntentReceiver resultTo, int resultCode, String resultData,
13188            Bundle map, String requiredPermission, int appOp,
13189            boolean ordered, boolean sticky, int callingPid, int callingUid,
13190            int userId) {
13191        intent = new Intent(intent);
13192
13193        // By default broadcasts do not go to stopped apps.
13194        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13195
13196        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13197            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13198            + " ordered=" + ordered + " userid=" + userId);
13199        if ((resultTo != null) && !ordered) {
13200            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13201        }
13202
13203        userId = handleIncomingUser(callingPid, callingUid, userId,
13204                true, false, "broadcast", callerPackage);
13205
13206        // Make sure that the user who is receiving this broadcast is started.
13207        // If not, we will just skip it.
13208        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13209            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13210                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13211                Slog.w(TAG, "Skipping broadcast of " + intent
13212                        + ": user " + userId + " is stopped");
13213                return ActivityManager.BROADCAST_SUCCESS;
13214            }
13215        }
13216
13217        /*
13218         * Prevent non-system code (defined here to be non-persistent
13219         * processes) from sending protected broadcasts.
13220         */
13221        int callingAppId = UserHandle.getAppId(callingUid);
13222        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13223            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13224            callingUid == 0) {
13225            // Always okay.
13226        } else if (callerApp == null || !callerApp.persistent) {
13227            try {
13228                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13229                        intent.getAction())) {
13230                    String msg = "Permission Denial: not allowed to send broadcast "
13231                            + intent.getAction() + " from pid="
13232                            + callingPid + ", uid=" + callingUid;
13233                    Slog.w(TAG, msg);
13234                    throw new SecurityException(msg);
13235                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13236                    // Special case for compatibility: we don't want apps to send this,
13237                    // but historically it has not been protected and apps may be using it
13238                    // to poke their own app widget.  So, instead of making it protected,
13239                    // just limit it to the caller.
13240                    if (callerApp == null) {
13241                        String msg = "Permission Denial: not allowed to send broadcast "
13242                                + intent.getAction() + " from unknown caller.";
13243                        Slog.w(TAG, msg);
13244                        throw new SecurityException(msg);
13245                    } else if (intent.getComponent() != null) {
13246                        // They are good enough to send to an explicit component...  verify
13247                        // it is being sent to the calling app.
13248                        if (!intent.getComponent().getPackageName().equals(
13249                                callerApp.info.packageName)) {
13250                            String msg = "Permission Denial: not allowed to send broadcast "
13251                                    + intent.getAction() + " to "
13252                                    + intent.getComponent().getPackageName() + " from "
13253                                    + callerApp.info.packageName;
13254                            Slog.w(TAG, msg);
13255                            throw new SecurityException(msg);
13256                        }
13257                    } else {
13258                        // Limit broadcast to their own package.
13259                        intent.setPackage(callerApp.info.packageName);
13260                    }
13261                }
13262            } catch (RemoteException e) {
13263                Slog.w(TAG, "Remote exception", e);
13264                return ActivityManager.BROADCAST_SUCCESS;
13265            }
13266        }
13267
13268        // Handle special intents: if this broadcast is from the package
13269        // manager about a package being removed, we need to remove all of
13270        // its activities from the history stack.
13271        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13272                intent.getAction());
13273        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13274                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13275                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13276                || uidRemoved) {
13277            if (checkComponentPermission(
13278                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13279                    callingPid, callingUid, -1, true)
13280                    == PackageManager.PERMISSION_GRANTED) {
13281                if (uidRemoved) {
13282                    final Bundle intentExtras = intent.getExtras();
13283                    final int uid = intentExtras != null
13284                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13285                    if (uid >= 0) {
13286                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13287                        synchronized (bs) {
13288                            bs.removeUidStatsLocked(uid);
13289                        }
13290                        mAppOpsService.uidRemoved(uid);
13291                    }
13292                } else {
13293                    // If resources are unavailable just force stop all
13294                    // those packages and flush the attribute cache as well.
13295                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13296                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13297                        if (list != null && (list.length > 0)) {
13298                            for (String pkg : list) {
13299                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
13300                                        "storage unmount");
13301                            }
13302                            sendPackageBroadcastLocked(
13303                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13304                        }
13305                    } else {
13306                        Uri data = intent.getData();
13307                        String ssp;
13308                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13309                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13310                                    intent.getAction());
13311                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13312                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13313                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13314                                        false, userId, removed ? "pkg removed" : "pkg changed");
13315                            }
13316                            if (removed) {
13317                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13318                                        new String[] {ssp}, userId);
13319                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13320                                    mAppOpsService.packageRemoved(
13321                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13322
13323                                    // Remove all permissions granted from/to this package
13324                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13325                                }
13326                            }
13327                        }
13328                    }
13329                }
13330            } else {
13331                String msg = "Permission Denial: " + intent.getAction()
13332                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13333                        + ", uid=" + callingUid + ")"
13334                        + " requires "
13335                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13336                Slog.w(TAG, msg);
13337                throw new SecurityException(msg);
13338            }
13339
13340        // Special case for adding a package: by default turn on compatibility
13341        // mode.
13342        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13343            Uri data = intent.getData();
13344            String ssp;
13345            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13346                mCompatModePackages.handlePackageAddedLocked(ssp,
13347                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13348            }
13349        }
13350
13351        /*
13352         * If this is the time zone changed action, queue up a message that will reset the timezone
13353         * of all currently running processes. This message will get queued up before the broadcast
13354         * happens.
13355         */
13356        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13357            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13358        }
13359
13360        /*
13361         * If the user set the time, let all running processes know.
13362         */
13363        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13364            final int is24Hour = intent.getBooleanExtra(
13365                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13366            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13367        }
13368
13369        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13370            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13371        }
13372
13373        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13374            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13375            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13376        }
13377
13378        // Add to the sticky list if requested.
13379        if (sticky) {
13380            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13381                    callingPid, callingUid)
13382                    != PackageManager.PERMISSION_GRANTED) {
13383                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13384                        + callingPid + ", uid=" + callingUid
13385                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13386                Slog.w(TAG, msg);
13387                throw new SecurityException(msg);
13388            }
13389            if (requiredPermission != null) {
13390                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13391                        + " and enforce permission " + requiredPermission);
13392                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13393            }
13394            if (intent.getComponent() != null) {
13395                throw new SecurityException(
13396                        "Sticky broadcasts can't target a specific component");
13397            }
13398            // We use userId directly here, since the "all" target is maintained
13399            // as a separate set of sticky broadcasts.
13400            if (userId != UserHandle.USER_ALL) {
13401                // But first, if this is not a broadcast to all users, then
13402                // make sure it doesn't conflict with an existing broadcast to
13403                // all users.
13404                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13405                        UserHandle.USER_ALL);
13406                if (stickies != null) {
13407                    ArrayList<Intent> list = stickies.get(intent.getAction());
13408                    if (list != null) {
13409                        int N = list.size();
13410                        int i;
13411                        for (i=0; i<N; i++) {
13412                            if (intent.filterEquals(list.get(i))) {
13413                                throw new IllegalArgumentException(
13414                                        "Sticky broadcast " + intent + " for user "
13415                                        + userId + " conflicts with existing global broadcast");
13416                            }
13417                        }
13418                    }
13419                }
13420            }
13421            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13422            if (stickies == null) {
13423                stickies = new ArrayMap<String, ArrayList<Intent>>();
13424                mStickyBroadcasts.put(userId, stickies);
13425            }
13426            ArrayList<Intent> list = stickies.get(intent.getAction());
13427            if (list == null) {
13428                list = new ArrayList<Intent>();
13429                stickies.put(intent.getAction(), list);
13430            }
13431            int N = list.size();
13432            int i;
13433            for (i=0; i<N; i++) {
13434                if (intent.filterEquals(list.get(i))) {
13435                    // This sticky already exists, replace it.
13436                    list.set(i, new Intent(intent));
13437                    break;
13438                }
13439            }
13440            if (i >= N) {
13441                list.add(new Intent(intent));
13442            }
13443        }
13444
13445        int[] users;
13446        if (userId == UserHandle.USER_ALL) {
13447            // Caller wants broadcast to go to all started users.
13448            users = mStartedUserArray;
13449        } else {
13450            // Caller wants broadcast to go to one specific user.
13451            users = new int[] {userId};
13452        }
13453
13454        // Figure out who all will receive this broadcast.
13455        List receivers = null;
13456        List<BroadcastFilter> registeredReceivers = null;
13457        // Need to resolve the intent to interested receivers...
13458        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13459                 == 0) {
13460            receivers = collectReceiverComponents(intent, resolvedType, users);
13461        }
13462        if (intent.getComponent() == null) {
13463            registeredReceivers = mReceiverResolver.queryIntent(intent,
13464                    resolvedType, false, userId);
13465        }
13466
13467        final boolean replacePending =
13468                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13469
13470        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13471                + " replacePending=" + replacePending);
13472
13473        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13474        if (!ordered && NR > 0) {
13475            // If we are not serializing this broadcast, then send the
13476            // registered receivers separately so they don't wait for the
13477            // components to be launched.
13478            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13479            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13480                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13481                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13482                    ordered, sticky, false, userId);
13483            if (DEBUG_BROADCAST) Slog.v(
13484                    TAG, "Enqueueing parallel broadcast " + r);
13485            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13486            if (!replaced) {
13487                queue.enqueueParallelBroadcastLocked(r);
13488                queue.scheduleBroadcastsLocked();
13489            }
13490            registeredReceivers = null;
13491            NR = 0;
13492        }
13493
13494        // Merge into one list.
13495        int ir = 0;
13496        if (receivers != null) {
13497            // A special case for PACKAGE_ADDED: do not allow the package
13498            // being added to see this broadcast.  This prevents them from
13499            // using this as a back door to get run as soon as they are
13500            // installed.  Maybe in the future we want to have a special install
13501            // broadcast or such for apps, but we'd like to deliberately make
13502            // this decision.
13503            String skipPackages[] = null;
13504            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13505                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13506                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13507                Uri data = intent.getData();
13508                if (data != null) {
13509                    String pkgName = data.getSchemeSpecificPart();
13510                    if (pkgName != null) {
13511                        skipPackages = new String[] { pkgName };
13512                    }
13513                }
13514            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13515                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13516            }
13517            if (skipPackages != null && (skipPackages.length > 0)) {
13518                for (String skipPackage : skipPackages) {
13519                    if (skipPackage != null) {
13520                        int NT = receivers.size();
13521                        for (int it=0; it<NT; it++) {
13522                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13523                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13524                                receivers.remove(it);
13525                                it--;
13526                                NT--;
13527                            }
13528                        }
13529                    }
13530                }
13531            }
13532
13533            int NT = receivers != null ? receivers.size() : 0;
13534            int it = 0;
13535            ResolveInfo curt = null;
13536            BroadcastFilter curr = null;
13537            while (it < NT && ir < NR) {
13538                if (curt == null) {
13539                    curt = (ResolveInfo)receivers.get(it);
13540                }
13541                if (curr == null) {
13542                    curr = registeredReceivers.get(ir);
13543                }
13544                if (curr.getPriority() >= curt.priority) {
13545                    // Insert this broadcast record into the final list.
13546                    receivers.add(it, curr);
13547                    ir++;
13548                    curr = null;
13549                    it++;
13550                    NT++;
13551                } else {
13552                    // Skip to the next ResolveInfo in the final list.
13553                    it++;
13554                    curt = null;
13555                }
13556            }
13557        }
13558        while (ir < NR) {
13559            if (receivers == null) {
13560                receivers = new ArrayList();
13561            }
13562            receivers.add(registeredReceivers.get(ir));
13563            ir++;
13564        }
13565
13566        if ((receivers != null && receivers.size() > 0)
13567                || resultTo != null) {
13568            BroadcastQueue queue = broadcastQueueForIntent(intent);
13569            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13570                    callerPackage, callingPid, callingUid, resolvedType,
13571                    requiredPermission, appOp, receivers, resultTo, resultCode,
13572                    resultData, map, ordered, sticky, false, userId);
13573            if (DEBUG_BROADCAST) Slog.v(
13574                    TAG, "Enqueueing ordered broadcast " + r
13575                    + ": prev had " + queue.mOrderedBroadcasts.size());
13576            if (DEBUG_BROADCAST) {
13577                int seq = r.intent.getIntExtra("seq", -1);
13578                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13579            }
13580            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13581            if (!replaced) {
13582                queue.enqueueOrderedBroadcastLocked(r);
13583                queue.scheduleBroadcastsLocked();
13584            }
13585        }
13586
13587        return ActivityManager.BROADCAST_SUCCESS;
13588    }
13589
13590    final Intent verifyBroadcastLocked(Intent intent) {
13591        // Refuse possible leaked file descriptors
13592        if (intent != null && intent.hasFileDescriptors() == true) {
13593            throw new IllegalArgumentException("File descriptors passed in Intent");
13594        }
13595
13596        int flags = intent.getFlags();
13597
13598        if (!mProcessesReady) {
13599            // if the caller really truly claims to know what they're doing, go
13600            // ahead and allow the broadcast without launching any receivers
13601            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13602                intent = new Intent(intent);
13603                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13604            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13605                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13606                        + " before boot completion");
13607                throw new IllegalStateException("Cannot broadcast before boot completed");
13608            }
13609        }
13610
13611        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13612            throw new IllegalArgumentException(
13613                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13614        }
13615
13616        return intent;
13617    }
13618
13619    public final int broadcastIntent(IApplicationThread caller,
13620            Intent intent, String resolvedType, IIntentReceiver resultTo,
13621            int resultCode, String resultData, Bundle map,
13622            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13623        enforceNotIsolatedCaller("broadcastIntent");
13624        synchronized(this) {
13625            intent = verifyBroadcastLocked(intent);
13626
13627            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13628            final int callingPid = Binder.getCallingPid();
13629            final int callingUid = Binder.getCallingUid();
13630            final long origId = Binder.clearCallingIdentity();
13631            int res = broadcastIntentLocked(callerApp,
13632                    callerApp != null ? callerApp.info.packageName : null,
13633                    intent, resolvedType, resultTo,
13634                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13635                    callingPid, callingUid, userId);
13636            Binder.restoreCallingIdentity(origId);
13637            return res;
13638        }
13639    }
13640
13641    int broadcastIntentInPackage(String packageName, int uid,
13642            Intent intent, String resolvedType, IIntentReceiver resultTo,
13643            int resultCode, String resultData, Bundle map,
13644            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13645        synchronized(this) {
13646            intent = verifyBroadcastLocked(intent);
13647
13648            final long origId = Binder.clearCallingIdentity();
13649            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13650                    resultTo, resultCode, resultData, map, requiredPermission,
13651                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13652            Binder.restoreCallingIdentity(origId);
13653            return res;
13654        }
13655    }
13656
13657    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13658        // Refuse possible leaked file descriptors
13659        if (intent != null && intent.hasFileDescriptors() == true) {
13660            throw new IllegalArgumentException("File descriptors passed in Intent");
13661        }
13662
13663        userId = handleIncomingUser(Binder.getCallingPid(),
13664                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13665
13666        synchronized(this) {
13667            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13668                    != PackageManager.PERMISSION_GRANTED) {
13669                String msg = "Permission Denial: unbroadcastIntent() from pid="
13670                        + Binder.getCallingPid()
13671                        + ", uid=" + Binder.getCallingUid()
13672                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13673                Slog.w(TAG, msg);
13674                throw new SecurityException(msg);
13675            }
13676            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13677            if (stickies != null) {
13678                ArrayList<Intent> list = stickies.get(intent.getAction());
13679                if (list != null) {
13680                    int N = list.size();
13681                    int i;
13682                    for (i=0; i<N; i++) {
13683                        if (intent.filterEquals(list.get(i))) {
13684                            list.remove(i);
13685                            break;
13686                        }
13687                    }
13688                    if (list.size() <= 0) {
13689                        stickies.remove(intent.getAction());
13690                    }
13691                }
13692                if (stickies.size() <= 0) {
13693                    mStickyBroadcasts.remove(userId);
13694                }
13695            }
13696        }
13697    }
13698
13699    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13700            String resultData, Bundle resultExtras, boolean resultAbort) {
13701        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13702        if (r == null) {
13703            Slog.w(TAG, "finishReceiver called but not found on queue");
13704            return false;
13705        }
13706
13707        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13708    }
13709
13710    void backgroundServicesFinishedLocked(int userId) {
13711        for (BroadcastQueue queue : mBroadcastQueues) {
13712            queue.backgroundServicesFinishedLocked(userId);
13713        }
13714    }
13715
13716    public void finishReceiver(IBinder who, int resultCode, String resultData,
13717            Bundle resultExtras, boolean resultAbort) {
13718        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13719
13720        // Refuse possible leaked file descriptors
13721        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13722            throw new IllegalArgumentException("File descriptors passed in Bundle");
13723        }
13724
13725        final long origId = Binder.clearCallingIdentity();
13726        try {
13727            boolean doNext = false;
13728            BroadcastRecord r;
13729
13730            synchronized(this) {
13731                r = broadcastRecordForReceiverLocked(who);
13732                if (r != null) {
13733                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13734                        resultData, resultExtras, resultAbort, true);
13735                }
13736            }
13737
13738            if (doNext) {
13739                r.queue.processNextBroadcast(false);
13740            }
13741            trimApplications();
13742        } finally {
13743            Binder.restoreCallingIdentity(origId);
13744        }
13745    }
13746
13747    // =========================================================
13748    // INSTRUMENTATION
13749    // =========================================================
13750
13751    public boolean startInstrumentation(ComponentName className,
13752            String profileFile, int flags, Bundle arguments,
13753            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13754            int userId, String abiOverride) {
13755        enforceNotIsolatedCaller("startInstrumentation");
13756        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13757                userId, false, true, "startInstrumentation", null);
13758        // Refuse possible leaked file descriptors
13759        if (arguments != null && arguments.hasFileDescriptors()) {
13760            throw new IllegalArgumentException("File descriptors passed in Bundle");
13761        }
13762
13763        synchronized(this) {
13764            InstrumentationInfo ii = null;
13765            ApplicationInfo ai = null;
13766            try {
13767                ii = mContext.getPackageManager().getInstrumentationInfo(
13768                    className, STOCK_PM_FLAGS);
13769                ai = AppGlobals.getPackageManager().getApplicationInfo(
13770                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13771            } catch (PackageManager.NameNotFoundException e) {
13772            } catch (RemoteException e) {
13773            }
13774            if (ii == null) {
13775                reportStartInstrumentationFailure(watcher, className,
13776                        "Unable to find instrumentation info for: " + className);
13777                return false;
13778            }
13779            if (ai == null) {
13780                reportStartInstrumentationFailure(watcher, className,
13781                        "Unable to find instrumentation target package: " + ii.targetPackage);
13782                return false;
13783            }
13784
13785            int match = mContext.getPackageManager().checkSignatures(
13786                    ii.targetPackage, ii.packageName);
13787            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13788                String msg = "Permission Denial: starting instrumentation "
13789                        + className + " from pid="
13790                        + Binder.getCallingPid()
13791                        + ", uid=" + Binder.getCallingPid()
13792                        + " not allowed because package " + ii.packageName
13793                        + " does not have a signature matching the target "
13794                        + ii.targetPackage;
13795                reportStartInstrumentationFailure(watcher, className, msg);
13796                throw new SecurityException(msg);
13797            }
13798
13799            final long origId = Binder.clearCallingIdentity();
13800            // Instrumentation can kill and relaunch even persistent processes
13801            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId,
13802                    "start instr");
13803            ProcessRecord app = addAppLocked(ai, false, abiOverride);
13804            app.instrumentationClass = className;
13805            app.instrumentationInfo = ai;
13806            app.instrumentationProfileFile = profileFile;
13807            app.instrumentationArguments = arguments;
13808            app.instrumentationWatcher = watcher;
13809            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13810            app.instrumentationResultClass = className;
13811            Binder.restoreCallingIdentity(origId);
13812        }
13813
13814        return true;
13815    }
13816
13817    /**
13818     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13819     * error to the logs, but if somebody is watching, send the report there too.  This enables
13820     * the "am" command to report errors with more information.
13821     *
13822     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13823     * @param cn The component name of the instrumentation.
13824     * @param report The error report.
13825     */
13826    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13827            ComponentName cn, String report) {
13828        Slog.w(TAG, report);
13829        try {
13830            if (watcher != null) {
13831                Bundle results = new Bundle();
13832                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13833                results.putString("Error", report);
13834                watcher.instrumentationStatus(cn, -1, results);
13835            }
13836        } catch (RemoteException e) {
13837            Slog.w(TAG, e);
13838        }
13839    }
13840
13841    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13842        if (app.instrumentationWatcher != null) {
13843            try {
13844                // NOTE:  IInstrumentationWatcher *must* be oneway here
13845                app.instrumentationWatcher.instrumentationFinished(
13846                    app.instrumentationClass,
13847                    resultCode,
13848                    results);
13849            } catch (RemoteException e) {
13850            }
13851        }
13852        if (app.instrumentationUiAutomationConnection != null) {
13853            try {
13854                app.instrumentationUiAutomationConnection.shutdown();
13855            } catch (RemoteException re) {
13856                /* ignore */
13857            }
13858            // Only a UiAutomation can set this flag and now that
13859            // it is finished we make sure it is reset to its default.
13860            mUserIsMonkey = false;
13861        }
13862        app.instrumentationWatcher = null;
13863        app.instrumentationUiAutomationConnection = null;
13864        app.instrumentationClass = null;
13865        app.instrumentationInfo = null;
13866        app.instrumentationProfileFile = null;
13867        app.instrumentationArguments = null;
13868
13869        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId,
13870                "finished inst");
13871    }
13872
13873    public void finishInstrumentation(IApplicationThread target,
13874            int resultCode, Bundle results) {
13875        int userId = UserHandle.getCallingUserId();
13876        // Refuse possible leaked file descriptors
13877        if (results != null && results.hasFileDescriptors()) {
13878            throw new IllegalArgumentException("File descriptors passed in Intent");
13879        }
13880
13881        synchronized(this) {
13882            ProcessRecord app = getRecordForAppLocked(target);
13883            if (app == null) {
13884                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13885                return;
13886            }
13887            final long origId = Binder.clearCallingIdentity();
13888            finishInstrumentationLocked(app, resultCode, results);
13889            Binder.restoreCallingIdentity(origId);
13890        }
13891    }
13892
13893    // =========================================================
13894    // CONFIGURATION
13895    // =========================================================
13896
13897    public ConfigurationInfo getDeviceConfigurationInfo() {
13898        ConfigurationInfo config = new ConfigurationInfo();
13899        synchronized (this) {
13900            config.reqTouchScreen = mConfiguration.touchscreen;
13901            config.reqKeyboardType = mConfiguration.keyboard;
13902            config.reqNavigation = mConfiguration.navigation;
13903            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13904                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13905                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13906            }
13907            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13908                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13909                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13910            }
13911            config.reqGlEsVersion = GL_ES_VERSION;
13912        }
13913        return config;
13914    }
13915
13916    ActivityStack getFocusedStack() {
13917        return mStackSupervisor.getFocusedStack();
13918    }
13919
13920    public Configuration getConfiguration() {
13921        Configuration ci;
13922        synchronized(this) {
13923            ci = new Configuration(mConfiguration);
13924        }
13925        return ci;
13926    }
13927
13928    public void updatePersistentConfiguration(Configuration values) {
13929        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13930                "updateConfiguration()");
13931        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13932                "updateConfiguration()");
13933        if (values == null) {
13934            throw new NullPointerException("Configuration must not be null");
13935        }
13936
13937        synchronized(this) {
13938            final long origId = Binder.clearCallingIdentity();
13939            updateConfigurationLocked(values, null, true, false);
13940            Binder.restoreCallingIdentity(origId);
13941        }
13942    }
13943
13944    public void updateConfiguration(Configuration values) {
13945        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13946                "updateConfiguration()");
13947
13948        synchronized(this) {
13949            if (values == null && mWindowManager != null) {
13950                // sentinel: fetch the current configuration from the window manager
13951                values = mWindowManager.computeNewConfiguration();
13952            }
13953
13954            if (mWindowManager != null) {
13955                mProcessList.applyDisplaySize(mWindowManager);
13956            }
13957
13958            final long origId = Binder.clearCallingIdentity();
13959            if (values != null) {
13960                Settings.System.clearConfiguration(values);
13961            }
13962            updateConfigurationLocked(values, null, false, false);
13963            Binder.restoreCallingIdentity(origId);
13964        }
13965    }
13966
13967    /**
13968     * Do either or both things: (1) change the current configuration, and (2)
13969     * make sure the given activity is running with the (now) current
13970     * configuration.  Returns true if the activity has been left running, or
13971     * false if <var>starting</var> is being destroyed to match the new
13972     * configuration.
13973     * @param persistent TODO
13974     */
13975    boolean updateConfigurationLocked(Configuration values,
13976            ActivityRecord starting, boolean persistent, boolean initLocale) {
13977        int changes = 0;
13978
13979        if (values != null) {
13980            Configuration newConfig = new Configuration(mConfiguration);
13981            changes = newConfig.updateFrom(values);
13982            if (changes != 0) {
13983                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13984                    Slog.i(TAG, "Updating configuration to: " + values);
13985                }
13986
13987                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13988
13989                if (values.locale != null && !initLocale) {
13990                    saveLocaleLocked(values.locale,
13991                                     !values.locale.equals(mConfiguration.locale),
13992                                     values.userSetLocale);
13993                }
13994
13995                mConfigurationSeq++;
13996                if (mConfigurationSeq <= 0) {
13997                    mConfigurationSeq = 1;
13998                }
13999                newConfig.seq = mConfigurationSeq;
14000                mConfiguration = newConfig;
14001                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14002
14003                final Configuration configCopy = new Configuration(mConfiguration);
14004
14005                // TODO: If our config changes, should we auto dismiss any currently
14006                // showing dialogs?
14007                mShowDialogs = shouldShowDialogs(newConfig);
14008
14009                AttributeCache ac = AttributeCache.instance();
14010                if (ac != null) {
14011                    ac.updateConfiguration(configCopy);
14012                }
14013
14014                // Make sure all resources in our process are updated
14015                // right now, so that anyone who is going to retrieve
14016                // resource values after we return will be sure to get
14017                // the new ones.  This is especially important during
14018                // boot, where the first config change needs to guarantee
14019                // all resources have that config before following boot
14020                // code is executed.
14021                mSystemThread.applyConfigurationToResources(configCopy);
14022
14023                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14024                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14025                    msg.obj = new Configuration(configCopy);
14026                    mHandler.sendMessage(msg);
14027                }
14028
14029                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14030                    ProcessRecord app = mLruProcesses.get(i);
14031                    try {
14032                        if (app.thread != null) {
14033                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14034                                    + app.processName + " new config " + mConfiguration);
14035                            app.thread.scheduleConfigurationChanged(configCopy);
14036                        }
14037                    } catch (Exception e) {
14038                    }
14039                }
14040                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14041                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14042                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14043                        | Intent.FLAG_RECEIVER_FOREGROUND);
14044                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14045                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14046                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14047                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14048                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14049                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14050                    broadcastIntentLocked(null, null, intent,
14051                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14052                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14053                }
14054            }
14055        }
14056
14057        boolean kept = true;
14058        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14059        // mainStack is null during startup.
14060        if (mainStack != null) {
14061            if (changes != 0 && starting == null) {
14062                // If the configuration changed, and the caller is not already
14063                // in the process of starting an activity, then find the top
14064                // activity to check if its configuration needs to change.
14065                starting = mainStack.topRunningActivityLocked(null);
14066            }
14067
14068            if (starting != null) {
14069                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14070                // And we need to make sure at this point that all other activities
14071                // are made visible with the correct configuration.
14072                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14073            }
14074        }
14075
14076        if (values != null && mWindowManager != null) {
14077            mWindowManager.setNewConfiguration(mConfiguration);
14078        }
14079
14080        return kept;
14081    }
14082
14083    /**
14084     * Decide based on the configuration whether we should shouw the ANR,
14085     * crash, etc dialogs.  The idea is that if there is no affordnace to
14086     * press the on-screen buttons, we shouldn't show the dialog.
14087     *
14088     * A thought: SystemUI might also want to get told about this, the Power
14089     * dialog / global actions also might want different behaviors.
14090     */
14091    private static final boolean shouldShowDialogs(Configuration config) {
14092        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14093                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14094    }
14095
14096    /**
14097     * Save the locale.  You must be inside a synchronized (this) block.
14098     */
14099    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14100        if(isDiff) {
14101            SystemProperties.set("user.language", l.getLanguage());
14102            SystemProperties.set("user.region", l.getCountry());
14103        }
14104
14105        if(isPersist) {
14106            SystemProperties.set("persist.sys.language", l.getLanguage());
14107            SystemProperties.set("persist.sys.country", l.getCountry());
14108            SystemProperties.set("persist.sys.localevar", l.getVariant());
14109        }
14110    }
14111
14112    @Override
14113    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14114        ActivityRecord srec = ActivityRecord.forToken(token);
14115        return srec != null && srec.task.affinity != null &&
14116                srec.task.affinity.equals(destAffinity);
14117    }
14118
14119    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14120            Intent resultData) {
14121
14122        synchronized (this) {
14123            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14124            if (stack != null) {
14125                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14126            }
14127            return false;
14128        }
14129    }
14130
14131    public int getLaunchedFromUid(IBinder activityToken) {
14132        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14133        if (srec == null) {
14134            return -1;
14135        }
14136        return srec.launchedFromUid;
14137    }
14138
14139    public String getLaunchedFromPackage(IBinder activityToken) {
14140        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14141        if (srec == null) {
14142            return null;
14143        }
14144        return srec.launchedFromPackage;
14145    }
14146
14147    // =========================================================
14148    // LIFETIME MANAGEMENT
14149    // =========================================================
14150
14151    // Returns which broadcast queue the app is the current [or imminent] receiver
14152    // on, or 'null' if the app is not an active broadcast recipient.
14153    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14154        BroadcastRecord r = app.curReceiver;
14155        if (r != null) {
14156            return r.queue;
14157        }
14158
14159        // It's not the current receiver, but it might be starting up to become one
14160        synchronized (this) {
14161            for (BroadcastQueue queue : mBroadcastQueues) {
14162                r = queue.mPendingBroadcast;
14163                if (r != null && r.curApp == app) {
14164                    // found it; report which queue it's in
14165                    return queue;
14166                }
14167            }
14168        }
14169
14170        return null;
14171    }
14172
14173    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14174            boolean doingAll, long now) {
14175        if (mAdjSeq == app.adjSeq) {
14176            // This adjustment has already been computed.
14177            return app.curRawAdj;
14178        }
14179
14180        if (app.thread == null) {
14181            app.adjSeq = mAdjSeq;
14182            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14183            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14184            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14185        }
14186
14187        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14188        app.adjSource = null;
14189        app.adjTarget = null;
14190        app.empty = false;
14191        app.cached = false;
14192
14193        final int activitiesSize = app.activities.size();
14194
14195        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14196            // The max adjustment doesn't allow this app to be anything
14197            // below foreground, so it is not worth doing work for it.
14198            app.adjType = "fixed";
14199            app.adjSeq = mAdjSeq;
14200            app.curRawAdj = app.maxAdj;
14201            app.foregroundActivities = false;
14202            app.keeping = true;
14203            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14204            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14205            // System process can do UI, and when they do we want to have
14206            // them trim their memory after the user leaves the UI.  To
14207            // facilitate this, here we need to determine whether or not it
14208            // is currently showing UI.
14209            app.systemNoUi = true;
14210            if (app == TOP_APP) {
14211                app.systemNoUi = false;
14212            } else if (activitiesSize > 0) {
14213                for (int j = 0; j < activitiesSize; j++) {
14214                    final ActivityRecord r = app.activities.get(j);
14215                    if (r.visible) {
14216                        app.systemNoUi = false;
14217                    }
14218                }
14219            }
14220            if (!app.systemNoUi) {
14221                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14222            }
14223            return (app.curAdj=app.maxAdj);
14224        }
14225
14226        app.keeping = false;
14227        app.systemNoUi = false;
14228
14229        // Determine the importance of the process, starting with most
14230        // important to least, and assign an appropriate OOM adjustment.
14231        int adj;
14232        int schedGroup;
14233        int procState;
14234        boolean foregroundActivities = false;
14235        boolean interesting = false;
14236        BroadcastQueue queue;
14237        if (app == TOP_APP) {
14238            // The last app on the list is the foreground app.
14239            adj = ProcessList.FOREGROUND_APP_ADJ;
14240            schedGroup = Process.THREAD_GROUP_DEFAULT;
14241            app.adjType = "top-activity";
14242            foregroundActivities = true;
14243            interesting = true;
14244            procState = ActivityManager.PROCESS_STATE_TOP;
14245        } else if (app.instrumentationClass != null) {
14246            // Don't want to kill running instrumentation.
14247            adj = ProcessList.FOREGROUND_APP_ADJ;
14248            schedGroup = Process.THREAD_GROUP_DEFAULT;
14249            app.adjType = "instrumentation";
14250            interesting = true;
14251            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14252        } else if ((queue = isReceivingBroadcast(app)) != null) {
14253            // An app that is currently receiving a broadcast also
14254            // counts as being in the foreground for OOM killer purposes.
14255            // It's placed in a sched group based on the nature of the
14256            // broadcast as reflected by which queue it's active in.
14257            adj = ProcessList.FOREGROUND_APP_ADJ;
14258            schedGroup = (queue == mFgBroadcastQueue)
14259                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14260            app.adjType = "broadcast";
14261            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14262        } else if (app.executingServices.size() > 0) {
14263            // An app that is currently executing a service callback also
14264            // counts as being in the foreground.
14265            adj = ProcessList.FOREGROUND_APP_ADJ;
14266            schedGroup = app.execServicesFg ?
14267                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14268            app.adjType = "exec-service";
14269            procState = ActivityManager.PROCESS_STATE_SERVICE;
14270            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14271        } else {
14272            // As far as we know the process is empty.  We may change our mind later.
14273            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14274            // At this point we don't actually know the adjustment.  Use the cached adj
14275            // value that the caller wants us to.
14276            adj = cachedAdj;
14277            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14278            app.cached = true;
14279            app.empty = true;
14280            app.adjType = "cch-empty";
14281        }
14282
14283        // Examine all activities if not already foreground.
14284        if (!foregroundActivities && activitiesSize > 0) {
14285            for (int j = 0; j < activitiesSize; j++) {
14286                final ActivityRecord r = app.activities.get(j);
14287                if (r.app != app) {
14288                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14289                            + app + "?!?");
14290                    continue;
14291                }
14292                if (r.visible) {
14293                    // App has a visible activity; only upgrade adjustment.
14294                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14295                        adj = ProcessList.VISIBLE_APP_ADJ;
14296                        app.adjType = "visible";
14297                    }
14298                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14299                        procState = ActivityManager.PROCESS_STATE_TOP;
14300                    }
14301                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14302                    app.cached = false;
14303                    app.empty = false;
14304                    foregroundActivities = true;
14305                    break;
14306                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14307                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14308                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14309                        app.adjType = "pausing";
14310                    }
14311                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14312                        procState = ActivityManager.PROCESS_STATE_TOP;
14313                    }
14314                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14315                    app.cached = false;
14316                    app.empty = false;
14317                    foregroundActivities = true;
14318                } else if (r.state == ActivityState.STOPPING) {
14319                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14320                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14321                        app.adjType = "stopping";
14322                    }
14323                    // For the process state, we will at this point consider the
14324                    // process to be cached.  It will be cached either as an activity
14325                    // or empty depending on whether the activity is finishing.  We do
14326                    // this so that we can treat the process as cached for purposes of
14327                    // memory trimming (determing current memory level, trim command to
14328                    // send to process) since there can be an arbitrary number of stopping
14329                    // processes and they should soon all go into the cached state.
14330                    if (!r.finishing) {
14331                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14332                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14333                        }
14334                    }
14335                    app.cached = false;
14336                    app.empty = false;
14337                    foregroundActivities = true;
14338                } else {
14339                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14340                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14341                        app.adjType = "cch-act";
14342                    }
14343                }
14344            }
14345        }
14346
14347        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14348            if (app.foregroundServices) {
14349                // The user is aware of this app, so make it visible.
14350                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14351                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14352                app.cached = false;
14353                app.adjType = "fg-service";
14354                schedGroup = Process.THREAD_GROUP_DEFAULT;
14355            } else if (app.forcingToForeground != null) {
14356                // The user is aware of this app, so make it visible.
14357                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14358                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14359                app.cached = false;
14360                app.adjType = "force-fg";
14361                app.adjSource = app.forcingToForeground;
14362                schedGroup = Process.THREAD_GROUP_DEFAULT;
14363            }
14364        }
14365
14366        if (app.foregroundServices) {
14367            interesting = true;
14368        }
14369
14370        if (app == mHeavyWeightProcess) {
14371            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14372                // We don't want to kill the current heavy-weight process.
14373                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14374                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14375                app.cached = false;
14376                app.adjType = "heavy";
14377            }
14378            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14379                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14380            }
14381        }
14382
14383        if (app == mHomeProcess) {
14384            if (adj > ProcessList.HOME_APP_ADJ) {
14385                // This process is hosting what we currently consider to be the
14386                // home app, so we don't want to let it go into the background.
14387                adj = ProcessList.HOME_APP_ADJ;
14388                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14389                app.cached = false;
14390                app.adjType = "home";
14391            }
14392            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14393                procState = ActivityManager.PROCESS_STATE_HOME;
14394            }
14395        }
14396
14397        if (app == mPreviousProcess && app.activities.size() > 0) {
14398            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14399                // This was the previous process that showed UI to the user.
14400                // We want to try to keep it around more aggressively, to give
14401                // a good experience around switching between two apps.
14402                adj = ProcessList.PREVIOUS_APP_ADJ;
14403                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14404                app.cached = false;
14405                app.adjType = "previous";
14406            }
14407            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14408                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14409            }
14410        }
14411
14412        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14413                + " reason=" + app.adjType);
14414
14415        // By default, we use the computed adjustment.  It may be changed if
14416        // there are applications dependent on our services or providers, but
14417        // this gives us a baseline and makes sure we don't get into an
14418        // infinite recursion.
14419        app.adjSeq = mAdjSeq;
14420        app.curRawAdj = adj;
14421        app.hasStartedServices = false;
14422
14423        if (mBackupTarget != null && app == mBackupTarget.app) {
14424            // If possible we want to avoid killing apps while they're being backed up
14425            if (adj > ProcessList.BACKUP_APP_ADJ) {
14426                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14427                adj = ProcessList.BACKUP_APP_ADJ;
14428                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14429                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14430                }
14431                app.adjType = "backup";
14432                app.cached = false;
14433            }
14434            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14435                procState = ActivityManager.PROCESS_STATE_BACKUP;
14436            }
14437        }
14438
14439        boolean mayBeTop = false;
14440
14441        for (int is = app.services.size()-1;
14442                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14443                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14444                        || procState > ActivityManager.PROCESS_STATE_TOP);
14445                is--) {
14446            ServiceRecord s = app.services.valueAt(is);
14447            if (s.startRequested) {
14448                app.hasStartedServices = true;
14449                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14450                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14451                }
14452                if (app.hasShownUi && app != mHomeProcess) {
14453                    // If this process has shown some UI, let it immediately
14454                    // go to the LRU list because it may be pretty heavy with
14455                    // UI stuff.  We'll tag it with a label just to help
14456                    // debug and understand what is going on.
14457                    if (adj > ProcessList.SERVICE_ADJ) {
14458                        app.adjType = "cch-started-ui-services";
14459                    }
14460                } else {
14461                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14462                        // This service has seen some activity within
14463                        // recent memory, so we will keep its process ahead
14464                        // of the background processes.
14465                        if (adj > ProcessList.SERVICE_ADJ) {
14466                            adj = ProcessList.SERVICE_ADJ;
14467                            app.adjType = "started-services";
14468                            app.cached = false;
14469                        }
14470                    }
14471                    // If we have let the service slide into the background
14472                    // state, still have some text describing what it is doing
14473                    // even though the service no longer has an impact.
14474                    if (adj > ProcessList.SERVICE_ADJ) {
14475                        app.adjType = "cch-started-services";
14476                    }
14477                }
14478                // Don't kill this process because it is doing work; it
14479                // has said it is doing work.
14480                app.keeping = true;
14481            }
14482            for (int conni = s.connections.size()-1;
14483                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14484                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14485                            || procState > ActivityManager.PROCESS_STATE_TOP);
14486                    conni--) {
14487                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14488                for (int i = 0;
14489                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14490                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14491                                || procState > ActivityManager.PROCESS_STATE_TOP);
14492                        i++) {
14493                    // XXX should compute this based on the max of
14494                    // all connected clients.
14495                    ConnectionRecord cr = clist.get(i);
14496                    if (cr.binding.client == app) {
14497                        // Binding to ourself is not interesting.
14498                        continue;
14499                    }
14500                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14501                        ProcessRecord client = cr.binding.client;
14502                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14503                                TOP_APP, doingAll, now);
14504                        int clientProcState = client.curProcState;
14505                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14506                            // If the other app is cached for any reason, for purposes here
14507                            // we are going to consider it empty.  The specific cached state
14508                            // doesn't propagate except under certain conditions.
14509                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14510                        }
14511                        String adjType = null;
14512                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14513                            // Not doing bind OOM management, so treat
14514                            // this guy more like a started service.
14515                            if (app.hasShownUi && app != mHomeProcess) {
14516                                // If this process has shown some UI, let it immediately
14517                                // go to the LRU list because it may be pretty heavy with
14518                                // UI stuff.  We'll tag it with a label just to help
14519                                // debug and understand what is going on.
14520                                if (adj > clientAdj) {
14521                                    adjType = "cch-bound-ui-services";
14522                                }
14523                                app.cached = false;
14524                                clientAdj = adj;
14525                                clientProcState = procState;
14526                            } else {
14527                                if (now >= (s.lastActivity
14528                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14529                                    // This service has not seen activity within
14530                                    // recent memory, so allow it to drop to the
14531                                    // LRU list if there is no other reason to keep
14532                                    // it around.  We'll also tag it with a label just
14533                                    // to help debug and undertand what is going on.
14534                                    if (adj > clientAdj) {
14535                                        adjType = "cch-bound-services";
14536                                    }
14537                                    clientAdj = adj;
14538                                }
14539                            }
14540                        }
14541                        if (adj > clientAdj) {
14542                            // If this process has recently shown UI, and
14543                            // the process that is binding to it is less
14544                            // important than being visible, then we don't
14545                            // care about the binding as much as we care
14546                            // about letting this process get into the LRU
14547                            // list to be killed and restarted if needed for
14548                            // memory.
14549                            if (app.hasShownUi && app != mHomeProcess
14550                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14551                                adjType = "cch-bound-ui-services";
14552                            } else {
14553                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14554                                        |Context.BIND_IMPORTANT)) != 0) {
14555                                    adj = clientAdj;
14556                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14557                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14558                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14559                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14560                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14561                                    adj = clientAdj;
14562                                } else {
14563                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14564                                        adj = ProcessList.VISIBLE_APP_ADJ;
14565                                    }
14566                                }
14567                                if (!client.cached) {
14568                                    app.cached = false;
14569                                }
14570                                if (client.keeping) {
14571                                    app.keeping = true;
14572                                }
14573                                adjType = "service";
14574                            }
14575                        }
14576                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14577                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14578                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14579                            }
14580                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14581                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14582                                    // Special handling of clients who are in the top state.
14583                                    // We *may* want to consider this process to be in the
14584                                    // top state as well, but only if there is not another
14585                                    // reason for it to be running.  Being on the top is a
14586                                    // special state, meaning you are specifically running
14587                                    // for the current top app.  If the process is already
14588                                    // running in the background for some other reason, it
14589                                    // is more important to continue considering it to be
14590                                    // in the background state.
14591                                    mayBeTop = true;
14592                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14593                                } else {
14594                                    // Special handling for above-top states (persistent
14595                                    // processes).  These should not bring the current process
14596                                    // into the top state, since they are not on top.  Instead
14597                                    // give them the best state after that.
14598                                    clientProcState =
14599                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14600                                }
14601                            }
14602                        } else {
14603                            if (clientProcState <
14604                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14605                                clientProcState =
14606                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14607                            }
14608                        }
14609                        if (procState > clientProcState) {
14610                            procState = clientProcState;
14611                        }
14612                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14613                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14614                            app.pendingUiClean = true;
14615                        }
14616                        if (adjType != null) {
14617                            app.adjType = adjType;
14618                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14619                                    .REASON_SERVICE_IN_USE;
14620                            app.adjSource = cr.binding.client;
14621                            app.adjSourceOom = clientAdj;
14622                            app.adjTarget = s.name;
14623                        }
14624                    }
14625                    final ActivityRecord a = cr.activity;
14626                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14627                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14628                                (a.visible || a.state == ActivityState.RESUMED
14629                                 || a.state == ActivityState.PAUSING)) {
14630                            adj = ProcessList.FOREGROUND_APP_ADJ;
14631                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14632                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14633                            }
14634                            app.cached = false;
14635                            app.adjType = "service";
14636                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14637                                    .REASON_SERVICE_IN_USE;
14638                            app.adjSource = a;
14639                            app.adjSourceOom = adj;
14640                            app.adjTarget = s.name;
14641                        }
14642                    }
14643                }
14644            }
14645        }
14646
14647        for (int provi = app.pubProviders.size()-1;
14648                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14649                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14650                        || procState > ActivityManager.PROCESS_STATE_TOP);
14651                provi--) {
14652            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14653            for (int i = cpr.connections.size()-1;
14654                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14655                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14656                            || procState > ActivityManager.PROCESS_STATE_TOP);
14657                    i--) {
14658                ContentProviderConnection conn = cpr.connections.get(i);
14659                ProcessRecord client = conn.client;
14660                if (client == app) {
14661                    // Being our own client is not interesting.
14662                    continue;
14663                }
14664                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14665                int clientProcState = client.curProcState;
14666                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14667                    // If the other app is cached for any reason, for purposes here
14668                    // we are going to consider it empty.
14669                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14670                }
14671                if (adj > clientAdj) {
14672                    if (app.hasShownUi && app != mHomeProcess
14673                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14674                        app.adjType = "cch-ui-provider";
14675                    } else {
14676                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14677                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14678                        app.adjType = "provider";
14679                    }
14680                    app.cached &= client.cached;
14681                    app.keeping |= client.keeping;
14682                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14683                            .REASON_PROVIDER_IN_USE;
14684                    app.adjSource = client;
14685                    app.adjSourceOom = clientAdj;
14686                    app.adjTarget = cpr.name;
14687                }
14688                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14689                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14690                        // Special handling of clients who are in the top state.
14691                        // We *may* want to consider this process to be in the
14692                        // top state as well, but only if there is not another
14693                        // reason for it to be running.  Being on the top is a
14694                        // special state, meaning you are specifically running
14695                        // for the current top app.  If the process is already
14696                        // running in the background for some other reason, it
14697                        // is more important to continue considering it to be
14698                        // in the background state.
14699                        mayBeTop = true;
14700                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14701                    } else {
14702                        // Special handling for above-top states (persistent
14703                        // processes).  These should not bring the current process
14704                        // into the top state, since they are not on top.  Instead
14705                        // give them the best state after that.
14706                        clientProcState =
14707                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14708                    }
14709                }
14710                if (procState > clientProcState) {
14711                    procState = clientProcState;
14712                }
14713                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14714                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14715                }
14716            }
14717            // If the provider has external (non-framework) process
14718            // dependencies, ensure that its adjustment is at least
14719            // FOREGROUND_APP_ADJ.
14720            if (cpr.hasExternalProcessHandles()) {
14721                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14722                    adj = ProcessList.FOREGROUND_APP_ADJ;
14723                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14724                    app.cached = false;
14725                    app.keeping = true;
14726                    app.adjType = "provider";
14727                    app.adjTarget = cpr.name;
14728                }
14729                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14730                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14731                }
14732            }
14733        }
14734
14735        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14736            // A client of one of our services or providers is in the top state.  We
14737            // *may* want to be in the top state, but not if we are already running in
14738            // the background for some other reason.  For the decision here, we are going
14739            // to pick out a few specific states that we want to remain in when a client
14740            // is top (states that tend to be longer-term) and otherwise allow it to go
14741            // to the top state.
14742            switch (procState) {
14743                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14744                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14745                case ActivityManager.PROCESS_STATE_SERVICE:
14746                    // These all are longer-term states, so pull them up to the top
14747                    // of the background states, but not all the way to the top state.
14748                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14749                    break;
14750                default:
14751                    // Otherwise, top is a better choice, so take it.
14752                    procState = ActivityManager.PROCESS_STATE_TOP;
14753                    break;
14754            }
14755        }
14756
14757        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14758            // This is a cached process, but with client activities.  Mark it so.
14759            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14760            app.adjType = "cch-client-act";
14761        }
14762
14763        if (adj == ProcessList.SERVICE_ADJ) {
14764            if (doingAll) {
14765                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14766                mNewNumServiceProcs++;
14767                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14768                if (!app.serviceb) {
14769                    // This service isn't far enough down on the LRU list to
14770                    // normally be a B service, but if we are low on RAM and it
14771                    // is large we want to force it down since we would prefer to
14772                    // keep launcher over it.
14773                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14774                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14775                        app.serviceHighRam = true;
14776                        app.serviceb = true;
14777                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14778                    } else {
14779                        mNewNumAServiceProcs++;
14780                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14781                    }
14782                } else {
14783                    app.serviceHighRam = false;
14784                }
14785            }
14786            if (app.serviceb) {
14787                adj = ProcessList.SERVICE_B_ADJ;
14788            }
14789        }
14790
14791        app.curRawAdj = adj;
14792
14793        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14794        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14795        if (adj > app.maxAdj) {
14796            adj = app.maxAdj;
14797            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14798                schedGroup = Process.THREAD_GROUP_DEFAULT;
14799            }
14800        }
14801        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14802            app.keeping = true;
14803        }
14804
14805        // Do final modification to adj.  Everything we do between here and applying
14806        // the final setAdj must be done in this function, because we will also use
14807        // it when computing the final cached adj later.  Note that we don't need to
14808        // worry about this for max adj above, since max adj will always be used to
14809        // keep it out of the cached vaues.
14810        adj = app.modifyRawOomAdj(adj);
14811
14812        app.curProcState = procState;
14813
14814        int importance = app.memImportance;
14815        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14816            app.curAdj = adj;
14817            app.curSchedGroup = schedGroup;
14818            if (!interesting) {
14819                // For this reporting, if there is not something explicitly
14820                // interesting in this process then we will push it to the
14821                // background importance.
14822                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14823            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14824                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14825            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14826                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14827            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14828                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14829            } else if (adj >= ProcessList.SERVICE_ADJ) {
14830                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14831            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14832                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14833            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14834                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14835            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14836                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14837            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14838                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14839            } else {
14840                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14841            }
14842        }
14843
14844        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14845        if (foregroundActivities != app.foregroundActivities) {
14846            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14847        }
14848        if (changes != 0) {
14849            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14850            app.memImportance = importance;
14851            app.foregroundActivities = foregroundActivities;
14852            int i = mPendingProcessChanges.size()-1;
14853            ProcessChangeItem item = null;
14854            while (i >= 0) {
14855                item = mPendingProcessChanges.get(i);
14856                if (item.pid == app.pid) {
14857                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14858                    break;
14859                }
14860                i--;
14861            }
14862            if (i < 0) {
14863                // No existing item in pending changes; need a new one.
14864                final int NA = mAvailProcessChanges.size();
14865                if (NA > 0) {
14866                    item = mAvailProcessChanges.remove(NA-1);
14867                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14868                } else {
14869                    item = new ProcessChangeItem();
14870                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14871                }
14872                item.changes = 0;
14873                item.pid = app.pid;
14874                item.uid = app.info.uid;
14875                if (mPendingProcessChanges.size() == 0) {
14876                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14877                            "*** Enqueueing dispatch processes changed!");
14878                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14879                }
14880                mPendingProcessChanges.add(item);
14881            }
14882            item.changes |= changes;
14883            item.importance = importance;
14884            item.foregroundActivities = foregroundActivities;
14885            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14886                    + Integer.toHexString(System.identityHashCode(item))
14887                    + " " + app.toShortString() + ": changes=" + item.changes
14888                    + " importance=" + item.importance
14889                    + " foreground=" + item.foregroundActivities
14890                    + " type=" + app.adjType + " source=" + app.adjSource
14891                    + " target=" + app.adjTarget);
14892        }
14893
14894        return app.curRawAdj;
14895    }
14896
14897    /**
14898     * Schedule PSS collection of a process.
14899     */
14900    void requestPssLocked(ProcessRecord proc, int procState) {
14901        if (mPendingPssProcesses.contains(proc)) {
14902            return;
14903        }
14904        if (mPendingPssProcesses.size() == 0) {
14905            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14906        }
14907        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
14908        proc.pssProcState = procState;
14909        mPendingPssProcesses.add(proc);
14910    }
14911
14912    /**
14913     * Schedule PSS collection of all processes.
14914     */
14915    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
14916        if (!always) {
14917            if (now < (mLastFullPssTime +
14918                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
14919                return;
14920            }
14921        }
14922        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
14923        mLastFullPssTime = now;
14924        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
14925        mPendingPssProcesses.clear();
14926        for (int i=mLruProcesses.size()-1; i>=0; i--) {
14927            ProcessRecord app = mLruProcesses.get(i);
14928            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
14929                app.pssProcState = app.setProcState;
14930                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
14931                        mSleeping, now);
14932                mPendingPssProcesses.add(app);
14933            }
14934        }
14935        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14936    }
14937
14938    /**
14939     * Ask a given process to GC right now.
14940     */
14941    final void performAppGcLocked(ProcessRecord app) {
14942        try {
14943            app.lastRequestedGc = SystemClock.uptimeMillis();
14944            if (app.thread != null) {
14945                if (app.reportLowMemory) {
14946                    app.reportLowMemory = false;
14947                    app.thread.scheduleLowMemory();
14948                } else {
14949                    app.thread.processInBackground();
14950                }
14951            }
14952        } catch (Exception e) {
14953            // whatever.
14954        }
14955    }
14956
14957    /**
14958     * Returns true if things are idle enough to perform GCs.
14959     */
14960    private final boolean canGcNowLocked() {
14961        boolean processingBroadcasts = false;
14962        for (BroadcastQueue q : mBroadcastQueues) {
14963            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14964                processingBroadcasts = true;
14965            }
14966        }
14967        return !processingBroadcasts
14968                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
14969    }
14970
14971    /**
14972     * Perform GCs on all processes that are waiting for it, but only
14973     * if things are idle.
14974     */
14975    final void performAppGcsLocked() {
14976        final int N = mProcessesToGc.size();
14977        if (N <= 0) {
14978            return;
14979        }
14980        if (canGcNowLocked()) {
14981            while (mProcessesToGc.size() > 0) {
14982                ProcessRecord proc = mProcessesToGc.remove(0);
14983                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
14984                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14985                            <= SystemClock.uptimeMillis()) {
14986                        // To avoid spamming the system, we will GC processes one
14987                        // at a time, waiting a few seconds between each.
14988                        performAppGcLocked(proc);
14989                        scheduleAppGcsLocked();
14990                        return;
14991                    } else {
14992                        // It hasn't been long enough since we last GCed this
14993                        // process...  put it in the list to wait for its time.
14994                        addProcessToGcListLocked(proc);
14995                        break;
14996                    }
14997                }
14998            }
14999
15000            scheduleAppGcsLocked();
15001        }
15002    }
15003
15004    /**
15005     * If all looks good, perform GCs on all processes waiting for them.
15006     */
15007    final void performAppGcsIfAppropriateLocked() {
15008        if (canGcNowLocked()) {
15009            performAppGcsLocked();
15010            return;
15011        }
15012        // Still not idle, wait some more.
15013        scheduleAppGcsLocked();
15014    }
15015
15016    /**
15017     * Schedule the execution of all pending app GCs.
15018     */
15019    final void scheduleAppGcsLocked() {
15020        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15021
15022        if (mProcessesToGc.size() > 0) {
15023            // Schedule a GC for the time to the next process.
15024            ProcessRecord proc = mProcessesToGc.get(0);
15025            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15026
15027            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15028            long now = SystemClock.uptimeMillis();
15029            if (when < (now+GC_TIMEOUT)) {
15030                when = now + GC_TIMEOUT;
15031            }
15032            mHandler.sendMessageAtTime(msg, when);
15033        }
15034    }
15035
15036    /**
15037     * Add a process to the array of processes waiting to be GCed.  Keeps the
15038     * list in sorted order by the last GC time.  The process can't already be
15039     * on the list.
15040     */
15041    final void addProcessToGcListLocked(ProcessRecord proc) {
15042        boolean added = false;
15043        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15044            if (mProcessesToGc.get(i).lastRequestedGc <
15045                    proc.lastRequestedGc) {
15046                added = true;
15047                mProcessesToGc.add(i+1, proc);
15048                break;
15049            }
15050        }
15051        if (!added) {
15052            mProcessesToGc.add(0, proc);
15053        }
15054    }
15055
15056    /**
15057     * Set up to ask a process to GC itself.  This will either do it
15058     * immediately, or put it on the list of processes to gc the next
15059     * time things are idle.
15060     */
15061    final void scheduleAppGcLocked(ProcessRecord app) {
15062        long now = SystemClock.uptimeMillis();
15063        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15064            return;
15065        }
15066        if (!mProcessesToGc.contains(app)) {
15067            addProcessToGcListLocked(app);
15068            scheduleAppGcsLocked();
15069        }
15070    }
15071
15072    final void checkExcessivePowerUsageLocked(boolean doKills) {
15073        updateCpuStatsNow();
15074
15075        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15076        boolean doWakeKills = doKills;
15077        boolean doCpuKills = doKills;
15078        if (mLastPowerCheckRealtime == 0) {
15079            doWakeKills = false;
15080        }
15081        if (mLastPowerCheckUptime == 0) {
15082            doCpuKills = false;
15083        }
15084        if (stats.isScreenOn()) {
15085            doWakeKills = false;
15086        }
15087        final long curRealtime = SystemClock.elapsedRealtime();
15088        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15089        final long curUptime = SystemClock.uptimeMillis();
15090        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15091        mLastPowerCheckRealtime = curRealtime;
15092        mLastPowerCheckUptime = curUptime;
15093        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15094            doWakeKills = false;
15095        }
15096        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15097            doCpuKills = false;
15098        }
15099        int i = mLruProcesses.size();
15100        while (i > 0) {
15101            i--;
15102            ProcessRecord app = mLruProcesses.get(i);
15103            if (!app.keeping) {
15104                long wtime;
15105                synchronized (stats) {
15106                    wtime = stats.getProcessWakeTime(app.info.uid,
15107                            app.pid, curRealtime);
15108                }
15109                long wtimeUsed = wtime - app.lastWakeTime;
15110                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15111                if (DEBUG_POWER) {
15112                    StringBuilder sb = new StringBuilder(128);
15113                    sb.append("Wake for ");
15114                    app.toShortString(sb);
15115                    sb.append(": over ");
15116                    TimeUtils.formatDuration(realtimeSince, sb);
15117                    sb.append(" used ");
15118                    TimeUtils.formatDuration(wtimeUsed, sb);
15119                    sb.append(" (");
15120                    sb.append((wtimeUsed*100)/realtimeSince);
15121                    sb.append("%)");
15122                    Slog.i(TAG, sb.toString());
15123                    sb.setLength(0);
15124                    sb.append("CPU for ");
15125                    app.toShortString(sb);
15126                    sb.append(": over ");
15127                    TimeUtils.formatDuration(uptimeSince, sb);
15128                    sb.append(" used ");
15129                    TimeUtils.formatDuration(cputimeUsed, sb);
15130                    sb.append(" (");
15131                    sb.append((cputimeUsed*100)/uptimeSince);
15132                    sb.append("%)");
15133                    Slog.i(TAG, sb.toString());
15134                }
15135                // If a process has held a wake lock for more
15136                // than 50% of the time during this period,
15137                // that sounds bad.  Kill!
15138                if (doWakeKills && realtimeSince > 0
15139                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15140                    synchronized (stats) {
15141                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15142                                realtimeSince, wtimeUsed);
15143                    }
15144                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15145                            + " during " + realtimeSince);
15146                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15147                } else if (doCpuKills && uptimeSince > 0
15148                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15149                    synchronized (stats) {
15150                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15151                                uptimeSince, cputimeUsed);
15152                    }
15153                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15154                            + " during " + uptimeSince);
15155                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15156                } else {
15157                    app.lastWakeTime = wtime;
15158                    app.lastCpuTime = app.curCpuTime;
15159                }
15160            }
15161        }
15162    }
15163
15164    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15165            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15166        boolean success = true;
15167
15168        if (app.curRawAdj != app.setRawAdj) {
15169            if (wasKeeping && !app.keeping) {
15170                // This app is no longer something we want to keep.  Note
15171                // its current wake lock time to later know to kill it if
15172                // it is not behaving well.
15173                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15174                synchronized (stats) {
15175                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15176                            app.pid, SystemClock.elapsedRealtime());
15177                }
15178                app.lastCpuTime = app.curCpuTime;
15179            }
15180
15181            app.setRawAdj = app.curRawAdj;
15182        }
15183
15184        if (app.curAdj != app.setAdj) {
15185            ProcessList.setOomAdj(app.pid, app.curAdj);
15186            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15187                TAG, "Set " + app.pid + " " + app.processName +
15188                " adj " + app.curAdj + ": " + app.adjType);
15189            app.setAdj = app.curAdj;
15190        }
15191
15192        if (app.setSchedGroup != app.curSchedGroup) {
15193            app.setSchedGroup = app.curSchedGroup;
15194            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15195                    "Setting process group of " + app.processName
15196                    + " to " + app.curSchedGroup);
15197            if (app.waitingToKill != null &&
15198                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15199                killUnneededProcessLocked(app, app.waitingToKill);
15200                success = false;
15201            } else {
15202                if (true) {
15203                    long oldId = Binder.clearCallingIdentity();
15204                    try {
15205                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15206                    } catch (Exception e) {
15207                        Slog.w(TAG, "Failed setting process group of " + app.pid
15208                                + " to " + app.curSchedGroup);
15209                        e.printStackTrace();
15210                    } finally {
15211                        Binder.restoreCallingIdentity(oldId);
15212                    }
15213                } else {
15214                    if (app.thread != null) {
15215                        try {
15216                            app.thread.setSchedulingGroup(app.curSchedGroup);
15217                        } catch (RemoteException e) {
15218                        }
15219                    }
15220                }
15221                Process.setSwappiness(app.pid,
15222                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15223            }
15224        }
15225        if (app.repProcState != app.curProcState) {
15226            app.repProcState = app.curProcState;
15227            if (!reportingProcessState && app.thread != null) {
15228                try {
15229                    if (false) {
15230                        //RuntimeException h = new RuntimeException("here");
15231                        Slog.i(TAG, "Sending new process state " + app.repProcState
15232                                + " to " + app /*, h*/);
15233                    }
15234                    app.thread.setProcessState(app.repProcState);
15235                } catch (RemoteException e) {
15236                }
15237            }
15238        }
15239        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15240                app.setProcState)) {
15241            app.lastStateTime = now;
15242            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15243                    mSleeping, now);
15244            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15245                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15246                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15247                    + (app.nextPssTime-now) + ": " + app);
15248        } else {
15249            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15250                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15251                requestPssLocked(app, app.setProcState);
15252                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15253                        mSleeping, now);
15254            } else if (false && DEBUG_PSS) {
15255                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15256            }
15257        }
15258        if (app.setProcState != app.curProcState) {
15259            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15260                    "Proc state change of " + app.processName
15261                    + " to " + app.curProcState);
15262            app.setProcState = app.curProcState;
15263            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15264                app.notCachedSinceIdle = false;
15265            }
15266            if (!doingAll) {
15267                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15268            } else {
15269                app.procStateChanged = true;
15270            }
15271        }
15272        return success;
15273    }
15274
15275    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15276        if (proc.thread != null && proc.baseProcessTracker != null) {
15277            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15278        }
15279    }
15280
15281    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15282            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15283        if (app.thread == null) {
15284            return false;
15285        }
15286
15287        final boolean wasKeeping = app.keeping;
15288
15289        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15290
15291        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15292                reportingProcessState, now);
15293    }
15294
15295    private final ActivityRecord resumedAppLocked() {
15296        return mStackSupervisor.resumedAppLocked();
15297    }
15298
15299    final boolean updateOomAdjLocked(ProcessRecord app) {
15300        return updateOomAdjLocked(app, false);
15301    }
15302
15303    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15304        final ActivityRecord TOP_ACT = resumedAppLocked();
15305        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15306        final boolean wasCached = app.cached;
15307
15308        mAdjSeq++;
15309
15310        // This is the desired cached adjusment we want to tell it to use.
15311        // If our app is currently cached, we know it, and that is it.  Otherwise,
15312        // we don't know it yet, and it needs to now be cached we will then
15313        // need to do a complete oom adj.
15314        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15315                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15316        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15317                SystemClock.uptimeMillis());
15318        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15319            // Changed to/from cached state, so apps after it in the LRU
15320            // list may also be changed.
15321            updateOomAdjLocked();
15322        }
15323        return success;
15324    }
15325
15326    final void updateOomAdjLocked() {
15327        final ActivityRecord TOP_ACT = resumedAppLocked();
15328        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15329        final long now = SystemClock.uptimeMillis();
15330        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15331        final int N = mLruProcesses.size();
15332
15333        if (false) {
15334            RuntimeException e = new RuntimeException();
15335            e.fillInStackTrace();
15336            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15337        }
15338
15339        mAdjSeq++;
15340        mNewNumServiceProcs = 0;
15341        mNewNumAServiceProcs = 0;
15342
15343        final int emptyProcessLimit;
15344        final int cachedProcessLimit;
15345        if (mProcessLimit <= 0) {
15346            emptyProcessLimit = cachedProcessLimit = 0;
15347        } else if (mProcessLimit == 1) {
15348            emptyProcessLimit = 1;
15349            cachedProcessLimit = 0;
15350        } else {
15351            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15352            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15353        }
15354
15355        // Let's determine how many processes we have running vs.
15356        // how many slots we have for background processes; we may want
15357        // to put multiple processes in a slot of there are enough of
15358        // them.
15359        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15360                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15361        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15362        if (numEmptyProcs > cachedProcessLimit) {
15363            // If there are more empty processes than our limit on cached
15364            // processes, then use the cached process limit for the factor.
15365            // This ensures that the really old empty processes get pushed
15366            // down to the bottom, so if we are running low on memory we will
15367            // have a better chance at keeping around more cached processes
15368            // instead of a gazillion empty processes.
15369            numEmptyProcs = cachedProcessLimit;
15370        }
15371        int emptyFactor = numEmptyProcs/numSlots;
15372        if (emptyFactor < 1) emptyFactor = 1;
15373        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15374        if (cachedFactor < 1) cachedFactor = 1;
15375        int stepCached = 0;
15376        int stepEmpty = 0;
15377        int numCached = 0;
15378        int numEmpty = 0;
15379        int numTrimming = 0;
15380
15381        mNumNonCachedProcs = 0;
15382        mNumCachedHiddenProcs = 0;
15383
15384        // First update the OOM adjustment for each of the
15385        // application processes based on their current state.
15386        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15387        int nextCachedAdj = curCachedAdj+1;
15388        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15389        int nextEmptyAdj = curEmptyAdj+2;
15390        for (int i=N-1; i>=0; i--) {
15391            ProcessRecord app = mLruProcesses.get(i);
15392            if (!app.killedByAm && app.thread != null) {
15393                app.procStateChanged = false;
15394                final boolean wasKeeping = app.keeping;
15395                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15396
15397                // If we haven't yet assigned the final cached adj
15398                // to the process, do that now.
15399                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15400                    switch (app.curProcState) {
15401                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15402                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15403                            // This process is a cached process holding activities...
15404                            // assign it the next cached value for that type, and then
15405                            // step that cached level.
15406                            app.curRawAdj = curCachedAdj;
15407                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15408                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15409                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15410                                    + ")");
15411                            if (curCachedAdj != nextCachedAdj) {
15412                                stepCached++;
15413                                if (stepCached >= cachedFactor) {
15414                                    stepCached = 0;
15415                                    curCachedAdj = nextCachedAdj;
15416                                    nextCachedAdj += 2;
15417                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15418                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15419                                    }
15420                                }
15421                            }
15422                            break;
15423                        default:
15424                            // For everything else, assign next empty cached process
15425                            // level and bump that up.  Note that this means that
15426                            // long-running services that have dropped down to the
15427                            // cached level will be treated as empty (since their process
15428                            // state is still as a service), which is what we want.
15429                            app.curRawAdj = curEmptyAdj;
15430                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15431                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15432                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15433                                    + ")");
15434                            if (curEmptyAdj != nextEmptyAdj) {
15435                                stepEmpty++;
15436                                if (stepEmpty >= emptyFactor) {
15437                                    stepEmpty = 0;
15438                                    curEmptyAdj = nextEmptyAdj;
15439                                    nextEmptyAdj += 2;
15440                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15441                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15442                                    }
15443                                }
15444                            }
15445                            break;
15446                    }
15447                }
15448
15449                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15450
15451                // Count the number of process types.
15452                switch (app.curProcState) {
15453                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15454                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15455                        mNumCachedHiddenProcs++;
15456                        numCached++;
15457                        if (numCached > cachedProcessLimit) {
15458                            killUnneededProcessLocked(app, "cached #" + numCached);
15459                        }
15460                        break;
15461                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15462                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15463                                && app.lastActivityTime < oldTime) {
15464                            killUnneededProcessLocked(app, "empty for "
15465                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15466                                    / 1000) + "s");
15467                        } else {
15468                            numEmpty++;
15469                            if (numEmpty > emptyProcessLimit) {
15470                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15471                            }
15472                        }
15473                        break;
15474                    default:
15475                        mNumNonCachedProcs++;
15476                        break;
15477                }
15478
15479                if (app.isolated && app.services.size() <= 0) {
15480                    // If this is an isolated process, and there are no
15481                    // services running in it, then the process is no longer
15482                    // needed.  We agressively kill these because we can by
15483                    // definition not re-use the same process again, and it is
15484                    // good to avoid having whatever code was running in them
15485                    // left sitting around after no longer needed.
15486                    killUnneededProcessLocked(app, "isolated not needed");
15487                }
15488
15489                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15490                        && !app.killedByAm) {
15491                    numTrimming++;
15492                }
15493            }
15494        }
15495
15496        mNumServiceProcs = mNewNumServiceProcs;
15497
15498        // Now determine the memory trimming level of background processes.
15499        // Unfortunately we need to start at the back of the list to do this
15500        // properly.  We only do this if the number of background apps we
15501        // are managing to keep around is less than half the maximum we desire;
15502        // if we are keeping a good number around, we'll let them use whatever
15503        // memory they want.
15504        final int numCachedAndEmpty = numCached + numEmpty;
15505        int memFactor;
15506        if (numCached <= ProcessList.TRIM_CACHED_APPS
15507                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15508            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15509                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15510            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15511                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15512            } else {
15513                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15514            }
15515        } else {
15516            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15517        }
15518        // We always allow the memory level to go up (better).  We only allow it to go
15519        // down if we are in a state where that is allowed, *and* the total number of processes
15520        // has gone down since last time.
15521        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15522                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15523                + " last=" + mLastNumProcesses);
15524        if (memFactor > mLastMemoryLevel) {
15525            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15526                memFactor = mLastMemoryLevel;
15527                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15528            }
15529        }
15530        mLastMemoryLevel = memFactor;
15531        mLastNumProcesses = mLruProcesses.size();
15532        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15533        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15534        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15535            if (mLowRamStartTime == 0) {
15536                mLowRamStartTime = now;
15537            }
15538            int step = 0;
15539            int fgTrimLevel;
15540            switch (memFactor) {
15541                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15542                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15543                    break;
15544                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15545                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15546                    break;
15547                default:
15548                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15549                    break;
15550            }
15551            int factor = numTrimming/3;
15552            int minFactor = 2;
15553            if (mHomeProcess != null) minFactor++;
15554            if (mPreviousProcess != null) minFactor++;
15555            if (factor < minFactor) factor = minFactor;
15556            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15557            for (int i=N-1; i>=0; i--) {
15558                ProcessRecord app = mLruProcesses.get(i);
15559                if (allChanged || app.procStateChanged) {
15560                    setProcessTrackerState(app, trackerMemFactor, now);
15561                    app.procStateChanged = false;
15562                }
15563                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15564                        && !app.killedByAm) {
15565                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15566                        try {
15567                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15568                                    "Trimming memory of " + app.processName
15569                                    + " to " + curLevel);
15570                            app.thread.scheduleTrimMemory(curLevel);
15571                        } catch (RemoteException e) {
15572                        }
15573                        if (false) {
15574                            // For now we won't do this; our memory trimming seems
15575                            // to be good enough at this point that destroying
15576                            // activities causes more harm than good.
15577                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15578                                    && app != mHomeProcess && app != mPreviousProcess) {
15579                                // Need to do this on its own message because the stack may not
15580                                // be in a consistent state at this point.
15581                                // For these apps we will also finish their activities
15582                                // to help them free memory.
15583                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15584                            }
15585                        }
15586                    }
15587                    app.trimMemoryLevel = curLevel;
15588                    step++;
15589                    if (step >= factor) {
15590                        step = 0;
15591                        switch (curLevel) {
15592                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15593                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15594                                break;
15595                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15596                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15597                                break;
15598                        }
15599                    }
15600                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15601                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15602                            && app.thread != null) {
15603                        try {
15604                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15605                                    "Trimming memory of heavy-weight " + app.processName
15606                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15607                            app.thread.scheduleTrimMemory(
15608                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15609                        } catch (RemoteException e) {
15610                        }
15611                    }
15612                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15613                } else {
15614                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15615                            || app.systemNoUi) && app.pendingUiClean) {
15616                        // If this application is now in the background and it
15617                        // had done UI, then give it the special trim level to
15618                        // have it free UI resources.
15619                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15620                        if (app.trimMemoryLevel < level && app.thread != null) {
15621                            try {
15622                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15623                                        "Trimming memory of bg-ui " + app.processName
15624                                        + " to " + level);
15625                                app.thread.scheduleTrimMemory(level);
15626                            } catch (RemoteException e) {
15627                            }
15628                        }
15629                        app.pendingUiClean = false;
15630                    }
15631                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15632                        try {
15633                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15634                                    "Trimming memory of fg " + app.processName
15635                                    + " to " + fgTrimLevel);
15636                            app.thread.scheduleTrimMemory(fgTrimLevel);
15637                        } catch (RemoteException e) {
15638                        }
15639                    }
15640                    app.trimMemoryLevel = fgTrimLevel;
15641                }
15642            }
15643        } else {
15644            if (mLowRamStartTime != 0) {
15645                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15646                mLowRamStartTime = 0;
15647            }
15648            for (int i=N-1; i>=0; i--) {
15649                ProcessRecord app = mLruProcesses.get(i);
15650                if (allChanged || app.procStateChanged) {
15651                    setProcessTrackerState(app, trackerMemFactor, now);
15652                    app.procStateChanged = false;
15653                }
15654                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15655                        || app.systemNoUi) && app.pendingUiClean) {
15656                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15657                            && app.thread != null) {
15658                        try {
15659                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15660                                    "Trimming memory of ui hidden " + app.processName
15661                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15662                            app.thread.scheduleTrimMemory(
15663                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15664                        } catch (RemoteException e) {
15665                        }
15666                    }
15667                    app.pendingUiClean = false;
15668                }
15669                app.trimMemoryLevel = 0;
15670            }
15671        }
15672
15673        if (mAlwaysFinishActivities) {
15674            // Need to do this on its own message because the stack may not
15675            // be in a consistent state at this point.
15676            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15677        }
15678
15679        if (allChanged) {
15680            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15681        }
15682
15683        if (mProcessStats.shouldWriteNowLocked(now)) {
15684            mHandler.post(new Runnable() {
15685                @Override public void run() {
15686                    synchronized (ActivityManagerService.this) {
15687                        mProcessStats.writeStateAsyncLocked();
15688                    }
15689                }
15690            });
15691        }
15692
15693        if (DEBUG_OOM_ADJ) {
15694            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15695        }
15696    }
15697
15698    final void trimApplications() {
15699        synchronized (this) {
15700            int i;
15701
15702            // First remove any unused application processes whose package
15703            // has been removed.
15704            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15705                final ProcessRecord app = mRemovedProcesses.get(i);
15706                if (app.activities.size() == 0
15707                        && app.curReceiver == null && app.services.size() == 0) {
15708                    Slog.i(
15709                        TAG, "Exiting empty application process "
15710                        + app.processName + " ("
15711                        + (app.thread != null ? app.thread.asBinder() : null)
15712                        + ")\n");
15713                    if (app.pid > 0 && app.pid != MY_PID) {
15714                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15715                                app.processName, app.setAdj, "empty");
15716                        app.killedByAm = true;
15717                        Process.killProcessQuiet(app.pid);
15718                    } else {
15719                        try {
15720                            app.thread.scheduleExit();
15721                        } catch (Exception e) {
15722                            // Ignore exceptions.
15723                        }
15724                    }
15725                    cleanUpApplicationRecordLocked(app, false, true, -1);
15726                    mRemovedProcesses.remove(i);
15727
15728                    if (app.persistent) {
15729                        if (app.persistent) {
15730                            addAppLocked(app.info, false, null /* ABI override */);
15731                        }
15732                    }
15733                }
15734            }
15735
15736            // Now update the oom adj for all processes.
15737            updateOomAdjLocked();
15738        }
15739    }
15740
15741    /** This method sends the specified signal to each of the persistent apps */
15742    public void signalPersistentProcesses(int sig) throws RemoteException {
15743        if (sig != Process.SIGNAL_USR1) {
15744            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15745        }
15746
15747        synchronized (this) {
15748            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15749                    != PackageManager.PERMISSION_GRANTED) {
15750                throw new SecurityException("Requires permission "
15751                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15752            }
15753
15754            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15755                ProcessRecord r = mLruProcesses.get(i);
15756                if (r.thread != null && r.persistent) {
15757                    Process.sendSignal(r.pid, sig);
15758                }
15759            }
15760        }
15761    }
15762
15763    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15764        if (proc == null || proc == mProfileProc) {
15765            proc = mProfileProc;
15766            path = mProfileFile;
15767            profileType = mProfileType;
15768            clearProfilerLocked();
15769        }
15770        if (proc == null) {
15771            return;
15772        }
15773        try {
15774            proc.thread.profilerControl(false, path, null, profileType);
15775        } catch (RemoteException e) {
15776            throw new IllegalStateException("Process disappeared");
15777        }
15778    }
15779
15780    private void clearProfilerLocked() {
15781        if (mProfileFd != null) {
15782            try {
15783                mProfileFd.close();
15784            } catch (IOException e) {
15785            }
15786        }
15787        mProfileApp = null;
15788        mProfileProc = null;
15789        mProfileFile = null;
15790        mProfileType = 0;
15791        mAutoStopProfiler = false;
15792    }
15793
15794    public boolean profileControl(String process, int userId, boolean start,
15795            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15796
15797        try {
15798            synchronized (this) {
15799                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15800                // its own permission.
15801                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15802                        != PackageManager.PERMISSION_GRANTED) {
15803                    throw new SecurityException("Requires permission "
15804                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15805                }
15806
15807                if (start && fd == null) {
15808                    throw new IllegalArgumentException("null fd");
15809                }
15810
15811                ProcessRecord proc = null;
15812                if (process != null) {
15813                    proc = findProcessLocked(process, userId, "profileControl");
15814                }
15815
15816                if (start && (proc == null || proc.thread == null)) {
15817                    throw new IllegalArgumentException("Unknown process: " + process);
15818                }
15819
15820                if (start) {
15821                    stopProfilerLocked(null, null, 0);
15822                    setProfileApp(proc.info, proc.processName, path, fd, false);
15823                    mProfileProc = proc;
15824                    mProfileType = profileType;
15825                    try {
15826                        fd = fd.dup();
15827                    } catch (IOException e) {
15828                        fd = null;
15829                    }
15830                    proc.thread.profilerControl(start, path, fd, profileType);
15831                    fd = null;
15832                    mProfileFd = null;
15833                } else {
15834                    stopProfilerLocked(proc, path, profileType);
15835                    if (fd != null) {
15836                        try {
15837                            fd.close();
15838                        } catch (IOException e) {
15839                        }
15840                    }
15841                }
15842
15843                return true;
15844            }
15845        } catch (RemoteException e) {
15846            throw new IllegalStateException("Process disappeared");
15847        } finally {
15848            if (fd != null) {
15849                try {
15850                    fd.close();
15851                } catch (IOException e) {
15852                }
15853            }
15854        }
15855    }
15856
15857    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15858        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15859                userId, true, true, callName, null);
15860        ProcessRecord proc = null;
15861        try {
15862            int pid = Integer.parseInt(process);
15863            synchronized (mPidsSelfLocked) {
15864                proc = mPidsSelfLocked.get(pid);
15865            }
15866        } catch (NumberFormatException e) {
15867        }
15868
15869        if (proc == null) {
15870            ArrayMap<String, SparseArray<ProcessRecord>> all
15871                    = mProcessNames.getMap();
15872            SparseArray<ProcessRecord> procs = all.get(process);
15873            if (procs != null && procs.size() > 0) {
15874                proc = procs.valueAt(0);
15875                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
15876                    for (int i=1; i<procs.size(); i++) {
15877                        ProcessRecord thisProc = procs.valueAt(i);
15878                        if (thisProc.userId == userId) {
15879                            proc = thisProc;
15880                            break;
15881                        }
15882                    }
15883                }
15884            }
15885        }
15886
15887        return proc;
15888    }
15889
15890    public boolean dumpHeap(String process, int userId, boolean managed,
15891            String path, ParcelFileDescriptor fd) throws RemoteException {
15892
15893        try {
15894            synchronized (this) {
15895                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15896                // its own permission (same as profileControl).
15897                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15898                        != PackageManager.PERMISSION_GRANTED) {
15899                    throw new SecurityException("Requires permission "
15900                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15901                }
15902
15903                if (fd == null) {
15904                    throw new IllegalArgumentException("null fd");
15905                }
15906
15907                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
15908                if (proc == null || proc.thread == null) {
15909                    throw new IllegalArgumentException("Unknown process: " + process);
15910                }
15911
15912                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15913                if (!isDebuggable) {
15914                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15915                        throw new SecurityException("Process not debuggable: " + proc);
15916                    }
15917                }
15918
15919                proc.thread.dumpHeap(managed, path, fd);
15920                fd = null;
15921                return true;
15922            }
15923        } catch (RemoteException e) {
15924            throw new IllegalStateException("Process disappeared");
15925        } finally {
15926            if (fd != null) {
15927                try {
15928                    fd.close();
15929                } catch (IOException e) {
15930                }
15931            }
15932        }
15933    }
15934
15935    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15936    public void monitor() {
15937        synchronized (this) { }
15938    }
15939
15940    void onCoreSettingsChange(Bundle settings) {
15941        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15942            ProcessRecord processRecord = mLruProcesses.get(i);
15943            try {
15944                if (processRecord.thread != null) {
15945                    processRecord.thread.setCoreSettings(settings);
15946                }
15947            } catch (RemoteException re) {
15948                /* ignore */
15949            }
15950        }
15951    }
15952
15953    // Multi-user methods
15954
15955    @Override
15956    public boolean switchUser(final int userId) {
15957        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
15958                != PackageManager.PERMISSION_GRANTED) {
15959            String msg = "Permission Denial: switchUser() from pid="
15960                    + Binder.getCallingPid()
15961                    + ", uid=" + Binder.getCallingUid()
15962                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
15963            Slog.w(TAG, msg);
15964            throw new SecurityException(msg);
15965        }
15966
15967        final long ident = Binder.clearCallingIdentity();
15968        try {
15969            synchronized (this) {
15970                final int oldUserId = mCurrentUserId;
15971                if (oldUserId == userId) {
15972                    return true;
15973                }
15974
15975                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
15976                if (userInfo == null) {
15977                    Slog.w(TAG, "No user info for user #" + userId);
15978                    return false;
15979                }
15980
15981                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
15982                        R.anim.screen_user_enter);
15983
15984                boolean needStart = false;
15985
15986                // If the user we are switching to is not currently started, then
15987                // we need to start it now.
15988                if (mStartedUsers.get(userId) == null) {
15989                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
15990                    updateStartedUserArrayLocked();
15991                    needStart = true;
15992                }
15993
15994                mCurrentUserId = userId;
15995                final Integer userIdInt = Integer.valueOf(userId);
15996                mUserLru.remove(userIdInt);
15997                mUserLru.add(userIdInt);
15998
15999                mWindowManager.setCurrentUser(userId);
16000
16001                // Once the internal notion of the active user has switched, we lock the device
16002                // with the option to show the user switcher on the keyguard.
16003                mWindowManager.lockNow(null);
16004
16005                final UserStartedState uss = mStartedUsers.get(userId);
16006
16007                // Make sure user is in the started state.  If it is currently
16008                // stopping, we need to knock that off.
16009                if (uss.mState == UserStartedState.STATE_STOPPING) {
16010                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16011                    // so we can just fairly silently bring the user back from
16012                    // the almost-dead.
16013                    uss.mState = UserStartedState.STATE_RUNNING;
16014                    updateStartedUserArrayLocked();
16015                    needStart = true;
16016                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16017                    // This means ACTION_SHUTDOWN has been sent, so we will
16018                    // need to treat this as a new boot of the user.
16019                    uss.mState = UserStartedState.STATE_BOOTING;
16020                    updateStartedUserArrayLocked();
16021                    needStart = true;
16022                }
16023
16024                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16025                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16026                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16027                        oldUserId, userId, uss));
16028                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16029                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16030                if (needStart) {
16031                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16032                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16033                            | Intent.FLAG_RECEIVER_FOREGROUND);
16034                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16035                    broadcastIntentLocked(null, null, intent,
16036                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16037                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16038                }
16039
16040                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16041                    if (userId != 0) {
16042                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16043                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16044                        broadcastIntentLocked(null, null, intent, null,
16045                                new IIntentReceiver.Stub() {
16046                                    public void performReceive(Intent intent, int resultCode,
16047                                            String data, Bundle extras, boolean ordered,
16048                                            boolean sticky, int sendingUser) {
16049                                        userInitialized(uss, userId);
16050                                    }
16051                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16052                                true, false, MY_PID, Process.SYSTEM_UID,
16053                                userId);
16054                        uss.initializing = true;
16055                    } else {
16056                        getUserManagerLocked().makeInitialized(userInfo.id);
16057                    }
16058                }
16059
16060                boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16061                if (homeInFront) {
16062                    startHomeActivityLocked(userId);
16063                } else {
16064                    mStackSupervisor.resumeTopActivitiesLocked();
16065                }
16066
16067                EventLogTags.writeAmSwitchUser(userId);
16068                getUserManagerLocked().userForeground(userId);
16069                sendUserSwitchBroadcastsLocked(oldUserId, userId);
16070                if (needStart) {
16071                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16072                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16073                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16074                    broadcastIntentLocked(null, null, intent,
16075                            null, new IIntentReceiver.Stub() {
16076                                @Override
16077                                public void performReceive(Intent intent, int resultCode, String data,
16078                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16079                                        throws RemoteException {
16080                                }
16081                            }, 0, null, null,
16082                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16083                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16084                }
16085            }
16086        } finally {
16087            Binder.restoreCallingIdentity(ident);
16088        }
16089
16090        return true;
16091    }
16092
16093    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16094        long ident = Binder.clearCallingIdentity();
16095        try {
16096            Intent intent;
16097            if (oldUserId >= 0) {
16098                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16099                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16100                        | Intent.FLAG_RECEIVER_FOREGROUND);
16101                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16102                broadcastIntentLocked(null, null, intent,
16103                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16104                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16105            }
16106            if (newUserId >= 0) {
16107                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16108                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16109                        | Intent.FLAG_RECEIVER_FOREGROUND);
16110                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16111                broadcastIntentLocked(null, null, intent,
16112                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16113                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16114                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16115                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16116                        | Intent.FLAG_RECEIVER_FOREGROUND);
16117                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16118                broadcastIntentLocked(null, null, intent,
16119                        null, null, 0, null, null,
16120                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16121                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16122            }
16123        } finally {
16124            Binder.restoreCallingIdentity(ident);
16125        }
16126    }
16127
16128    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16129            final int newUserId) {
16130        final int N = mUserSwitchObservers.beginBroadcast();
16131        if (N > 0) {
16132            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16133                int mCount = 0;
16134                @Override
16135                public void sendResult(Bundle data) throws RemoteException {
16136                    synchronized (ActivityManagerService.this) {
16137                        if (mCurUserSwitchCallback == this) {
16138                            mCount++;
16139                            if (mCount == N) {
16140                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16141                            }
16142                        }
16143                    }
16144                }
16145            };
16146            synchronized (this) {
16147                uss.switching = true;
16148                mCurUserSwitchCallback = callback;
16149            }
16150            for (int i=0; i<N; i++) {
16151                try {
16152                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16153                            newUserId, callback);
16154                } catch (RemoteException e) {
16155                }
16156            }
16157        } else {
16158            synchronized (this) {
16159                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16160            }
16161        }
16162        mUserSwitchObservers.finishBroadcast();
16163    }
16164
16165    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16166        synchronized (this) {
16167            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16168            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16169        }
16170    }
16171
16172    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16173        mCurUserSwitchCallback = null;
16174        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16175        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16176                oldUserId, newUserId, uss));
16177    }
16178
16179    void userInitialized(UserStartedState uss, int newUserId) {
16180        completeSwitchAndInitalize(uss, newUserId, true, false);
16181    }
16182
16183    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16184        completeSwitchAndInitalize(uss, newUserId, false, true);
16185    }
16186
16187    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16188            boolean clearInitializing, boolean clearSwitching) {
16189        boolean unfrozen = false;
16190        synchronized (this) {
16191            if (clearInitializing) {
16192                uss.initializing = false;
16193                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16194            }
16195            if (clearSwitching) {
16196                uss.switching = false;
16197            }
16198            if (!uss.switching && !uss.initializing) {
16199                mWindowManager.stopFreezingScreen();
16200                unfrozen = true;
16201            }
16202        }
16203        if (unfrozen) {
16204            final int N = mUserSwitchObservers.beginBroadcast();
16205            for (int i=0; i<N; i++) {
16206                try {
16207                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16208                } catch (RemoteException e) {
16209                }
16210            }
16211            mUserSwitchObservers.finishBroadcast();
16212        }
16213    }
16214
16215    void finishUserSwitch(UserStartedState uss) {
16216        synchronized (this) {
16217            if (uss.mState == UserStartedState.STATE_BOOTING
16218                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16219                uss.mState = UserStartedState.STATE_RUNNING;
16220                final int userId = uss.mHandle.getIdentifier();
16221                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16222                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16223                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16224                broadcastIntentLocked(null, null, intent,
16225                        null, null, 0, null, null,
16226                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16227                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16228            }
16229            int num = mUserLru.size();
16230            int i = 0;
16231            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16232                Integer oldUserId = mUserLru.get(i);
16233                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16234                if (oldUss == null) {
16235                    // Shouldn't happen, but be sane if it does.
16236                    mUserLru.remove(i);
16237                    num--;
16238                    continue;
16239                }
16240                if (oldUss.mState == UserStartedState.STATE_STOPPING
16241                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16242                    // This user is already stopping, doesn't count.
16243                    num--;
16244                    i++;
16245                    continue;
16246                }
16247                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16248                    // Owner and current can't be stopped, but count as running.
16249                    i++;
16250                    continue;
16251                }
16252                // This is a user to be stopped.
16253                stopUserLocked(oldUserId, null);
16254                num--;
16255                i++;
16256            }
16257        }
16258    }
16259
16260    @Override
16261    public int stopUser(final int userId, final IStopUserCallback callback) {
16262        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16263                != PackageManager.PERMISSION_GRANTED) {
16264            String msg = "Permission Denial: switchUser() from pid="
16265                    + Binder.getCallingPid()
16266                    + ", uid=" + Binder.getCallingUid()
16267                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16268            Slog.w(TAG, msg);
16269            throw new SecurityException(msg);
16270        }
16271        if (userId <= 0) {
16272            throw new IllegalArgumentException("Can't stop primary user " + userId);
16273        }
16274        synchronized (this) {
16275            return stopUserLocked(userId, callback);
16276        }
16277    }
16278
16279    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16280        if (mCurrentUserId == userId) {
16281            return ActivityManager.USER_OP_IS_CURRENT;
16282        }
16283
16284        final UserStartedState uss = mStartedUsers.get(userId);
16285        if (uss == null) {
16286            // User is not started, nothing to do...  but we do need to
16287            // callback if requested.
16288            if (callback != null) {
16289                mHandler.post(new Runnable() {
16290                    @Override
16291                    public void run() {
16292                        try {
16293                            callback.userStopped(userId);
16294                        } catch (RemoteException e) {
16295                        }
16296                    }
16297                });
16298            }
16299            return ActivityManager.USER_OP_SUCCESS;
16300        }
16301
16302        if (callback != null) {
16303            uss.mStopCallbacks.add(callback);
16304        }
16305
16306        if (uss.mState != UserStartedState.STATE_STOPPING
16307                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16308            uss.mState = UserStartedState.STATE_STOPPING;
16309            updateStartedUserArrayLocked();
16310
16311            long ident = Binder.clearCallingIdentity();
16312            try {
16313                // We are going to broadcast ACTION_USER_STOPPING and then
16314                // once that is done send a final ACTION_SHUTDOWN and then
16315                // stop the user.
16316                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16317                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16318                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16319                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16320                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16321                // This is the result receiver for the final shutdown broadcast.
16322                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16323                    @Override
16324                    public void performReceive(Intent intent, int resultCode, String data,
16325                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16326                        finishUserStop(uss);
16327                    }
16328                };
16329                // This is the result receiver for the initial stopping broadcast.
16330                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16331                    @Override
16332                    public void performReceive(Intent intent, int resultCode, String data,
16333                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16334                        // On to the next.
16335                        synchronized (ActivityManagerService.this) {
16336                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16337                                // Whoops, we are being started back up.  Abort, abort!
16338                                return;
16339                            }
16340                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16341                        }
16342                        broadcastIntentLocked(null, null, shutdownIntent,
16343                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16344                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16345                    }
16346                };
16347                // Kick things off.
16348                broadcastIntentLocked(null, null, stoppingIntent,
16349                        null, stoppingReceiver, 0, null, null,
16350                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16351                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16352            } finally {
16353                Binder.restoreCallingIdentity(ident);
16354            }
16355        }
16356
16357        return ActivityManager.USER_OP_SUCCESS;
16358    }
16359
16360    void finishUserStop(UserStartedState uss) {
16361        final int userId = uss.mHandle.getIdentifier();
16362        boolean stopped;
16363        ArrayList<IStopUserCallback> callbacks;
16364        synchronized (this) {
16365            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16366            if (mStartedUsers.get(userId) != uss) {
16367                stopped = false;
16368            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16369                stopped = false;
16370            } else {
16371                stopped = true;
16372                // User can no longer run.
16373                mStartedUsers.remove(userId);
16374                mUserLru.remove(Integer.valueOf(userId));
16375                updateStartedUserArrayLocked();
16376
16377                // Clean up all state and processes associated with the user.
16378                // Kill all the processes for the user.
16379                forceStopUserLocked(userId, "finish user");
16380            }
16381        }
16382
16383        for (int i=0; i<callbacks.size(); i++) {
16384            try {
16385                if (stopped) callbacks.get(i).userStopped(userId);
16386                else callbacks.get(i).userStopAborted(userId);
16387            } catch (RemoteException e) {
16388            }
16389        }
16390
16391        mStackSupervisor.removeUserLocked(userId);
16392    }
16393
16394    @Override
16395    public UserInfo getCurrentUser() {
16396        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16397                != PackageManager.PERMISSION_GRANTED) && (
16398                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16399                != PackageManager.PERMISSION_GRANTED)) {
16400            String msg = "Permission Denial: getCurrentUser() from pid="
16401                    + Binder.getCallingPid()
16402                    + ", uid=" + Binder.getCallingUid()
16403                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16404            Slog.w(TAG, msg);
16405            throw new SecurityException(msg);
16406        }
16407        synchronized (this) {
16408            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16409        }
16410    }
16411
16412    int getCurrentUserIdLocked() {
16413        return mCurrentUserId;
16414    }
16415
16416    @Override
16417    public boolean isUserRunning(int userId, boolean orStopped) {
16418        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16419                != PackageManager.PERMISSION_GRANTED) {
16420            String msg = "Permission Denial: isUserRunning() from pid="
16421                    + Binder.getCallingPid()
16422                    + ", uid=" + Binder.getCallingUid()
16423                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16424            Slog.w(TAG, msg);
16425            throw new SecurityException(msg);
16426        }
16427        synchronized (this) {
16428            return isUserRunningLocked(userId, orStopped);
16429        }
16430    }
16431
16432    boolean isUserRunningLocked(int userId, boolean orStopped) {
16433        UserStartedState state = mStartedUsers.get(userId);
16434        if (state == null) {
16435            return false;
16436        }
16437        if (orStopped) {
16438            return true;
16439        }
16440        return state.mState != UserStartedState.STATE_STOPPING
16441                && state.mState != UserStartedState.STATE_SHUTDOWN;
16442    }
16443
16444    @Override
16445    public int[] getRunningUserIds() {
16446        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16447                != PackageManager.PERMISSION_GRANTED) {
16448            String msg = "Permission Denial: isUserRunning() from pid="
16449                    + Binder.getCallingPid()
16450                    + ", uid=" + Binder.getCallingUid()
16451                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16452            Slog.w(TAG, msg);
16453            throw new SecurityException(msg);
16454        }
16455        synchronized (this) {
16456            return mStartedUserArray;
16457        }
16458    }
16459
16460    private void updateStartedUserArrayLocked() {
16461        int num = 0;
16462        for (int i=0; i<mStartedUsers.size();  i++) {
16463            UserStartedState uss = mStartedUsers.valueAt(i);
16464            // This list does not include stopping users.
16465            if (uss.mState != UserStartedState.STATE_STOPPING
16466                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16467                num++;
16468            }
16469        }
16470        mStartedUserArray = new int[num];
16471        num = 0;
16472        for (int i=0; i<mStartedUsers.size();  i++) {
16473            UserStartedState uss = mStartedUsers.valueAt(i);
16474            if (uss.mState != UserStartedState.STATE_STOPPING
16475                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16476                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16477                num++;
16478            }
16479        }
16480    }
16481
16482    @Override
16483    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16484        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16485                != PackageManager.PERMISSION_GRANTED) {
16486            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16487                    + Binder.getCallingPid()
16488                    + ", uid=" + Binder.getCallingUid()
16489                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16490            Slog.w(TAG, msg);
16491            throw new SecurityException(msg);
16492        }
16493
16494        mUserSwitchObservers.register(observer);
16495    }
16496
16497    @Override
16498    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16499        mUserSwitchObservers.unregister(observer);
16500    }
16501
16502    private boolean userExists(int userId) {
16503        if (userId == 0) {
16504            return true;
16505        }
16506        UserManagerService ums = getUserManagerLocked();
16507        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16508    }
16509
16510    int[] getUsersLocked() {
16511        UserManagerService ums = getUserManagerLocked();
16512        return ums != null ? ums.getUserIds() : new int[] { 0 };
16513    }
16514
16515    UserManagerService getUserManagerLocked() {
16516        if (mUserManager == null) {
16517            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16518            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16519        }
16520        return mUserManager;
16521    }
16522
16523    private int applyUserId(int uid, int userId) {
16524        return UserHandle.getUid(userId, uid);
16525    }
16526
16527    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16528        if (info == null) return null;
16529        ApplicationInfo newInfo = new ApplicationInfo(info);
16530        newInfo.uid = applyUserId(info.uid, userId);
16531        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16532                + info.packageName;
16533        return newInfo;
16534    }
16535
16536    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16537        if (aInfo == null
16538                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16539            return aInfo;
16540        }
16541
16542        ActivityInfo info = new ActivityInfo(aInfo);
16543        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16544        return info;
16545    }
16546
16547    private final class LocalService extends ActivityManagerInternal {
16548        @Override
16549        public void goingToSleep() {
16550            ActivityManagerService.this.goingToSleep();
16551        }
16552
16553        @Override
16554        public void wakingUp() {
16555            ActivityManagerService.this.wakingUp();
16556        }
16557    }
16558}
16559