ActivityManagerService.java revision dca272b8c21f2910424496b97cd9b7a558008876
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    /** Flag whether the device has a recents UI */
1084    final boolean mHasRecents;
1085
1086    final ServiceThread mHandlerThread;
1087    final MainHandler mHandler;
1088
1089    final class MainHandler extends Handler {
1090        public MainHandler(Looper looper) {
1091            super(looper, null, true);
1092        }
1093
1094        @Override
1095        public void handleMessage(Message msg) {
1096            switch (msg.what) {
1097            case SHOW_ERROR_MSG: {
1098                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1099                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1100                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1101                synchronized (ActivityManagerService.this) {
1102                    ProcessRecord proc = (ProcessRecord)data.get("app");
1103                    AppErrorResult res = (AppErrorResult) data.get("result");
1104                    if (proc != null && proc.crashDialog != null) {
1105                        Slog.e(TAG, "App already has crash dialog: " + proc);
1106                        if (res != null) {
1107                            res.set(0);
1108                        }
1109                        return;
1110                    }
1111                    if (!showBackground && UserHandle.getAppId(proc.uid)
1112                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1113                            && proc.pid != MY_PID) {
1114                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1115                        if (res != null) {
1116                            res.set(0);
1117                        }
1118                        return;
1119                    }
1120                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1121                        Dialog d = new AppErrorDialog(mContext,
1122                                ActivityManagerService.this, res, proc);
1123                        d.show();
1124                        proc.crashDialog = d;
1125                    } else {
1126                        // The device is asleep, so just pretend that the user
1127                        // saw a crash dialog and hit "force quit".
1128                        if (res != null) {
1129                            res.set(0);
1130                        }
1131                    }
1132                }
1133
1134                ensureBootCompleted();
1135            } break;
1136            case SHOW_NOT_RESPONDING_MSG: {
1137                synchronized (ActivityManagerService.this) {
1138                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1139                    ProcessRecord proc = (ProcessRecord)data.get("app");
1140                    if (proc != null && proc.anrDialog != null) {
1141                        Slog.e(TAG, "App already has anr dialog: " + proc);
1142                        return;
1143                    }
1144
1145                    Intent intent = new Intent("android.intent.action.ANR");
1146                    if (!mProcessesReady) {
1147                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1148                                | Intent.FLAG_RECEIVER_FOREGROUND);
1149                    }
1150                    broadcastIntentLocked(null, null, intent,
1151                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1152                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1153
1154                    if (mShowDialogs) {
1155                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1156                                mContext, proc, (ActivityRecord)data.get("activity"),
1157                                msg.arg1 != 0);
1158                        d.show();
1159                        proc.anrDialog = d;
1160                    } else {
1161                        // Just kill the app if there is no dialog to be shown.
1162                        killAppAtUsersRequest(proc, null);
1163                    }
1164                }
1165
1166                ensureBootCompleted();
1167            } break;
1168            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1169                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1170                synchronized (ActivityManagerService.this) {
1171                    ProcessRecord proc = (ProcessRecord) data.get("app");
1172                    if (proc == null) {
1173                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1174                        break;
1175                    }
1176                    if (proc.crashDialog != null) {
1177                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1178                        return;
1179                    }
1180                    AppErrorResult res = (AppErrorResult) data.get("result");
1181                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1182                        Dialog d = new StrictModeViolationDialog(mContext,
1183                                ActivityManagerService.this, res, proc);
1184                        d.show();
1185                        proc.crashDialog = d;
1186                    } else {
1187                        // The device is asleep, so just pretend that the user
1188                        // saw a crash dialog and hit "force quit".
1189                        res.set(0);
1190                    }
1191                }
1192                ensureBootCompleted();
1193            } break;
1194            case SHOW_FACTORY_ERROR_MSG: {
1195                Dialog d = new FactoryErrorDialog(
1196                    mContext, msg.getData().getCharSequence("msg"));
1197                d.show();
1198                ensureBootCompleted();
1199            } break;
1200            case UPDATE_CONFIGURATION_MSG: {
1201                final ContentResolver resolver = mContext.getContentResolver();
1202                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1203            } break;
1204            case GC_BACKGROUND_PROCESSES_MSG: {
1205                synchronized (ActivityManagerService.this) {
1206                    performAppGcsIfAppropriateLocked();
1207                }
1208            } break;
1209            case WAIT_FOR_DEBUGGER_MSG: {
1210                synchronized (ActivityManagerService.this) {
1211                    ProcessRecord app = (ProcessRecord)msg.obj;
1212                    if (msg.arg1 != 0) {
1213                        if (!app.waitedForDebugger) {
1214                            Dialog d = new AppWaitingForDebuggerDialog(
1215                                    ActivityManagerService.this,
1216                                    mContext, app);
1217                            app.waitDialog = d;
1218                            app.waitedForDebugger = true;
1219                            d.show();
1220                        }
1221                    } else {
1222                        if (app.waitDialog != null) {
1223                            app.waitDialog.dismiss();
1224                            app.waitDialog = null;
1225                        }
1226                    }
1227                }
1228            } break;
1229            case SERVICE_TIMEOUT_MSG: {
1230                if (mDidDexOpt) {
1231                    mDidDexOpt = false;
1232                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1233                    nmsg.obj = msg.obj;
1234                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1235                    return;
1236                }
1237                mServices.serviceTimeout((ProcessRecord)msg.obj);
1238            } break;
1239            case UPDATE_TIME_ZONE: {
1240                synchronized (ActivityManagerService.this) {
1241                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1242                        ProcessRecord r = mLruProcesses.get(i);
1243                        if (r.thread != null) {
1244                            try {
1245                                r.thread.updateTimeZone();
1246                            } catch (RemoteException ex) {
1247                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1248                            }
1249                        }
1250                    }
1251                }
1252            } break;
1253            case CLEAR_DNS_CACHE_MSG: {
1254                synchronized (ActivityManagerService.this) {
1255                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1256                        ProcessRecord r = mLruProcesses.get(i);
1257                        if (r.thread != null) {
1258                            try {
1259                                r.thread.clearDnsCache();
1260                            } catch (RemoteException ex) {
1261                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1262                            }
1263                        }
1264                    }
1265                }
1266            } break;
1267            case UPDATE_HTTP_PROXY_MSG: {
1268                ProxyProperties proxy = (ProxyProperties)msg.obj;
1269                String host = "";
1270                String port = "";
1271                String exclList = "";
1272                String pacFileUrl = null;
1273                if (proxy != null) {
1274                    host = proxy.getHost();
1275                    port = Integer.toString(proxy.getPort());
1276                    exclList = proxy.getExclusionList();
1277                    pacFileUrl = proxy.getPacFileUrl();
1278                }
1279                synchronized (ActivityManagerService.this) {
1280                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1281                        ProcessRecord r = mLruProcesses.get(i);
1282                        if (r.thread != null) {
1283                            try {
1284                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1285                            } catch (RemoteException ex) {
1286                                Slog.w(TAG, "Failed to update http proxy for: " +
1287                                        r.info.processName);
1288                            }
1289                        }
1290                    }
1291                }
1292            } break;
1293            case SHOW_UID_ERROR_MSG: {
1294                String title = "System UIDs Inconsistent";
1295                String text = "UIDs on the system are inconsistent, you need to wipe your"
1296                        + " data partition or your device will be unstable.";
1297                Log.e(TAG, title + ": " + text);
1298                if (mShowDialogs) {
1299                    // XXX This is a temporary dialog, no need to localize.
1300                    AlertDialog d = new BaseErrorDialog(mContext);
1301                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1302                    d.setCancelable(false);
1303                    d.setTitle(title);
1304                    d.setMessage(text);
1305                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1306                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1307                    mUidAlert = d;
1308                    d.show();
1309                }
1310            } break;
1311            case IM_FEELING_LUCKY_MSG: {
1312                if (mUidAlert != null) {
1313                    mUidAlert.dismiss();
1314                    mUidAlert = null;
1315                }
1316            } break;
1317            case PROC_START_TIMEOUT_MSG: {
1318                if (mDidDexOpt) {
1319                    mDidDexOpt = false;
1320                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1321                    nmsg.obj = msg.obj;
1322                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1323                    return;
1324                }
1325                ProcessRecord app = (ProcessRecord)msg.obj;
1326                synchronized (ActivityManagerService.this) {
1327                    processStartTimedOutLocked(app);
1328                }
1329            } break;
1330            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1331                synchronized (ActivityManagerService.this) {
1332                    doPendingActivityLaunchesLocked(true);
1333                }
1334            } break;
1335            case KILL_APPLICATION_MSG: {
1336                synchronized (ActivityManagerService.this) {
1337                    int appid = msg.arg1;
1338                    boolean restart = (msg.arg2 == 1);
1339                    Bundle bundle = (Bundle)msg.obj;
1340                    String pkg = bundle.getString("pkg");
1341                    String reason = bundle.getString("reason");
1342                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1343                            UserHandle.USER_ALL, reason);
1344                }
1345            } break;
1346            case FINALIZE_PENDING_INTENT_MSG: {
1347                ((PendingIntentRecord)msg.obj).completeFinalize();
1348            } break;
1349            case POST_HEAVY_NOTIFICATION_MSG: {
1350                INotificationManager inm = NotificationManager.getService();
1351                if (inm == null) {
1352                    return;
1353                }
1354
1355                ActivityRecord root = (ActivityRecord)msg.obj;
1356                ProcessRecord process = root.app;
1357                if (process == null) {
1358                    return;
1359                }
1360
1361                try {
1362                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1363                    String text = mContext.getString(R.string.heavy_weight_notification,
1364                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1365                    Notification notification = new Notification();
1366                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1367                    notification.when = 0;
1368                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1369                    notification.tickerText = text;
1370                    notification.defaults = 0; // please be quiet
1371                    notification.sound = null;
1372                    notification.vibrate = null;
1373                    notification.setLatestEventInfo(context, text,
1374                            mContext.getText(R.string.heavy_weight_notification_detail),
1375                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1376                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1377                                    new UserHandle(root.userId)));
1378
1379                    try {
1380                        int[] outId = new int[1];
1381                        inm.enqueueNotificationWithTag("android", "android", null,
1382                                R.string.heavy_weight_notification,
1383                                notification, outId, root.userId);
1384                    } catch (RuntimeException e) {
1385                        Slog.w(ActivityManagerService.TAG,
1386                                "Error showing notification for heavy-weight app", e);
1387                    } catch (RemoteException e) {
1388                    }
1389                } catch (NameNotFoundException e) {
1390                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1391                }
1392            } break;
1393            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1394                INotificationManager inm = NotificationManager.getService();
1395                if (inm == null) {
1396                    return;
1397                }
1398                try {
1399                    inm.cancelNotificationWithTag("android", null,
1400                            R.string.heavy_weight_notification,  msg.arg1);
1401                } catch (RuntimeException e) {
1402                    Slog.w(ActivityManagerService.TAG,
1403                            "Error canceling notification for service", e);
1404                } catch (RemoteException e) {
1405                }
1406            } break;
1407            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1408                synchronized (ActivityManagerService.this) {
1409                    checkExcessivePowerUsageLocked(true);
1410                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1411                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1412                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1413                }
1414            } break;
1415            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1416                synchronized (ActivityManagerService.this) {
1417                    ActivityRecord ar = (ActivityRecord)msg.obj;
1418                    if (mCompatModeDialog != null) {
1419                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1420                                ar.info.applicationInfo.packageName)) {
1421                            return;
1422                        }
1423                        mCompatModeDialog.dismiss();
1424                        mCompatModeDialog = null;
1425                    }
1426                    if (ar != null && false) {
1427                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1428                                ar.packageName)) {
1429                            int mode = mCompatModePackages.computeCompatModeLocked(
1430                                    ar.info.applicationInfo);
1431                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1432                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1433                                mCompatModeDialog = new CompatModeDialog(
1434                                        ActivityManagerService.this, mContext,
1435                                        ar.info.applicationInfo);
1436                                mCompatModeDialog.show();
1437                            }
1438                        }
1439                    }
1440                }
1441                break;
1442            }
1443            case DISPATCH_PROCESSES_CHANGED: {
1444                dispatchProcessesChanged();
1445                break;
1446            }
1447            case DISPATCH_PROCESS_DIED: {
1448                final int pid = msg.arg1;
1449                final int uid = msg.arg2;
1450                dispatchProcessDied(pid, uid);
1451                break;
1452            }
1453            case REPORT_MEM_USAGE_MSG: {
1454                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1455                Thread thread = new Thread() {
1456                    @Override public void run() {
1457                        final SparseArray<ProcessMemInfo> infoMap
1458                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1459                        for (int i=0, N=memInfos.size(); i<N; i++) {
1460                            ProcessMemInfo mi = memInfos.get(i);
1461                            infoMap.put(mi.pid, mi);
1462                        }
1463                        updateCpuStatsNow();
1464                        synchronized (mProcessCpuThread) {
1465                            final int N = mProcessCpuTracker.countStats();
1466                            for (int i=0; i<N; i++) {
1467                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1468                                if (st.vsize > 0) {
1469                                    long pss = Debug.getPss(st.pid, null);
1470                                    if (pss > 0) {
1471                                        if (infoMap.indexOfKey(st.pid) < 0) {
1472                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1473                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1474                                            mi.pss = pss;
1475                                            memInfos.add(mi);
1476                                        }
1477                                    }
1478                                }
1479                            }
1480                        }
1481
1482                        long totalPss = 0;
1483                        for (int i=0, N=memInfos.size(); i<N; i++) {
1484                            ProcessMemInfo mi = memInfos.get(i);
1485                            if (mi.pss == 0) {
1486                                mi.pss = Debug.getPss(mi.pid, null);
1487                            }
1488                            totalPss += mi.pss;
1489                        }
1490                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1491                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1492                                if (lhs.oomAdj != rhs.oomAdj) {
1493                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1494                                }
1495                                if (lhs.pss != rhs.pss) {
1496                                    return lhs.pss < rhs.pss ? 1 : -1;
1497                                }
1498                                return 0;
1499                            }
1500                        });
1501
1502                        StringBuilder tag = new StringBuilder(128);
1503                        StringBuilder stack = new StringBuilder(128);
1504                        tag.append("Low on memory -- ");
1505                        appendMemBucket(tag, totalPss, "total", false);
1506                        appendMemBucket(stack, totalPss, "total", true);
1507
1508                        StringBuilder logBuilder = new StringBuilder(1024);
1509                        logBuilder.append("Low on memory:\n");
1510
1511                        boolean firstLine = true;
1512                        int lastOomAdj = Integer.MIN_VALUE;
1513                        for (int i=0, N=memInfos.size(); i<N; i++) {
1514                            ProcessMemInfo mi = memInfos.get(i);
1515
1516                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1517                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1518                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1519                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1520                                if (lastOomAdj != mi.oomAdj) {
1521                                    lastOomAdj = mi.oomAdj;
1522                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1523                                        tag.append(" / ");
1524                                    }
1525                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1526                                        if (firstLine) {
1527                                            stack.append(":");
1528                                            firstLine = false;
1529                                        }
1530                                        stack.append("\n\t at ");
1531                                    } else {
1532                                        stack.append("$");
1533                                    }
1534                                } else {
1535                                    tag.append(" ");
1536                                    stack.append("$");
1537                                }
1538                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1539                                    appendMemBucket(tag, mi.pss, mi.name, false);
1540                                }
1541                                appendMemBucket(stack, mi.pss, mi.name, true);
1542                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1543                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1544                                    stack.append("(");
1545                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1546                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1547                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1548                                            stack.append(":");
1549                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1550                                        }
1551                                    }
1552                                    stack.append(")");
1553                                }
1554                            }
1555
1556                            logBuilder.append("  ");
1557                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1558                            logBuilder.append(' ');
1559                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1560                            logBuilder.append(' ');
1561                            ProcessList.appendRamKb(logBuilder, mi.pss);
1562                            logBuilder.append(" kB: ");
1563                            logBuilder.append(mi.name);
1564                            logBuilder.append(" (");
1565                            logBuilder.append(mi.pid);
1566                            logBuilder.append(") ");
1567                            logBuilder.append(mi.adjType);
1568                            logBuilder.append('\n');
1569                            if (mi.adjReason != null) {
1570                                logBuilder.append("                      ");
1571                                logBuilder.append(mi.adjReason);
1572                                logBuilder.append('\n');
1573                            }
1574                        }
1575
1576                        logBuilder.append("           ");
1577                        ProcessList.appendRamKb(logBuilder, totalPss);
1578                        logBuilder.append(" kB: TOTAL\n");
1579
1580                        long[] infos = new long[Debug.MEMINFO_COUNT];
1581                        Debug.getMemInfo(infos);
1582                        logBuilder.append("  MemInfo: ");
1583                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1584                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1585                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1586                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1587                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1588                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1589                            logBuilder.append("  ZRAM: ");
1590                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1591                            logBuilder.append(" kB RAM, ");
1592                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1593                            logBuilder.append(" kB swap total, ");
1594                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1595                            logBuilder.append(" kB swap free\n");
1596                        }
1597                        Slog.i(TAG, logBuilder.toString());
1598
1599                        StringBuilder dropBuilder = new StringBuilder(1024);
1600                        /*
1601                        StringWriter oomSw = new StringWriter();
1602                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1603                        StringWriter catSw = new StringWriter();
1604                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1605                        String[] emptyArgs = new String[] { };
1606                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1607                        oomPw.flush();
1608                        String oomString = oomSw.toString();
1609                        */
1610                        dropBuilder.append(stack);
1611                        dropBuilder.append('\n');
1612                        dropBuilder.append('\n');
1613                        dropBuilder.append(logBuilder);
1614                        dropBuilder.append('\n');
1615                        /*
1616                        dropBuilder.append(oomString);
1617                        dropBuilder.append('\n');
1618                        */
1619                        StringWriter catSw = new StringWriter();
1620                        synchronized (ActivityManagerService.this) {
1621                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1622                            String[] emptyArgs = new String[] { };
1623                            catPw.println();
1624                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1625                            catPw.println();
1626                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1627                                    false, false, null);
1628                            catPw.println();
1629                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1630                            catPw.flush();
1631                        }
1632                        dropBuilder.append(catSw.toString());
1633                        addErrorToDropBox("lowmem", null, "system_server", null,
1634                                null, tag.toString(), dropBuilder.toString(), null, null);
1635                        //Slog.i(TAG, "Sent to dropbox:");
1636                        //Slog.i(TAG, dropBuilder.toString());
1637                        synchronized (ActivityManagerService.this) {
1638                            long now = SystemClock.uptimeMillis();
1639                            if (mLastMemUsageReportTime < now) {
1640                                mLastMemUsageReportTime = now;
1641                            }
1642                        }
1643                    }
1644                };
1645                thread.start();
1646                break;
1647            }
1648            case REPORT_USER_SWITCH_MSG: {
1649                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1650                break;
1651            }
1652            case CONTINUE_USER_SWITCH_MSG: {
1653                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1654                break;
1655            }
1656            case USER_SWITCH_TIMEOUT_MSG: {
1657                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1658                break;
1659            }
1660            case IMMERSIVE_MODE_LOCK_MSG: {
1661                final boolean nextState = (msg.arg1 != 0);
1662                if (mUpdateLock.isHeld() != nextState) {
1663                    if (DEBUG_IMMERSIVE) {
1664                        final ActivityRecord r = (ActivityRecord) msg.obj;
1665                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1666                    }
1667                    if (nextState) {
1668                        mUpdateLock.acquire();
1669                    } else {
1670                        mUpdateLock.release();
1671                    }
1672                }
1673                break;
1674            }
1675            case PERSIST_URI_GRANTS_MSG: {
1676                writeGrantedUriPermissions();
1677                break;
1678            }
1679            case REQUEST_ALL_PSS_MSG: {
1680                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1681                break;
1682            }
1683            case UPDATE_TIME: {
1684                synchronized (ActivityManagerService.this) {
1685                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1686                        ProcessRecord r = mLruProcesses.get(i);
1687                        if (r.thread != null) {
1688                            try {
1689                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1690                            } catch (RemoteException ex) {
1691                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1692                            }
1693                        }
1694                    }
1695                }
1696
1697                break;
1698            }
1699            }
1700        }
1701    };
1702
1703    static final int COLLECT_PSS_BG_MSG = 1;
1704
1705    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1706        @Override
1707        public void handleMessage(Message msg) {
1708            switch (msg.what) {
1709            case COLLECT_PSS_BG_MSG: {
1710                int i=0, num=0;
1711                long start = SystemClock.uptimeMillis();
1712                long[] tmp = new long[1];
1713                do {
1714                    ProcessRecord proc;
1715                    int procState;
1716                    int pid;
1717                    synchronized (ActivityManagerService.this) {
1718                        if (i >= mPendingPssProcesses.size()) {
1719                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1720                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1721                            mPendingPssProcesses.clear();
1722                            return;
1723                        }
1724                        proc = mPendingPssProcesses.get(i);
1725                        procState = proc.pssProcState;
1726                        if (proc.thread != null && procState == proc.setProcState) {
1727                            pid = proc.pid;
1728                        } else {
1729                            proc = null;
1730                            pid = 0;
1731                        }
1732                        i++;
1733                    }
1734                    if (proc != null) {
1735                        long pss = Debug.getPss(pid, tmp);
1736                        synchronized (ActivityManagerService.this) {
1737                            if (proc.thread != null && proc.setProcState == procState
1738                                    && proc.pid == pid) {
1739                                num++;
1740                                proc.lastPssTime = SystemClock.uptimeMillis();
1741                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1742                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1743                                        + ": " + pss + " lastPss=" + proc.lastPss
1744                                        + " state=" + ProcessList.makeProcStateString(procState));
1745                                if (proc.initialIdlePss == 0) {
1746                                    proc.initialIdlePss = pss;
1747                                }
1748                                proc.lastPss = pss;
1749                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1750                                    proc.lastCachedPss = pss;
1751                                }
1752                            }
1753                        }
1754                    }
1755                } while (true);
1756            }
1757            }
1758        }
1759    };
1760
1761    public void setSystemProcess() {
1762        try {
1763            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1764            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1765            ServiceManager.addService("meminfo", new MemBinder(this));
1766            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1767            ServiceManager.addService("dbinfo", new DbBinder(this));
1768            if (MONITOR_CPU_USAGE) {
1769                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1770            }
1771            ServiceManager.addService("permission", new PermissionController(this));
1772
1773            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1774                    "android", STOCK_PM_FLAGS);
1775            mSystemThread.installSystemApplicationInfo(info);
1776
1777            synchronized (this) {
1778                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1779                app.persistent = true;
1780                app.pid = MY_PID;
1781                app.maxAdj = ProcessList.SYSTEM_ADJ;
1782                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1783                mProcessNames.put(app.processName, app.uid, app);
1784                synchronized (mPidsSelfLocked) {
1785                    mPidsSelfLocked.put(app.pid, app);
1786                }
1787                updateLruProcessLocked(app, false, null);
1788                updateOomAdjLocked();
1789            }
1790        } catch (PackageManager.NameNotFoundException e) {
1791            throw new RuntimeException(
1792                    "Unable to find android system package", e);
1793        }
1794    }
1795
1796    public void setWindowManager(WindowManagerService wm) {
1797        mWindowManager = wm;
1798        mStackSupervisor.setWindowManager(wm);
1799    }
1800
1801    public void startObservingNativeCrashes() {
1802        final NativeCrashListener ncl = new NativeCrashListener(this);
1803        ncl.start();
1804    }
1805
1806    public IAppOpsService getAppOpsService() {
1807        return mAppOpsService;
1808    }
1809
1810    static class MemBinder extends Binder {
1811        ActivityManagerService mActivityManagerService;
1812        MemBinder(ActivityManagerService activityManagerService) {
1813            mActivityManagerService = activityManagerService;
1814        }
1815
1816        @Override
1817        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1818            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1819                    != PackageManager.PERMISSION_GRANTED) {
1820                pw.println("Permission Denial: can't dump meminfo from from pid="
1821                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1822                        + " without permission " + android.Manifest.permission.DUMP);
1823                return;
1824            }
1825
1826            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1827        }
1828    }
1829
1830    static class GraphicsBinder extends Binder {
1831        ActivityManagerService mActivityManagerService;
1832        GraphicsBinder(ActivityManagerService activityManagerService) {
1833            mActivityManagerService = activityManagerService;
1834        }
1835
1836        @Override
1837        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1838            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1839                    != PackageManager.PERMISSION_GRANTED) {
1840                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1841                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1842                        + " without permission " + android.Manifest.permission.DUMP);
1843                return;
1844            }
1845
1846            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1847        }
1848    }
1849
1850    static class DbBinder extends Binder {
1851        ActivityManagerService mActivityManagerService;
1852        DbBinder(ActivityManagerService activityManagerService) {
1853            mActivityManagerService = activityManagerService;
1854        }
1855
1856        @Override
1857        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1858            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1859                    != PackageManager.PERMISSION_GRANTED) {
1860                pw.println("Permission Denial: can't dump dbinfo from from pid="
1861                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1862                        + " without permission " + android.Manifest.permission.DUMP);
1863                return;
1864            }
1865
1866            mActivityManagerService.dumpDbInfo(fd, pw, args);
1867        }
1868    }
1869
1870    static class CpuBinder extends Binder {
1871        ActivityManagerService mActivityManagerService;
1872        CpuBinder(ActivityManagerService activityManagerService) {
1873            mActivityManagerService = activityManagerService;
1874        }
1875
1876        @Override
1877        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1878            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1879                    != PackageManager.PERMISSION_GRANTED) {
1880                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1881                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1882                        + " without permission " + android.Manifest.permission.DUMP);
1883                return;
1884            }
1885
1886            synchronized (mActivityManagerService.mProcessCpuThread) {
1887                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1888                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1889                        SystemClock.uptimeMillis()));
1890            }
1891        }
1892    }
1893
1894    public static final class Lifecycle extends SystemService {
1895        private final ActivityManagerService mService;
1896
1897        public Lifecycle(Context context) {
1898            super(context);
1899            mService = new ActivityManagerService(context);
1900        }
1901
1902        @Override
1903        public void onStart() {
1904            mService.start();
1905        }
1906
1907        public ActivityManagerService getService() {
1908            return mService;
1909        }
1910    }
1911
1912    // Note: This method is invoked on the main thread but may need to attach various
1913    // handlers to other threads.  So take care to be explicit about the looper.
1914    public ActivityManagerService(Context systemContext) {
1915        mContext = systemContext;
1916        mFactoryTest = FactoryTest.getMode();
1917        mSystemThread = ActivityThread.currentActivityThread();
1918
1919        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1920
1921        mHandlerThread = new ServiceThread(TAG,
1922                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1923        mHandlerThread.start();
1924        mHandler = new MainHandler(mHandlerThread.getLooper());
1925
1926        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1927                "foreground", BROADCAST_FG_TIMEOUT, false);
1928        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1929                "background", BROADCAST_BG_TIMEOUT, true);
1930        mBroadcastQueues[0] = mFgBroadcastQueue;
1931        mBroadcastQueues[1] = mBgBroadcastQueue;
1932
1933        mServices = new ActiveServices(this);
1934        mProviderMap = new ProviderMap(this);
1935
1936        // TODO: Move creation of battery stats service outside of activity manager service.
1937        File dataDir = Environment.getDataDirectory();
1938        File systemDir = new File(dataDir, "system");
1939        systemDir.mkdirs();
1940        mBatteryStatsService = new BatteryStatsService(new File(
1941                systemDir, "batterystats.bin").toString(), mHandler);
1942        mBatteryStatsService.getActiveStatistics().readLocked();
1943        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1944        mOnBattery = DEBUG_POWER ? true
1945                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1946        mBatteryStatsService.getActiveStatistics().setCallback(this);
1947
1948        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1949
1950        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1951        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1952
1953        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1954
1955        // User 0 is the first and only user that runs at boot.
1956        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1957        mUserLru.add(Integer.valueOf(0));
1958        updateStartedUserArrayLocked();
1959
1960        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1961            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1962
1963        mConfiguration.setToDefaults();
1964        mConfiguration.setLocale(Locale.getDefault());
1965
1966        mConfigurationSeq = mConfiguration.seq = 1;
1967        mProcessCpuTracker.init();
1968
1969        mHasRecents = mContext.getResources().getBoolean(
1970                com.android.internal.R.bool.config_hasRecents);
1971
1972        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1973        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1974        mStackSupervisor = new ActivityStackSupervisor(this);
1975
1976        mProcessCpuThread = new Thread("CpuTracker") {
1977            @Override
1978            public void run() {
1979                while (true) {
1980                    try {
1981                        try {
1982                            synchronized(this) {
1983                                final long now = SystemClock.uptimeMillis();
1984                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1985                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1986                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1987                                //        + ", write delay=" + nextWriteDelay);
1988                                if (nextWriteDelay < nextCpuDelay) {
1989                                    nextCpuDelay = nextWriteDelay;
1990                                }
1991                                if (nextCpuDelay > 0) {
1992                                    mProcessCpuMutexFree.set(true);
1993                                    this.wait(nextCpuDelay);
1994                                }
1995                            }
1996                        } catch (InterruptedException e) {
1997                        }
1998                        updateCpuStatsNow();
1999                    } catch (Exception e) {
2000                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2001                    }
2002                }
2003            }
2004        };
2005
2006        Watchdog.getInstance().addMonitor(this);
2007        Watchdog.getInstance().addThread(mHandler);
2008    }
2009
2010    private void start() {
2011        mProcessCpuThread.start();
2012
2013        mBatteryStatsService.publish(mContext);
2014        mUsageStatsService.publish(mContext);
2015        mAppOpsService.publish(mContext);
2016
2017        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2018    }
2019
2020    @Override
2021    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2022            throws RemoteException {
2023        if (code == SYSPROPS_TRANSACTION) {
2024            // We need to tell all apps about the system property change.
2025            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2026            synchronized(this) {
2027                final int NP = mProcessNames.getMap().size();
2028                for (int ip=0; ip<NP; ip++) {
2029                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2030                    final int NA = apps.size();
2031                    for (int ia=0; ia<NA; ia++) {
2032                        ProcessRecord app = apps.valueAt(ia);
2033                        if (app.thread != null) {
2034                            procs.add(app.thread.asBinder());
2035                        }
2036                    }
2037                }
2038            }
2039
2040            int N = procs.size();
2041            for (int i=0; i<N; i++) {
2042                Parcel data2 = Parcel.obtain();
2043                try {
2044                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2045                } catch (RemoteException e) {
2046                }
2047                data2.recycle();
2048            }
2049        }
2050        try {
2051            return super.onTransact(code, data, reply, flags);
2052        } catch (RuntimeException e) {
2053            // The activity manager only throws security exceptions, so let's
2054            // log all others.
2055            if (!(e instanceof SecurityException)) {
2056                Slog.wtf(TAG, "Activity Manager Crash", e);
2057            }
2058            throw e;
2059        }
2060    }
2061
2062    void updateCpuStats() {
2063        final long now = SystemClock.uptimeMillis();
2064        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2065            return;
2066        }
2067        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2068            synchronized (mProcessCpuThread) {
2069                mProcessCpuThread.notify();
2070            }
2071        }
2072    }
2073
2074    void updateCpuStatsNow() {
2075        synchronized (mProcessCpuThread) {
2076            mProcessCpuMutexFree.set(false);
2077            final long now = SystemClock.uptimeMillis();
2078            boolean haveNewCpuStats = false;
2079
2080            if (MONITOR_CPU_USAGE &&
2081                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2082                mLastCpuTime.set(now);
2083                haveNewCpuStats = true;
2084                mProcessCpuTracker.update();
2085                //Slog.i(TAG, mProcessCpu.printCurrentState());
2086                //Slog.i(TAG, "Total CPU usage: "
2087                //        + mProcessCpu.getTotalCpuPercent() + "%");
2088
2089                // Slog the cpu usage if the property is set.
2090                if ("true".equals(SystemProperties.get("events.cpu"))) {
2091                    int user = mProcessCpuTracker.getLastUserTime();
2092                    int system = mProcessCpuTracker.getLastSystemTime();
2093                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2094                    int irq = mProcessCpuTracker.getLastIrqTime();
2095                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2096                    int idle = mProcessCpuTracker.getLastIdleTime();
2097
2098                    int total = user + system + iowait + irq + softIrq + idle;
2099                    if (total == 0) total = 1;
2100
2101                    EventLog.writeEvent(EventLogTags.CPU,
2102                            ((user+system+iowait+irq+softIrq) * 100) / total,
2103                            (user * 100) / total,
2104                            (system * 100) / total,
2105                            (iowait * 100) / total,
2106                            (irq * 100) / total,
2107                            (softIrq * 100) / total);
2108                }
2109            }
2110
2111            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2112            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2113            synchronized(bstats) {
2114                synchronized(mPidsSelfLocked) {
2115                    if (haveNewCpuStats) {
2116                        if (mOnBattery) {
2117                            int perc = bstats.startAddingCpuLocked();
2118                            int totalUTime = 0;
2119                            int totalSTime = 0;
2120                            final int N = mProcessCpuTracker.countStats();
2121                            for (int i=0; i<N; i++) {
2122                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2123                                if (!st.working) {
2124                                    continue;
2125                                }
2126                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2127                                int otherUTime = (st.rel_utime*perc)/100;
2128                                int otherSTime = (st.rel_stime*perc)/100;
2129                                totalUTime += otherUTime;
2130                                totalSTime += otherSTime;
2131                                if (pr != null) {
2132                                    BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked(
2133                                            st.name, st.pid);
2134                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2135                                            st.rel_stime-otherSTime);
2136                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2137                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2138                                } else if (st.uid >= Process.FIRST_APPLICATION_UID) {
2139                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2140                                    if (ps == null) {
2141                                        st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid,
2142                                                "(Unknown)");
2143                                    }
2144                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2145                                            st.rel_stime-otherSTime);
2146                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2147                                } else {
2148                                    BatteryStatsImpl.Uid.Proc ps =
2149                                            bstats.getProcessStatsLocked(st.name, st.pid);
2150                                    if (ps != null) {
2151                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2152                                                st.rel_stime-otherSTime);
2153                                        ps.addSpeedStepTimes(cpuSpeedTimes);
2154                                    }
2155                                }
2156                            }
2157                            bstats.finishAddingCpuLocked(perc, totalUTime,
2158                                    totalSTime, cpuSpeedTimes);
2159                        }
2160                    }
2161                }
2162
2163                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2164                    mLastWriteTime = now;
2165                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2166                }
2167            }
2168        }
2169    }
2170
2171    @Override
2172    public void batteryNeedsCpuUpdate() {
2173        updateCpuStatsNow();
2174    }
2175
2176    @Override
2177    public void batteryPowerChanged(boolean onBattery) {
2178        // When plugging in, update the CPU stats first before changing
2179        // the plug state.
2180        updateCpuStatsNow();
2181        synchronized (this) {
2182            synchronized(mPidsSelfLocked) {
2183                mOnBattery = DEBUG_POWER ? true : onBattery;
2184            }
2185        }
2186    }
2187
2188    /**
2189     * Initialize the application bind args. These are passed to each
2190     * process when the bindApplication() IPC is sent to the process. They're
2191     * lazily setup to make sure the services are running when they're asked for.
2192     */
2193    private HashMap<String, IBinder> getCommonServicesLocked() {
2194        if (mAppBindArgs == null) {
2195            mAppBindArgs = new HashMap<String, IBinder>();
2196
2197            // Setup the application init args
2198            mAppBindArgs.put("package", ServiceManager.getService("package"));
2199            mAppBindArgs.put("window", ServiceManager.getService("window"));
2200            mAppBindArgs.put(Context.ALARM_SERVICE,
2201                    ServiceManager.getService(Context.ALARM_SERVICE));
2202        }
2203        return mAppBindArgs;
2204    }
2205
2206    final void setFocusedActivityLocked(ActivityRecord r) {
2207        if (mFocusedActivity != r) {
2208            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2209            mFocusedActivity = r;
2210            mStackSupervisor.setFocusedStack(r);
2211            if (r != null) {
2212                mWindowManager.setFocusedApp(r.appToken, true);
2213            }
2214            applyUpdateLockStateLocked(r);
2215        }
2216    }
2217
2218    @Override
2219    public void setFocusedStack(int stackId) {
2220        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2221        synchronized (ActivityManagerService.this) {
2222            ActivityStack stack = mStackSupervisor.getStack(stackId);
2223            if (stack != null) {
2224                ActivityRecord r = stack.topRunningActivityLocked(null);
2225                if (r != null) {
2226                    setFocusedActivityLocked(r);
2227                }
2228            }
2229        }
2230    }
2231
2232    @Override
2233    public void notifyActivityDrawn(IBinder token) {
2234        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2235        synchronized (this) {
2236            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2237            if (r != null) {
2238                r.task.stack.notifyActivityDrawnLocked(r);
2239            }
2240        }
2241    }
2242
2243    final void applyUpdateLockStateLocked(ActivityRecord r) {
2244        // Modifications to the UpdateLock state are done on our handler, outside
2245        // the activity manager's locks.  The new state is determined based on the
2246        // state *now* of the relevant activity record.  The object is passed to
2247        // the handler solely for logging detail, not to be consulted/modified.
2248        final boolean nextState = r != null && r.immersive;
2249        mHandler.sendMessage(
2250                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2251    }
2252
2253    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2254        Message msg = Message.obtain();
2255        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2256        msg.obj = r.task.askedCompatMode ? null : r;
2257        mHandler.sendMessage(msg);
2258    }
2259
2260    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2261            String what, Object obj, ProcessRecord srcApp) {
2262        app.lastActivityTime = now;
2263
2264        if (app.activities.size() > 0) {
2265            // Don't want to touch dependent processes that are hosting activities.
2266            return index;
2267        }
2268
2269        int lrui = mLruProcesses.lastIndexOf(app);
2270        if (lrui < 0) {
2271            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2272                    + what + " " + obj + " from " + srcApp);
2273            return index;
2274        }
2275
2276        if (lrui >= index) {
2277            // Don't want to cause this to move dependent processes *back* in the
2278            // list as if they were less frequently used.
2279            return index;
2280        }
2281
2282        if (lrui >= mLruProcessActivityStart) {
2283            // Don't want to touch dependent processes that are hosting activities.
2284            return index;
2285        }
2286
2287        mLruProcesses.remove(lrui);
2288        if (index > 0) {
2289            index--;
2290        }
2291        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2292                + " in LRU list: " + app);
2293        mLruProcesses.add(index, app);
2294        return index;
2295    }
2296
2297    final void removeLruProcessLocked(ProcessRecord app) {
2298        int lrui = mLruProcesses.lastIndexOf(app);
2299        if (lrui >= 0) {
2300            if (lrui <= mLruProcessActivityStart) {
2301                mLruProcessActivityStart--;
2302            }
2303            if (lrui <= mLruProcessServiceStart) {
2304                mLruProcessServiceStart--;
2305            }
2306            mLruProcesses.remove(lrui);
2307        }
2308    }
2309
2310    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2311            ProcessRecord client) {
2312        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2313        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2314        if (!activityChange && hasActivity) {
2315            // The process has activties, so we are only going to allow activity-based
2316            // adjustments move it.  It should be kept in the front of the list with other
2317            // processes that have activities, and we don't want those to change their
2318            // order except due to activity operations.
2319            return;
2320        }
2321
2322        mLruSeq++;
2323        final long now = SystemClock.uptimeMillis();
2324        app.lastActivityTime = now;
2325
2326        // First a quick reject: if the app is already at the position we will
2327        // put it, then there is nothing to do.
2328        if (hasActivity) {
2329            final int N = mLruProcesses.size();
2330            if (N > 0 && mLruProcesses.get(N-1) == app) {
2331                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2332                return;
2333            }
2334        } else {
2335            if (mLruProcessServiceStart > 0
2336                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2337                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2338                return;
2339            }
2340        }
2341
2342        int lrui = mLruProcesses.lastIndexOf(app);
2343
2344        if (app.persistent && lrui >= 0) {
2345            // We don't care about the position of persistent processes, as long as
2346            // they are in the list.
2347            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2348            return;
2349        }
2350
2351        /* In progress: compute new position first, so we can avoid doing work
2352           if the process is not actually going to move.  Not yet working.
2353        int addIndex;
2354        int nextIndex;
2355        boolean inActivity = false, inService = false;
2356        if (hasActivity) {
2357            // Process has activities, put it at the very tipsy-top.
2358            addIndex = mLruProcesses.size();
2359            nextIndex = mLruProcessServiceStart;
2360            inActivity = true;
2361        } else if (hasService) {
2362            // Process has services, put it at the top of the service list.
2363            addIndex = mLruProcessActivityStart;
2364            nextIndex = mLruProcessServiceStart;
2365            inActivity = true;
2366            inService = true;
2367        } else  {
2368            // Process not otherwise of interest, it goes to the top of the non-service area.
2369            addIndex = mLruProcessServiceStart;
2370            if (client != null) {
2371                int clientIndex = mLruProcesses.lastIndexOf(client);
2372                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2373                        + app);
2374                if (clientIndex >= 0 && addIndex > clientIndex) {
2375                    addIndex = clientIndex;
2376                }
2377            }
2378            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2379        }
2380
2381        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2382                + mLruProcessActivityStart + "): " + app);
2383        */
2384
2385        if (lrui >= 0) {
2386            if (lrui < mLruProcessActivityStart) {
2387                mLruProcessActivityStart--;
2388            }
2389            if (lrui < mLruProcessServiceStart) {
2390                mLruProcessServiceStart--;
2391            }
2392            /*
2393            if (addIndex > lrui) {
2394                addIndex--;
2395            }
2396            if (nextIndex > lrui) {
2397                nextIndex--;
2398            }
2399            */
2400            mLruProcesses.remove(lrui);
2401        }
2402
2403        /*
2404        mLruProcesses.add(addIndex, app);
2405        if (inActivity) {
2406            mLruProcessActivityStart++;
2407        }
2408        if (inService) {
2409            mLruProcessActivityStart++;
2410        }
2411        */
2412
2413        int nextIndex;
2414        if (hasActivity) {
2415            final int N = mLruProcesses.size();
2416            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2417                // Process doesn't have activities, but has clients with
2418                // activities...  move it up, but one below the top (the top
2419                // should always have a real activity).
2420                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2421                mLruProcesses.add(N-1, app);
2422                // To keep it from spamming the LRU list (by making a bunch of clients),
2423                // we will push down any other entries owned by the app.
2424                final int uid = app.info.uid;
2425                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2426                    ProcessRecord subProc = mLruProcesses.get(i);
2427                    if (subProc.info.uid == uid) {
2428                        // We want to push this one down the list.  If the process after
2429                        // it is for the same uid, however, don't do so, because we don't
2430                        // want them internally to be re-ordered.
2431                        if (mLruProcesses.get(i-1).info.uid != uid) {
2432                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2433                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2434                            ProcessRecord tmp = mLruProcesses.get(i);
2435                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2436                            mLruProcesses.set(i-1, tmp);
2437                            i--;
2438                        }
2439                    } else {
2440                        // A gap, we can stop here.
2441                        break;
2442                    }
2443                }
2444            } else {
2445                // Process has activities, put it at the very tipsy-top.
2446                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2447                mLruProcesses.add(app);
2448            }
2449            nextIndex = mLruProcessServiceStart;
2450        } else if (hasService) {
2451            // Process has services, put it at the top of the service list.
2452            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2453            mLruProcesses.add(mLruProcessActivityStart, app);
2454            nextIndex = mLruProcessServiceStart;
2455            mLruProcessActivityStart++;
2456        } else  {
2457            // Process not otherwise of interest, it goes to the top of the non-service area.
2458            int index = mLruProcessServiceStart;
2459            if (client != null) {
2460                // If there is a client, don't allow the process to be moved up higher
2461                // in the list than that client.
2462                int clientIndex = mLruProcesses.lastIndexOf(client);
2463                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2464                        + " when updating " + app);
2465                if (clientIndex <= lrui) {
2466                    // Don't allow the client index restriction to push it down farther in the
2467                    // list than it already is.
2468                    clientIndex = lrui;
2469                }
2470                if (clientIndex >= 0 && index > clientIndex) {
2471                    index = clientIndex;
2472                }
2473            }
2474            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2475            mLruProcesses.add(index, app);
2476            nextIndex = index-1;
2477            mLruProcessActivityStart++;
2478            mLruProcessServiceStart++;
2479        }
2480
2481        // If the app is currently using a content provider or service,
2482        // bump those processes as well.
2483        for (int j=app.connections.size()-1; j>=0; j--) {
2484            ConnectionRecord cr = app.connections.valueAt(j);
2485            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2486                    && cr.binding.service.app != null
2487                    && cr.binding.service.app.lruSeq != mLruSeq
2488                    && !cr.binding.service.app.persistent) {
2489                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2490                        "service connection", cr, app);
2491            }
2492        }
2493        for (int j=app.conProviders.size()-1; j>=0; j--) {
2494            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2495            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2496                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2497                        "provider reference", cpr, app);
2498            }
2499        }
2500    }
2501
2502    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2503        if (uid == Process.SYSTEM_UID) {
2504            // The system gets to run in any process.  If there are multiple
2505            // processes with the same uid, just pick the first (this
2506            // should never happen).
2507            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2508            if (procs == null) return null;
2509            final int N = procs.size();
2510            for (int i = 0; i < N; i++) {
2511                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2512            }
2513        }
2514        ProcessRecord proc = mProcessNames.get(processName, uid);
2515        if (false && proc != null && !keepIfLarge
2516                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2517                && proc.lastCachedPss >= 4000) {
2518            // Turn this condition on to cause killing to happen regularly, for testing.
2519            if (proc.baseProcessTracker != null) {
2520                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2521            }
2522            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2523                    + "k from cached");
2524        } else if (proc != null && !keepIfLarge
2525                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2526                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2527            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2528            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2529                if (proc.baseProcessTracker != null) {
2530                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2531                }
2532                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2533                        + "k from cached");
2534            }
2535        }
2536        return proc;
2537    }
2538
2539    void ensurePackageDexOpt(String packageName) {
2540        IPackageManager pm = AppGlobals.getPackageManager();
2541        try {
2542            if (pm.performDexOpt(packageName)) {
2543                mDidDexOpt = true;
2544            }
2545        } catch (RemoteException e) {
2546        }
2547    }
2548
2549    boolean isNextTransitionForward() {
2550        int transit = mWindowManager.getPendingAppTransition();
2551        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2552                || transit == AppTransition.TRANSIT_TASK_OPEN
2553                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2554    }
2555
2556    final ProcessRecord startProcessLocked(String processName,
2557            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2558            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2559            boolean isolated, boolean keepIfLarge) {
2560        ProcessRecord app;
2561        if (!isolated) {
2562            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2563        } else {
2564            // If this is an isolated process, it can't re-use an existing process.
2565            app = null;
2566        }
2567        // We don't have to do anything more if:
2568        // (1) There is an existing application record; and
2569        // (2) The caller doesn't think it is dead, OR there is no thread
2570        //     object attached to it so we know it couldn't have crashed; and
2571        // (3) There is a pid assigned to it, so it is either starting or
2572        //     already running.
2573        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2574                + " app=" + app + " knownToBeDead=" + knownToBeDead
2575                + " thread=" + (app != null ? app.thread : null)
2576                + " pid=" + (app != null ? app.pid : -1));
2577        if (app != null && app.pid > 0) {
2578            if (!knownToBeDead || app.thread == null) {
2579                // We already have the app running, or are waiting for it to
2580                // come up (we have a pid but not yet its thread), so keep it.
2581                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2582                // If this is a new package in the process, add the package to the list
2583                app.addPackage(info.packageName, mProcessStats);
2584                return app;
2585            }
2586
2587            // An application record is attached to a previous process,
2588            // clean it up now.
2589            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2590            handleAppDiedLocked(app, true, true);
2591        }
2592
2593        String hostingNameStr = hostingName != null
2594                ? hostingName.flattenToShortString() : null;
2595
2596        if (!isolated) {
2597            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2598                // If we are in the background, then check to see if this process
2599                // is bad.  If so, we will just silently fail.
2600                if (mBadProcesses.get(info.processName, info.uid) != null) {
2601                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2602                            + "/" + info.processName);
2603                    return null;
2604                }
2605            } else {
2606                // When the user is explicitly starting a process, then clear its
2607                // crash count so that we won't make it bad until they see at
2608                // least one crash dialog again, and make the process good again
2609                // if it had been bad.
2610                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2611                        + "/" + info.processName);
2612                mProcessCrashTimes.remove(info.processName, info.uid);
2613                if (mBadProcesses.get(info.processName, info.uid) != null) {
2614                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2615                            UserHandle.getUserId(info.uid), info.uid,
2616                            info.processName);
2617                    mBadProcesses.remove(info.processName, info.uid);
2618                    if (app != null) {
2619                        app.bad = false;
2620                    }
2621                }
2622            }
2623        }
2624
2625        if (app == null) {
2626            app = newProcessRecordLocked(info, processName, isolated);
2627            if (app == null) {
2628                Slog.w(TAG, "Failed making new process record for "
2629                        + processName + "/" + info.uid + " isolated=" + isolated);
2630                return null;
2631            }
2632            mProcessNames.put(processName, app.uid, app);
2633            if (isolated) {
2634                mIsolatedProcesses.put(app.uid, app);
2635            }
2636        } else {
2637            // If this is a new package in the process, add the package to the list
2638            app.addPackage(info.packageName, mProcessStats);
2639        }
2640
2641        // If the system is not ready yet, then hold off on starting this
2642        // process until it is.
2643        if (!mProcessesReady
2644                && !isAllowedWhileBooting(info)
2645                && !allowWhileBooting) {
2646            if (!mProcessesOnHold.contains(app)) {
2647                mProcessesOnHold.add(app);
2648            }
2649            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2650            return app;
2651        }
2652
2653        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2654        return (app.pid != 0) ? app : null;
2655    }
2656
2657    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2658        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2659    }
2660
2661    private final void startProcessLocked(ProcessRecord app,
2662            String hostingType, String hostingNameStr, String abiOverride) {
2663        if (app.pid > 0 && app.pid != MY_PID) {
2664            synchronized (mPidsSelfLocked) {
2665                mPidsSelfLocked.remove(app.pid);
2666                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2667            }
2668            app.setPid(0);
2669        }
2670
2671        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2672                "startProcessLocked removing on hold: " + app);
2673        mProcessesOnHold.remove(app);
2674
2675        updateCpuStats();
2676
2677        try {
2678            int uid = app.uid;
2679
2680            int[] gids = null;
2681            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2682            if (!app.isolated) {
2683                int[] permGids = null;
2684                try {
2685                    final PackageManager pm = mContext.getPackageManager();
2686                    permGids = pm.getPackageGids(app.info.packageName);
2687
2688                    if (Environment.isExternalStorageEmulated()) {
2689                        if (pm.checkPermission(
2690                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2691                                app.info.packageName) == PERMISSION_GRANTED) {
2692                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2693                        } else {
2694                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2695                        }
2696                    }
2697                } catch (PackageManager.NameNotFoundException e) {
2698                    Slog.w(TAG, "Unable to retrieve gids", e);
2699                }
2700
2701                /*
2702                 * Add shared application and profile GIDs so applications can share some
2703                 * resources like shared libraries and access user-wide resources
2704                 */
2705                if (permGids == null) {
2706                    gids = new int[2];
2707                } else {
2708                    gids = new int[permGids.length + 2];
2709                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2710                }
2711                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2712                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2713            }
2714            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2715                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2716                        && mTopComponent != null
2717                        && app.processName.equals(mTopComponent.getPackageName())) {
2718                    uid = 0;
2719                }
2720                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2721                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2722                    uid = 0;
2723                }
2724            }
2725            int debugFlags = 0;
2726            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2727                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2728                // Also turn on CheckJNI for debuggable apps. It's quite
2729                // awkward to turn on otherwise.
2730                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2731            }
2732            // Run the app in safe mode if its manifest requests so or the
2733            // system is booted in safe mode.
2734            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2735                mSafeMode == true) {
2736                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2737            }
2738            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2739                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2740            }
2741            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2742                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2743            }
2744            if ("1".equals(SystemProperties.get("debug.assert"))) {
2745                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2746            }
2747
2748            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
2749            if (requiredAbi == null) {
2750                requiredAbi = Build.SUPPORTED_ABIS[0];
2751            }
2752
2753            // Start the process.  It will either succeed and return a result containing
2754            // the PID of the new process, or else throw a RuntimeException.
2755            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2756                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2757                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2758
2759            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2760            synchronized (bs) {
2761                if (bs.isOnBattery()) {
2762                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2763                }
2764            }
2765
2766            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2767                    UserHandle.getUserId(uid), startResult.pid, uid,
2768                    app.processName, hostingType,
2769                    hostingNameStr != null ? hostingNameStr : "");
2770
2771            if (app.persistent) {
2772                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2773            }
2774
2775            StringBuilder buf = mStringBuilder;
2776            buf.setLength(0);
2777            buf.append("Start proc ");
2778            buf.append(app.processName);
2779            buf.append(" for ");
2780            buf.append(hostingType);
2781            if (hostingNameStr != null) {
2782                buf.append(" ");
2783                buf.append(hostingNameStr);
2784            }
2785            buf.append(": pid=");
2786            buf.append(startResult.pid);
2787            buf.append(" uid=");
2788            buf.append(uid);
2789            buf.append(" gids={");
2790            if (gids != null) {
2791                for (int gi=0; gi<gids.length; gi++) {
2792                    if (gi != 0) buf.append(", ");
2793                    buf.append(gids[gi]);
2794
2795                }
2796            }
2797            buf.append("}");
2798            if (requiredAbi != null) {
2799                buf.append(" abi=");
2800                buf.append(requiredAbi);
2801            }
2802            Slog.i(TAG, buf.toString());
2803            app.setPid(startResult.pid);
2804            app.usingWrapper = startResult.usingWrapper;
2805            app.removed = false;
2806            app.killedByAm = false;
2807            synchronized (mPidsSelfLocked) {
2808                this.mPidsSelfLocked.put(startResult.pid, app);
2809                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2810                msg.obj = app;
2811                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2812                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2813            }
2814        } catch (RuntimeException e) {
2815            // XXX do better error recovery.
2816            app.setPid(0);
2817            Slog.e(TAG, "Failure starting process " + app.processName, e);
2818        }
2819    }
2820
2821    void updateUsageStats(ActivityRecord component, boolean resumed) {
2822        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2823        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2824        if (resumed) {
2825            mUsageStatsService.noteResumeComponent(component.realActivity);
2826            synchronized (stats) {
2827                stats.noteActivityResumedLocked(component.app.uid);
2828            }
2829        } else {
2830            mUsageStatsService.notePauseComponent(component.realActivity);
2831            synchronized (stats) {
2832                stats.noteActivityPausedLocked(component.app.uid);
2833            }
2834        }
2835    }
2836
2837    Intent getHomeIntent() {
2838        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2839        intent.setComponent(mTopComponent);
2840        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2841            intent.addCategory(Intent.CATEGORY_HOME);
2842        }
2843        return intent;
2844    }
2845
2846    boolean startHomeActivityLocked(int userId) {
2847        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2848                && mTopAction == null) {
2849            // We are running in factory test mode, but unable to find
2850            // the factory test app, so just sit around displaying the
2851            // error message and don't try to start anything.
2852            return false;
2853        }
2854        Intent intent = getHomeIntent();
2855        ActivityInfo aInfo =
2856            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2857        if (aInfo != null) {
2858            intent.setComponent(new ComponentName(
2859                    aInfo.applicationInfo.packageName, aInfo.name));
2860            // Don't do this if the home app is currently being
2861            // instrumented.
2862            aInfo = new ActivityInfo(aInfo);
2863            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2864            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2865                    aInfo.applicationInfo.uid, true);
2866            if (app == null || app.instrumentationClass == null) {
2867                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2868                mStackSupervisor.startHomeActivity(intent, aInfo);
2869            }
2870        }
2871
2872        return true;
2873    }
2874
2875    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2876        ActivityInfo ai = null;
2877        ComponentName comp = intent.getComponent();
2878        try {
2879            if (comp != null) {
2880                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2881            } else {
2882                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2883                        intent,
2884                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2885                            flags, userId);
2886
2887                if (info != null) {
2888                    ai = info.activityInfo;
2889                }
2890            }
2891        } catch (RemoteException e) {
2892            // ignore
2893        }
2894
2895        return ai;
2896    }
2897
2898    /**
2899     * Starts the "new version setup screen" if appropriate.
2900     */
2901    void startSetupActivityLocked() {
2902        // Only do this once per boot.
2903        if (mCheckedForSetup) {
2904            return;
2905        }
2906
2907        // We will show this screen if the current one is a different
2908        // version than the last one shown, and we are not running in
2909        // low-level factory test mode.
2910        final ContentResolver resolver = mContext.getContentResolver();
2911        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2912                Settings.Global.getInt(resolver,
2913                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2914            mCheckedForSetup = true;
2915
2916            // See if we should be showing the platform update setup UI.
2917            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2918            List<ResolveInfo> ris = mContext.getPackageManager()
2919                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2920
2921            // We don't allow third party apps to replace this.
2922            ResolveInfo ri = null;
2923            for (int i=0; ris != null && i<ris.size(); i++) {
2924                if ((ris.get(i).activityInfo.applicationInfo.flags
2925                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2926                    ri = ris.get(i);
2927                    break;
2928                }
2929            }
2930
2931            if (ri != null) {
2932                String vers = ri.activityInfo.metaData != null
2933                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2934                        : null;
2935                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2936                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2937                            Intent.METADATA_SETUP_VERSION);
2938                }
2939                String lastVers = Settings.Secure.getString(
2940                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2941                if (vers != null && !vers.equals(lastVers)) {
2942                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2943                    intent.setComponent(new ComponentName(
2944                            ri.activityInfo.packageName, ri.activityInfo.name));
2945                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2946                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2947                }
2948            }
2949        }
2950    }
2951
2952    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2953        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2954    }
2955
2956    void enforceNotIsolatedCaller(String caller) {
2957        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2958            throw new SecurityException("Isolated process not allowed to call " + caller);
2959        }
2960    }
2961
2962    @Override
2963    public int getFrontActivityScreenCompatMode() {
2964        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2965        synchronized (this) {
2966            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2967        }
2968    }
2969
2970    @Override
2971    public void setFrontActivityScreenCompatMode(int mode) {
2972        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2973                "setFrontActivityScreenCompatMode");
2974        synchronized (this) {
2975            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2976        }
2977    }
2978
2979    @Override
2980    public int getPackageScreenCompatMode(String packageName) {
2981        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2982        synchronized (this) {
2983            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2984        }
2985    }
2986
2987    @Override
2988    public void setPackageScreenCompatMode(String packageName, int mode) {
2989        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2990                "setPackageScreenCompatMode");
2991        synchronized (this) {
2992            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2993        }
2994    }
2995
2996    @Override
2997    public boolean getPackageAskScreenCompat(String packageName) {
2998        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2999        synchronized (this) {
3000            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3001        }
3002    }
3003
3004    @Override
3005    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3006        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3007                "setPackageAskScreenCompat");
3008        synchronized (this) {
3009            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3010        }
3011    }
3012
3013    private void dispatchProcessesChanged() {
3014        int N;
3015        synchronized (this) {
3016            N = mPendingProcessChanges.size();
3017            if (mActiveProcessChanges.length < N) {
3018                mActiveProcessChanges = new ProcessChangeItem[N];
3019            }
3020            mPendingProcessChanges.toArray(mActiveProcessChanges);
3021            mAvailProcessChanges.addAll(mPendingProcessChanges);
3022            mPendingProcessChanges.clear();
3023            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3024        }
3025
3026        int i = mProcessObservers.beginBroadcast();
3027        while (i > 0) {
3028            i--;
3029            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3030            if (observer != null) {
3031                try {
3032                    for (int j=0; j<N; j++) {
3033                        ProcessChangeItem item = mActiveProcessChanges[j];
3034                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3035                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3036                                    + item.pid + " uid=" + item.uid + ": "
3037                                    + item.foregroundActivities);
3038                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3039                                    item.foregroundActivities);
3040                        }
3041                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3042                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3043                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3044                            observer.onImportanceChanged(item.pid, item.uid,
3045                                    item.importance);
3046                        }
3047                    }
3048                } catch (RemoteException e) {
3049                }
3050            }
3051        }
3052        mProcessObservers.finishBroadcast();
3053    }
3054
3055    private void dispatchProcessDied(int pid, int uid) {
3056        int i = mProcessObservers.beginBroadcast();
3057        while (i > 0) {
3058            i--;
3059            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3060            if (observer != null) {
3061                try {
3062                    observer.onProcessDied(pid, uid);
3063                } catch (RemoteException e) {
3064                }
3065            }
3066        }
3067        mProcessObservers.finishBroadcast();
3068    }
3069
3070    final void doPendingActivityLaunchesLocked(boolean doResume) {
3071        final int N = mPendingActivityLaunches.size();
3072        if (N <= 0) {
3073            return;
3074        }
3075        for (int i=0; i<N; i++) {
3076            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3077            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3078                    doResume && i == (N-1), null);
3079        }
3080        mPendingActivityLaunches.clear();
3081    }
3082
3083    @Override
3084    public final int startActivity(IApplicationThread caller, String callingPackage,
3085            Intent intent, String resolvedType, IBinder resultTo,
3086            String resultWho, int requestCode, int startFlags,
3087            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3088        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3089                resultWho, requestCode,
3090                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3091    }
3092
3093    @Override
3094    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3095            Intent intent, String resolvedType, IBinder resultTo,
3096            String resultWho, int requestCode, int startFlags,
3097            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3098        enforceNotIsolatedCaller("startActivity");
3099        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3100                false, true, "startActivity", null);
3101        // TODO: Switch to user app stacks here.
3102        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3103                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3104                null, null, options, userId, null);
3105    }
3106
3107    @Override
3108    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3109            Intent intent, String resolvedType, IBinder resultTo,
3110            String resultWho, int requestCode, int startFlags, String profileFile,
3111            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3112        enforceNotIsolatedCaller("startActivityAndWait");
3113        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3114                false, true, "startActivityAndWait", null);
3115        WaitResult res = new WaitResult();
3116        // TODO: Switch to user app stacks here.
3117        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3118                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3119                res, null, options, UserHandle.getCallingUserId(), null);
3120        return res;
3121    }
3122
3123    @Override
3124    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3125            Intent intent, String resolvedType, IBinder resultTo,
3126            String resultWho, int requestCode, int startFlags, Configuration config,
3127            Bundle options, int userId) {
3128        enforceNotIsolatedCaller("startActivityWithConfig");
3129        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3130                false, true, "startActivityWithConfig", null);
3131        // TODO: Switch to user app stacks here.
3132        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3133                resolvedType, resultTo, resultWho, requestCode, startFlags,
3134                null, null, null, config, options, userId, null);
3135        return ret;
3136    }
3137
3138    @Override
3139    public int startActivityIntentSender(IApplicationThread caller,
3140            IntentSender intent, Intent fillInIntent, String resolvedType,
3141            IBinder resultTo, String resultWho, int requestCode,
3142            int flagsMask, int flagsValues, Bundle options) {
3143        enforceNotIsolatedCaller("startActivityIntentSender");
3144        // Refuse possible leaked file descriptors
3145        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3146            throw new IllegalArgumentException("File descriptors passed in Intent");
3147        }
3148
3149        IIntentSender sender = intent.getTarget();
3150        if (!(sender instanceof PendingIntentRecord)) {
3151            throw new IllegalArgumentException("Bad PendingIntent object");
3152        }
3153
3154        PendingIntentRecord pir = (PendingIntentRecord)sender;
3155
3156        synchronized (this) {
3157            // If this is coming from the currently resumed activity, it is
3158            // effectively saying that app switches are allowed at this point.
3159            final ActivityStack stack = getFocusedStack();
3160            if (stack.mResumedActivity != null &&
3161                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3162                mAppSwitchesAllowedTime = 0;
3163            }
3164        }
3165        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3166                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3167        return ret;
3168    }
3169
3170    @Override
3171    public boolean startNextMatchingActivity(IBinder callingActivity,
3172            Intent intent, Bundle options) {
3173        // Refuse possible leaked file descriptors
3174        if (intent != null && intent.hasFileDescriptors() == true) {
3175            throw new IllegalArgumentException("File descriptors passed in Intent");
3176        }
3177
3178        synchronized (this) {
3179            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3180            if (r == null) {
3181                ActivityOptions.abort(options);
3182                return false;
3183            }
3184            if (r.app == null || r.app.thread == null) {
3185                // The caller is not running...  d'oh!
3186                ActivityOptions.abort(options);
3187                return false;
3188            }
3189            intent = new Intent(intent);
3190            // The caller is not allowed to change the data.
3191            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3192            // And we are resetting to find the next component...
3193            intent.setComponent(null);
3194
3195            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3196
3197            ActivityInfo aInfo = null;
3198            try {
3199                List<ResolveInfo> resolves =
3200                    AppGlobals.getPackageManager().queryIntentActivities(
3201                            intent, r.resolvedType,
3202                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3203                            UserHandle.getCallingUserId());
3204
3205                // Look for the original activity in the list...
3206                final int N = resolves != null ? resolves.size() : 0;
3207                for (int i=0; i<N; i++) {
3208                    ResolveInfo rInfo = resolves.get(i);
3209                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3210                            && rInfo.activityInfo.name.equals(r.info.name)) {
3211                        // We found the current one...  the next matching is
3212                        // after it.
3213                        i++;
3214                        if (i<N) {
3215                            aInfo = resolves.get(i).activityInfo;
3216                        }
3217                        if (debug) {
3218                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3219                                    + "/" + r.info.name);
3220                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3221                                    + "/" + aInfo.name);
3222                        }
3223                        break;
3224                    }
3225                }
3226            } catch (RemoteException e) {
3227            }
3228
3229            if (aInfo == null) {
3230                // Nobody who is next!
3231                ActivityOptions.abort(options);
3232                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3233                return false;
3234            }
3235
3236            intent.setComponent(new ComponentName(
3237                    aInfo.applicationInfo.packageName, aInfo.name));
3238            intent.setFlags(intent.getFlags()&~(
3239                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3240                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3241                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3242                    Intent.FLAG_ACTIVITY_NEW_TASK));
3243
3244            // Okay now we need to start the new activity, replacing the
3245            // currently running activity.  This is a little tricky because
3246            // we want to start the new one as if the current one is finished,
3247            // but not finish the current one first so that there is no flicker.
3248            // And thus...
3249            final boolean wasFinishing = r.finishing;
3250            r.finishing = true;
3251
3252            // Propagate reply information over to the new activity.
3253            final ActivityRecord resultTo = r.resultTo;
3254            final String resultWho = r.resultWho;
3255            final int requestCode = r.requestCode;
3256            r.resultTo = null;
3257            if (resultTo != null) {
3258                resultTo.removeResultsLocked(r, resultWho, requestCode);
3259            }
3260
3261            final long origId = Binder.clearCallingIdentity();
3262            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3263                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3264                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3265                    options, false, null, null);
3266            Binder.restoreCallingIdentity(origId);
3267
3268            r.finishing = wasFinishing;
3269            if (res != ActivityManager.START_SUCCESS) {
3270                return false;
3271            }
3272            return true;
3273        }
3274    }
3275
3276    final int startActivityInPackage(int uid, String callingPackage,
3277            Intent intent, String resolvedType, IBinder resultTo,
3278            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3279                    IActivityContainer container) {
3280
3281        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3282                false, true, "startActivityInPackage", null);
3283
3284        // TODO: Switch to user app stacks here.
3285        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3286                resultTo, resultWho, requestCode, startFlags,
3287                null, null, null, null, options, userId, container);
3288        return ret;
3289    }
3290
3291    @Override
3292    public final int startActivities(IApplicationThread caller, String callingPackage,
3293            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3294            int userId) {
3295        enforceNotIsolatedCaller("startActivities");
3296        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3297                false, true, "startActivity", null);
3298        // TODO: Switch to user app stacks here.
3299        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3300                resolvedTypes, resultTo, options, userId);
3301        return ret;
3302    }
3303
3304    final int startActivitiesInPackage(int uid, String callingPackage,
3305            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3306            Bundle options, int userId) {
3307
3308        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3309                false, true, "startActivityInPackage", null);
3310        // TODO: Switch to user app stacks here.
3311        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3312                resultTo, options, userId);
3313        return ret;
3314    }
3315
3316    final void addRecentTaskLocked(TaskRecord task) {
3317        int N = mRecentTasks.size();
3318        // Quick case: check if the top-most recent task is the same.
3319        if (N > 0 && mRecentTasks.get(0) == task) {
3320            return;
3321        }
3322        // Remove any existing entries that are the same kind of task.
3323        for (int i=0; i<N; i++) {
3324            TaskRecord tr = mRecentTasks.get(i);
3325            if (task.userId == tr.userId
3326                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3327                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3328                tr.disposeThumbnail();
3329                mRecentTasks.remove(i);
3330                i--;
3331                N--;
3332                if (task.intent == null) {
3333                    // If the new recent task we are adding is not fully
3334                    // specified, then replace it with the existing recent task.
3335                    task = tr;
3336                }
3337            }
3338        }
3339        if (N >= MAX_RECENT_TASKS) {
3340            mRecentTasks.remove(N-1).disposeThumbnail();
3341        }
3342        mRecentTasks.add(0, task);
3343    }
3344
3345    @Override
3346    public void reportActivityFullyDrawn(IBinder token) {
3347        synchronized (this) {
3348            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3349            if (r == null) {
3350                return;
3351            }
3352            r.reportFullyDrawnLocked();
3353        }
3354    }
3355
3356    @Override
3357    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3358        synchronized (this) {
3359            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3360            if (r == null) {
3361                return;
3362            }
3363            final long origId = Binder.clearCallingIdentity();
3364            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3365            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3366                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3367            if (config != null) {
3368                r.frozenBeforeDestroy = true;
3369                if (!updateConfigurationLocked(config, r, false, false)) {
3370                    mStackSupervisor.resumeTopActivitiesLocked();
3371                }
3372            }
3373            Binder.restoreCallingIdentity(origId);
3374        }
3375    }
3376
3377    @Override
3378    public int getRequestedOrientation(IBinder token) {
3379        synchronized (this) {
3380            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3381            if (r == null) {
3382                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3383            }
3384            return mWindowManager.getAppOrientation(r.appToken);
3385        }
3386    }
3387
3388    /**
3389     * This is the internal entry point for handling Activity.finish().
3390     *
3391     * @param token The Binder token referencing the Activity we want to finish.
3392     * @param resultCode Result code, if any, from this Activity.
3393     * @param resultData Result data (Intent), if any, from this Activity.
3394     *
3395     * @return Returns true if the activity successfully finished, or false if it is still running.
3396     */
3397    @Override
3398    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3399        // Refuse possible leaked file descriptors
3400        if (resultData != null && resultData.hasFileDescriptors() == true) {
3401            throw new IllegalArgumentException("File descriptors passed in Intent");
3402        }
3403
3404        synchronized(this) {
3405            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3406            if (r == null) {
3407                return true;
3408            }
3409            if (mController != null) {
3410                // Find the first activity that is not finishing.
3411                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3412                if (next != null) {
3413                    // ask watcher if this is allowed
3414                    boolean resumeOK = true;
3415                    try {
3416                        resumeOK = mController.activityResuming(next.packageName);
3417                    } catch (RemoteException e) {
3418                        mController = null;
3419                        Watchdog.getInstance().setActivityController(null);
3420                    }
3421
3422                    if (!resumeOK) {
3423                        return false;
3424                    }
3425                }
3426            }
3427            final long origId = Binder.clearCallingIdentity();
3428            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3429                    resultData, "app-request", true);
3430            Binder.restoreCallingIdentity(origId);
3431            return res;
3432        }
3433    }
3434
3435    @Override
3436    public final void finishHeavyWeightApp() {
3437        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3438                != PackageManager.PERMISSION_GRANTED) {
3439            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3440                    + Binder.getCallingPid()
3441                    + ", uid=" + Binder.getCallingUid()
3442                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3443            Slog.w(TAG, msg);
3444            throw new SecurityException(msg);
3445        }
3446
3447        synchronized(this) {
3448            if (mHeavyWeightProcess == null) {
3449                return;
3450            }
3451
3452            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3453                    mHeavyWeightProcess.activities);
3454            for (int i=0; i<activities.size(); i++) {
3455                ActivityRecord r = activities.get(i);
3456                if (!r.finishing) {
3457                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3458                            null, "finish-heavy", true);
3459                }
3460            }
3461
3462            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3463                    mHeavyWeightProcess.userId, 0));
3464            mHeavyWeightProcess = null;
3465        }
3466    }
3467
3468    @Override
3469    public void crashApplication(int uid, int initialPid, String packageName,
3470            String message) {
3471        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3472                != PackageManager.PERMISSION_GRANTED) {
3473            String msg = "Permission Denial: crashApplication() from pid="
3474                    + Binder.getCallingPid()
3475                    + ", uid=" + Binder.getCallingUid()
3476                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3477            Slog.w(TAG, msg);
3478            throw new SecurityException(msg);
3479        }
3480
3481        synchronized(this) {
3482            ProcessRecord proc = null;
3483
3484            // Figure out which process to kill.  We don't trust that initialPid
3485            // still has any relation to current pids, so must scan through the
3486            // list.
3487            synchronized (mPidsSelfLocked) {
3488                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3489                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3490                    if (p.uid != uid) {
3491                        continue;
3492                    }
3493                    if (p.pid == initialPid) {
3494                        proc = p;
3495                        break;
3496                    }
3497                    if (p.pkgList.containsKey(packageName)) {
3498                        proc = p;
3499                    }
3500                }
3501            }
3502
3503            if (proc == null) {
3504                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3505                        + " initialPid=" + initialPid
3506                        + " packageName=" + packageName);
3507                return;
3508            }
3509
3510            if (proc.thread != null) {
3511                if (proc.pid == Process.myPid()) {
3512                    Log.w(TAG, "crashApplication: trying to crash self!");
3513                    return;
3514                }
3515                long ident = Binder.clearCallingIdentity();
3516                try {
3517                    proc.thread.scheduleCrash(message);
3518                } catch (RemoteException e) {
3519                }
3520                Binder.restoreCallingIdentity(ident);
3521            }
3522        }
3523    }
3524
3525    @Override
3526    public final void finishSubActivity(IBinder token, String resultWho,
3527            int requestCode) {
3528        synchronized(this) {
3529            final long origId = Binder.clearCallingIdentity();
3530            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3531            if (r != null) {
3532                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3533            }
3534            Binder.restoreCallingIdentity(origId);
3535        }
3536    }
3537
3538    @Override
3539    public boolean finishActivityAffinity(IBinder token) {
3540        synchronized(this) {
3541            final long origId = Binder.clearCallingIdentity();
3542            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3543            boolean res = false;
3544            if (r != null) {
3545                res = r.task.stack.finishActivityAffinityLocked(r);
3546            }
3547            Binder.restoreCallingIdentity(origId);
3548            return res;
3549        }
3550    }
3551
3552    @Override
3553    public boolean willActivityBeVisible(IBinder token) {
3554        synchronized(this) {
3555            ActivityStack stack = ActivityRecord.getStackLocked(token);
3556            if (stack != null) {
3557                return stack.willActivityBeVisibleLocked(token);
3558            }
3559            return false;
3560        }
3561    }
3562
3563    @Override
3564    public void overridePendingTransition(IBinder token, String packageName,
3565            int enterAnim, int exitAnim) {
3566        synchronized(this) {
3567            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3568            if (self == null) {
3569                return;
3570            }
3571
3572            final long origId = Binder.clearCallingIdentity();
3573
3574            if (self.state == ActivityState.RESUMED
3575                    || self.state == ActivityState.PAUSING) {
3576                mWindowManager.overridePendingAppTransition(packageName,
3577                        enterAnim, exitAnim, null);
3578            }
3579
3580            Binder.restoreCallingIdentity(origId);
3581        }
3582    }
3583
3584    /**
3585     * Main function for removing an existing process from the activity manager
3586     * as a result of that process going away.  Clears out all connections
3587     * to the process.
3588     */
3589    private final void handleAppDiedLocked(ProcessRecord app,
3590            boolean restarting, boolean allowRestart) {
3591        int pid = app.pid;
3592        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3593        if (!restarting) {
3594            removeLruProcessLocked(app);
3595            if (pid > 0) {
3596                ProcessList.remove(pid);
3597            }
3598        }
3599
3600        if (mProfileProc == app) {
3601            clearProfilerLocked();
3602        }
3603
3604        // Remove this application's activities from active lists.
3605        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3606
3607        app.activities.clear();
3608
3609        if (app.instrumentationClass != null) {
3610            Slog.w(TAG, "Crash of app " + app.processName
3611                  + " running instrumentation " + app.instrumentationClass);
3612            Bundle info = new Bundle();
3613            info.putString("shortMsg", "Process crashed.");
3614            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3615        }
3616
3617        if (!restarting) {
3618            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3619                // If there was nothing to resume, and we are not already
3620                // restarting this process, but there is a visible activity that
3621                // is hosted by the process...  then make sure all visible
3622                // activities are running, taking care of restarting this
3623                // process.
3624                if (hasVisibleActivities) {
3625                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3626                }
3627            }
3628        }
3629    }
3630
3631    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3632        IBinder threadBinder = thread.asBinder();
3633        // Find the application record.
3634        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3635            ProcessRecord rec = mLruProcesses.get(i);
3636            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3637                return i;
3638            }
3639        }
3640        return -1;
3641    }
3642
3643    final ProcessRecord getRecordForAppLocked(
3644            IApplicationThread thread) {
3645        if (thread == null) {
3646            return null;
3647        }
3648
3649        int appIndex = getLRURecordIndexForAppLocked(thread);
3650        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3651    }
3652
3653    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3654        // If there are no longer any background processes running,
3655        // and the app that died was not running instrumentation,
3656        // then tell everyone we are now low on memory.
3657        boolean haveBg = false;
3658        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3659            ProcessRecord rec = mLruProcesses.get(i);
3660            if (rec.thread != null
3661                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3662                haveBg = true;
3663                break;
3664            }
3665        }
3666
3667        if (!haveBg) {
3668            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3669            if (doReport) {
3670                long now = SystemClock.uptimeMillis();
3671                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3672                    doReport = false;
3673                } else {
3674                    mLastMemUsageReportTime = now;
3675                }
3676            }
3677            final ArrayList<ProcessMemInfo> memInfos
3678                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3679            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3680            long now = SystemClock.uptimeMillis();
3681            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3682                ProcessRecord rec = mLruProcesses.get(i);
3683                if (rec == dyingProc || rec.thread == null) {
3684                    continue;
3685                }
3686                if (doReport) {
3687                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3688                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3689                }
3690                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3691                    // The low memory report is overriding any current
3692                    // state for a GC request.  Make sure to do
3693                    // heavy/important/visible/foreground processes first.
3694                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3695                        rec.lastRequestedGc = 0;
3696                    } else {
3697                        rec.lastRequestedGc = rec.lastLowMemory;
3698                    }
3699                    rec.reportLowMemory = true;
3700                    rec.lastLowMemory = now;
3701                    mProcessesToGc.remove(rec);
3702                    addProcessToGcListLocked(rec);
3703                }
3704            }
3705            if (doReport) {
3706                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3707                mHandler.sendMessage(msg);
3708            }
3709            scheduleAppGcsLocked();
3710        }
3711    }
3712
3713    final void appDiedLocked(ProcessRecord app, int pid,
3714            IApplicationThread thread) {
3715
3716        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3717        synchronized (stats) {
3718            stats.noteProcessDiedLocked(app.info.uid, pid);
3719        }
3720
3721        // Clean up already done if the process has been re-started.
3722        if (app.pid == pid && app.thread != null &&
3723                app.thread.asBinder() == thread.asBinder()) {
3724            boolean doLowMem = app.instrumentationClass == null;
3725            boolean doOomAdj = doLowMem;
3726            if (!app.killedByAm) {
3727                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3728                        + ") has died.");
3729                mAllowLowerMemLevel = true;
3730            } else {
3731                // Note that we always want to do oom adj to update our state with the
3732                // new number of procs.
3733                mAllowLowerMemLevel = false;
3734                doLowMem = false;
3735            }
3736            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3737            if (DEBUG_CLEANUP) Slog.v(
3738                TAG, "Dying app: " + app + ", pid: " + pid
3739                + ", thread: " + thread.asBinder());
3740            handleAppDiedLocked(app, false, true);
3741
3742            if (doOomAdj) {
3743                updateOomAdjLocked();
3744            }
3745            if (doLowMem) {
3746                doLowMemReportIfNeededLocked(app);
3747            }
3748        } else if (app.pid != pid) {
3749            // A new process has already been started.
3750            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3751                    + ") has died and restarted (pid " + app.pid + ").");
3752            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3753        } else if (DEBUG_PROCESSES) {
3754            Slog.d(TAG, "Received spurious death notification for thread "
3755                    + thread.asBinder());
3756        }
3757    }
3758
3759    /**
3760     * If a stack trace dump file is configured, dump process stack traces.
3761     * @param clearTraces causes the dump file to be erased prior to the new
3762     *    traces being written, if true; when false, the new traces will be
3763     *    appended to any existing file content.
3764     * @param firstPids of dalvik VM processes to dump stack traces for first
3765     * @param lastPids of dalvik VM processes to dump stack traces for last
3766     * @param nativeProcs optional list of native process names to dump stack crawls
3767     * @return file containing stack traces, or null if no dump file is configured
3768     */
3769    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3770            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3771        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3772        if (tracesPath == null || tracesPath.length() == 0) {
3773            return null;
3774        }
3775
3776        File tracesFile = new File(tracesPath);
3777        try {
3778            File tracesDir = tracesFile.getParentFile();
3779            if (!tracesDir.exists()) {
3780                tracesFile.mkdirs();
3781                if (!SELinux.restorecon(tracesDir)) {
3782                    return null;
3783                }
3784            }
3785            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3786
3787            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3788            tracesFile.createNewFile();
3789            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3790        } catch (IOException e) {
3791            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3792            return null;
3793        }
3794
3795        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3796        return tracesFile;
3797    }
3798
3799    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3800            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3801        // Use a FileObserver to detect when traces finish writing.
3802        // The order of traces is considered important to maintain for legibility.
3803        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3804            @Override
3805            public synchronized void onEvent(int event, String path) { notify(); }
3806        };
3807
3808        try {
3809            observer.startWatching();
3810
3811            // First collect all of the stacks of the most important pids.
3812            if (firstPids != null) {
3813                try {
3814                    int num = firstPids.size();
3815                    for (int i = 0; i < num; i++) {
3816                        synchronized (observer) {
3817                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3818                            observer.wait(200);  // Wait for write-close, give up after 200msec
3819                        }
3820                    }
3821                } catch (InterruptedException e) {
3822                    Log.wtf(TAG, e);
3823                }
3824            }
3825
3826            // Next collect the stacks of the native pids
3827            if (nativeProcs != null) {
3828                int[] pids = Process.getPidsForCommands(nativeProcs);
3829                if (pids != null) {
3830                    for (int pid : pids) {
3831                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3832                    }
3833                }
3834            }
3835
3836            // Lastly, measure CPU usage.
3837            if (processCpuTracker != null) {
3838                processCpuTracker.init();
3839                System.gc();
3840                processCpuTracker.update();
3841                try {
3842                    synchronized (processCpuTracker) {
3843                        processCpuTracker.wait(500); // measure over 1/2 second.
3844                    }
3845                } catch (InterruptedException e) {
3846                }
3847                processCpuTracker.update();
3848
3849                // We'll take the stack crawls of just the top apps using CPU.
3850                final int N = processCpuTracker.countWorkingStats();
3851                int numProcs = 0;
3852                for (int i=0; i<N && numProcs<5; i++) {
3853                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3854                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3855                        numProcs++;
3856                        try {
3857                            synchronized (observer) {
3858                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3859                                observer.wait(200);  // Wait for write-close, give up after 200msec
3860                            }
3861                        } catch (InterruptedException e) {
3862                            Log.wtf(TAG, e);
3863                        }
3864
3865                    }
3866                }
3867            }
3868        } finally {
3869            observer.stopWatching();
3870        }
3871    }
3872
3873    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3874        if (true || IS_USER_BUILD) {
3875            return;
3876        }
3877        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3878        if (tracesPath == null || tracesPath.length() == 0) {
3879            return;
3880        }
3881
3882        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3883        StrictMode.allowThreadDiskWrites();
3884        try {
3885            final File tracesFile = new File(tracesPath);
3886            final File tracesDir = tracesFile.getParentFile();
3887            final File tracesTmp = new File(tracesDir, "__tmp__");
3888            try {
3889                if (!tracesDir.exists()) {
3890                    tracesFile.mkdirs();
3891                    if (!SELinux.restorecon(tracesDir.getPath())) {
3892                        return;
3893                    }
3894                }
3895                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3896
3897                if (tracesFile.exists()) {
3898                    tracesTmp.delete();
3899                    tracesFile.renameTo(tracesTmp);
3900                }
3901                StringBuilder sb = new StringBuilder();
3902                Time tobj = new Time();
3903                tobj.set(System.currentTimeMillis());
3904                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3905                sb.append(": ");
3906                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3907                sb.append(" since ");
3908                sb.append(msg);
3909                FileOutputStream fos = new FileOutputStream(tracesFile);
3910                fos.write(sb.toString().getBytes());
3911                if (app == null) {
3912                    fos.write("\n*** No application process!".getBytes());
3913                }
3914                fos.close();
3915                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3916            } catch (IOException e) {
3917                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3918                return;
3919            }
3920
3921            if (app != null) {
3922                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3923                firstPids.add(app.pid);
3924                dumpStackTraces(tracesPath, firstPids, null, null, null);
3925            }
3926
3927            File lastTracesFile = null;
3928            File curTracesFile = null;
3929            for (int i=9; i>=0; i--) {
3930                String name = String.format(Locale.US, "slow%02d.txt", i);
3931                curTracesFile = new File(tracesDir, name);
3932                if (curTracesFile.exists()) {
3933                    if (lastTracesFile != null) {
3934                        curTracesFile.renameTo(lastTracesFile);
3935                    } else {
3936                        curTracesFile.delete();
3937                    }
3938                }
3939                lastTracesFile = curTracesFile;
3940            }
3941            tracesFile.renameTo(curTracesFile);
3942            if (tracesTmp.exists()) {
3943                tracesTmp.renameTo(tracesFile);
3944            }
3945        } finally {
3946            StrictMode.setThreadPolicy(oldPolicy);
3947        }
3948    }
3949
3950    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3951            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3952        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3953        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3954
3955        if (mController != null) {
3956            try {
3957                // 0 == continue, -1 = kill process immediately
3958                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3959                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3960            } catch (RemoteException e) {
3961                mController = null;
3962                Watchdog.getInstance().setActivityController(null);
3963            }
3964        }
3965
3966        long anrTime = SystemClock.uptimeMillis();
3967        if (MONITOR_CPU_USAGE) {
3968            updateCpuStatsNow();
3969        }
3970
3971        synchronized (this) {
3972            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3973            if (mShuttingDown) {
3974                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3975                return;
3976            } else if (app.notResponding) {
3977                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3978                return;
3979            } else if (app.crashing) {
3980                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3981                return;
3982            }
3983
3984            // In case we come through here for the same app before completing
3985            // this one, mark as anring now so we will bail out.
3986            app.notResponding = true;
3987
3988            // Log the ANR to the event log.
3989            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3990                    app.processName, app.info.flags, annotation);
3991
3992            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3993            firstPids.add(app.pid);
3994
3995            int parentPid = app.pid;
3996            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3997            if (parentPid != app.pid) firstPids.add(parentPid);
3998
3999            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4000
4001            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4002                ProcessRecord r = mLruProcesses.get(i);
4003                if (r != null && r.thread != null) {
4004                    int pid = r.pid;
4005                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4006                        if (r.persistent) {
4007                            firstPids.add(pid);
4008                        } else {
4009                            lastPids.put(pid, Boolean.TRUE);
4010                        }
4011                    }
4012                }
4013            }
4014        }
4015
4016        // Log the ANR to the main log.
4017        StringBuilder info = new StringBuilder();
4018        info.setLength(0);
4019        info.append("ANR in ").append(app.processName);
4020        if (activity != null && activity.shortComponentName != null) {
4021            info.append(" (").append(activity.shortComponentName).append(")");
4022        }
4023        info.append("\n");
4024        info.append("PID: ").append(app.pid).append("\n");
4025        if (annotation != null) {
4026            info.append("Reason: ").append(annotation).append("\n");
4027        }
4028        if (parent != null && parent != activity) {
4029            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4030        }
4031
4032        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4033
4034        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4035                NATIVE_STACKS_OF_INTEREST);
4036
4037        String cpuInfo = null;
4038        if (MONITOR_CPU_USAGE) {
4039            updateCpuStatsNow();
4040            synchronized (mProcessCpuThread) {
4041                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4042            }
4043            info.append(processCpuTracker.printCurrentLoad());
4044            info.append(cpuInfo);
4045        }
4046
4047        info.append(processCpuTracker.printCurrentState(anrTime));
4048
4049        Slog.e(TAG, info.toString());
4050        if (tracesFile == null) {
4051            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4052            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4053        }
4054
4055        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4056                cpuInfo, tracesFile, null);
4057
4058        if (mController != null) {
4059            try {
4060                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4061                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4062                if (res != 0) {
4063                    if (res < 0 && app.pid != MY_PID) {
4064                        Process.killProcess(app.pid);
4065                    } else {
4066                        synchronized (this) {
4067                            mServices.scheduleServiceTimeoutLocked(app);
4068                        }
4069                    }
4070                    return;
4071                }
4072            } catch (RemoteException e) {
4073                mController = null;
4074                Watchdog.getInstance().setActivityController(null);
4075            }
4076        }
4077
4078        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4079        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4080                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4081
4082        synchronized (this) {
4083            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4084                killUnneededProcessLocked(app, "background ANR");
4085                return;
4086            }
4087
4088            // Set the app's notResponding state, and look up the errorReportReceiver
4089            makeAppNotRespondingLocked(app,
4090                    activity != null ? activity.shortComponentName : null,
4091                    annotation != null ? "ANR " + annotation : "ANR",
4092                    info.toString());
4093
4094            // Bring up the infamous App Not Responding dialog
4095            Message msg = Message.obtain();
4096            HashMap<String, Object> map = new HashMap<String, Object>();
4097            msg.what = SHOW_NOT_RESPONDING_MSG;
4098            msg.obj = map;
4099            msg.arg1 = aboveSystem ? 1 : 0;
4100            map.put("app", app);
4101            if (activity != null) {
4102                map.put("activity", activity);
4103            }
4104
4105            mHandler.sendMessage(msg);
4106        }
4107    }
4108
4109    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4110        if (!mLaunchWarningShown) {
4111            mLaunchWarningShown = true;
4112            mHandler.post(new Runnable() {
4113                @Override
4114                public void run() {
4115                    synchronized (ActivityManagerService.this) {
4116                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4117                        d.show();
4118                        mHandler.postDelayed(new Runnable() {
4119                            @Override
4120                            public void run() {
4121                                synchronized (ActivityManagerService.this) {
4122                                    d.dismiss();
4123                                    mLaunchWarningShown = false;
4124                                }
4125                            }
4126                        }, 4000);
4127                    }
4128                }
4129            });
4130        }
4131    }
4132
4133    @Override
4134    public boolean clearApplicationUserData(final String packageName,
4135            final IPackageDataObserver observer, int userId) {
4136        enforceNotIsolatedCaller("clearApplicationUserData");
4137        int uid = Binder.getCallingUid();
4138        int pid = Binder.getCallingPid();
4139        userId = handleIncomingUser(pid, uid,
4140                userId, false, true, "clearApplicationUserData", null);
4141        long callingId = Binder.clearCallingIdentity();
4142        try {
4143            IPackageManager pm = AppGlobals.getPackageManager();
4144            int pkgUid = -1;
4145            synchronized(this) {
4146                try {
4147                    pkgUid = pm.getPackageUid(packageName, userId);
4148                } catch (RemoteException e) {
4149                }
4150                if (pkgUid == -1) {
4151                    Slog.w(TAG, "Invalid packageName: " + packageName);
4152                    if (observer != null) {
4153                        try {
4154                            observer.onRemoveCompleted(packageName, false);
4155                        } catch (RemoteException e) {
4156                            Slog.i(TAG, "Observer no longer exists.");
4157                        }
4158                    }
4159                    return false;
4160                }
4161                if (uid == pkgUid || checkComponentPermission(
4162                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4163                        pid, uid, -1, true)
4164                        == PackageManager.PERMISSION_GRANTED) {
4165                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4166                } else {
4167                    throw new SecurityException("PID " + pid + " does not have permission "
4168                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4169                                    + " of package " + packageName);
4170                }
4171            }
4172
4173            try {
4174                // Clear application user data
4175                pm.clearApplicationUserData(packageName, observer, userId);
4176
4177                // Remove all permissions granted from/to this package
4178                removeUriPermissionsForPackageLocked(packageName, userId, true);
4179
4180                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4181                        Uri.fromParts("package", packageName, null));
4182                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4183                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4184                        null, null, 0, null, null, null, false, false, userId);
4185            } catch (RemoteException e) {
4186            }
4187        } finally {
4188            Binder.restoreCallingIdentity(callingId);
4189        }
4190        return true;
4191    }
4192
4193    @Override
4194    public void killBackgroundProcesses(final String packageName, int userId) {
4195        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4196                != PackageManager.PERMISSION_GRANTED &&
4197                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4198                        != PackageManager.PERMISSION_GRANTED) {
4199            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4200                    + Binder.getCallingPid()
4201                    + ", uid=" + Binder.getCallingUid()
4202                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4203            Slog.w(TAG, msg);
4204            throw new SecurityException(msg);
4205        }
4206
4207        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4208                userId, true, true, "killBackgroundProcesses", null);
4209        long callingId = Binder.clearCallingIdentity();
4210        try {
4211            IPackageManager pm = AppGlobals.getPackageManager();
4212            synchronized(this) {
4213                int appId = -1;
4214                try {
4215                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4216                } catch (RemoteException e) {
4217                }
4218                if (appId == -1) {
4219                    Slog.w(TAG, "Invalid packageName: " + packageName);
4220                    return;
4221                }
4222                killPackageProcessesLocked(packageName, appId, userId,
4223                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4224            }
4225        } finally {
4226            Binder.restoreCallingIdentity(callingId);
4227        }
4228    }
4229
4230    @Override
4231    public void killAllBackgroundProcesses() {
4232        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4233                != PackageManager.PERMISSION_GRANTED) {
4234            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4235                    + Binder.getCallingPid()
4236                    + ", uid=" + Binder.getCallingUid()
4237                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4238            Slog.w(TAG, msg);
4239            throw new SecurityException(msg);
4240        }
4241
4242        long callingId = Binder.clearCallingIdentity();
4243        try {
4244            synchronized(this) {
4245                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4246                final int NP = mProcessNames.getMap().size();
4247                for (int ip=0; ip<NP; ip++) {
4248                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4249                    final int NA = apps.size();
4250                    for (int ia=0; ia<NA; ia++) {
4251                        ProcessRecord app = apps.valueAt(ia);
4252                        if (app.persistent) {
4253                            // we don't kill persistent processes
4254                            continue;
4255                        }
4256                        if (app.removed) {
4257                            procs.add(app);
4258                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4259                            app.removed = true;
4260                            procs.add(app);
4261                        }
4262                    }
4263                }
4264
4265                int N = procs.size();
4266                for (int i=0; i<N; i++) {
4267                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4268                }
4269                mAllowLowerMemLevel = true;
4270                updateOomAdjLocked();
4271                doLowMemReportIfNeededLocked(null);
4272            }
4273        } finally {
4274            Binder.restoreCallingIdentity(callingId);
4275        }
4276    }
4277
4278    @Override
4279    public void forceStopPackage(final String packageName, int userId) {
4280        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4281                != PackageManager.PERMISSION_GRANTED) {
4282            String msg = "Permission Denial: forceStopPackage() from pid="
4283                    + Binder.getCallingPid()
4284                    + ", uid=" + Binder.getCallingUid()
4285                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4286            Slog.w(TAG, msg);
4287            throw new SecurityException(msg);
4288        }
4289        final int callingPid = Binder.getCallingPid();
4290        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4291                userId, true, true, "forceStopPackage", null);
4292        long callingId = Binder.clearCallingIdentity();
4293        try {
4294            IPackageManager pm = AppGlobals.getPackageManager();
4295            synchronized(this) {
4296                int[] users = userId == UserHandle.USER_ALL
4297                        ? getUsersLocked() : new int[] { userId };
4298                for (int user : users) {
4299                    int pkgUid = -1;
4300                    try {
4301                        pkgUid = pm.getPackageUid(packageName, user);
4302                    } catch (RemoteException e) {
4303                    }
4304                    if (pkgUid == -1) {
4305                        Slog.w(TAG, "Invalid packageName: " + packageName);
4306                        continue;
4307                    }
4308                    try {
4309                        pm.setPackageStoppedState(packageName, true, user);
4310                    } catch (RemoteException e) {
4311                    } catch (IllegalArgumentException e) {
4312                        Slog.w(TAG, "Failed trying to unstop package "
4313                                + packageName + ": " + e);
4314                    }
4315                    if (isUserRunningLocked(user, false)) {
4316                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4317                    }
4318                }
4319            }
4320        } finally {
4321            Binder.restoreCallingIdentity(callingId);
4322        }
4323    }
4324
4325    /*
4326     * The pkg name and app id have to be specified.
4327     */
4328    @Override
4329    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4330        if (pkg == null) {
4331            return;
4332        }
4333        // Make sure the uid is valid.
4334        if (appid < 0) {
4335            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4336            return;
4337        }
4338        int callerUid = Binder.getCallingUid();
4339        // Only the system server can kill an application
4340        if (callerUid == Process.SYSTEM_UID) {
4341            // Post an aysnc message to kill the application
4342            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4343            msg.arg1 = appid;
4344            msg.arg2 = 0;
4345            Bundle bundle = new Bundle();
4346            bundle.putString("pkg", pkg);
4347            bundle.putString("reason", reason);
4348            msg.obj = bundle;
4349            mHandler.sendMessage(msg);
4350        } else {
4351            throw new SecurityException(callerUid + " cannot kill pkg: " +
4352                    pkg);
4353        }
4354    }
4355
4356    @Override
4357    public void closeSystemDialogs(String reason) {
4358        enforceNotIsolatedCaller("closeSystemDialogs");
4359
4360        final int pid = Binder.getCallingPid();
4361        final int uid = Binder.getCallingUid();
4362        final long origId = Binder.clearCallingIdentity();
4363        try {
4364            synchronized (this) {
4365                // Only allow this from foreground processes, so that background
4366                // applications can't abuse it to prevent system UI from being shown.
4367                if (uid >= Process.FIRST_APPLICATION_UID) {
4368                    ProcessRecord proc;
4369                    synchronized (mPidsSelfLocked) {
4370                        proc = mPidsSelfLocked.get(pid);
4371                    }
4372                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4373                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4374                                + " from background process " + proc);
4375                        return;
4376                    }
4377                }
4378                closeSystemDialogsLocked(reason);
4379            }
4380        } finally {
4381            Binder.restoreCallingIdentity(origId);
4382        }
4383    }
4384
4385    void closeSystemDialogsLocked(String reason) {
4386        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4387        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4388                | Intent.FLAG_RECEIVER_FOREGROUND);
4389        if (reason != null) {
4390            intent.putExtra("reason", reason);
4391        }
4392        mWindowManager.closeSystemDialogs(reason);
4393
4394        mStackSupervisor.closeSystemDialogsLocked();
4395
4396        broadcastIntentLocked(null, null, intent, null,
4397                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4398                Process.SYSTEM_UID, UserHandle.USER_ALL);
4399    }
4400
4401    @Override
4402    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4403        enforceNotIsolatedCaller("getProcessMemoryInfo");
4404        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4405        for (int i=pids.length-1; i>=0; i--) {
4406            ProcessRecord proc;
4407            int oomAdj;
4408            synchronized (this) {
4409                synchronized (mPidsSelfLocked) {
4410                    proc = mPidsSelfLocked.get(pids[i]);
4411                    oomAdj = proc != null ? proc.setAdj : 0;
4412                }
4413            }
4414            infos[i] = new Debug.MemoryInfo();
4415            Debug.getMemoryInfo(pids[i], infos[i]);
4416            if (proc != null) {
4417                synchronized (this) {
4418                    if (proc.thread != null && proc.setAdj == oomAdj) {
4419                        // Record this for posterity if the process has been stable.
4420                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4421                                infos[i].getTotalUss(), false, proc.pkgList);
4422                    }
4423                }
4424            }
4425        }
4426        return infos;
4427    }
4428
4429    @Override
4430    public long[] getProcessPss(int[] pids) {
4431        enforceNotIsolatedCaller("getProcessPss");
4432        long[] pss = new long[pids.length];
4433        for (int i=pids.length-1; i>=0; i--) {
4434            ProcessRecord proc;
4435            int oomAdj;
4436            synchronized (this) {
4437                synchronized (mPidsSelfLocked) {
4438                    proc = mPidsSelfLocked.get(pids[i]);
4439                    oomAdj = proc != null ? proc.setAdj : 0;
4440                }
4441            }
4442            long[] tmpUss = new long[1];
4443            pss[i] = Debug.getPss(pids[i], tmpUss);
4444            if (proc != null) {
4445                synchronized (this) {
4446                    if (proc.thread != null && proc.setAdj == oomAdj) {
4447                        // Record this for posterity if the process has been stable.
4448                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4449                    }
4450                }
4451            }
4452        }
4453        return pss;
4454    }
4455
4456    @Override
4457    public void killApplicationProcess(String processName, int uid) {
4458        if (processName == null) {
4459            return;
4460        }
4461
4462        int callerUid = Binder.getCallingUid();
4463        // Only the system server can kill an application
4464        if (callerUid == Process.SYSTEM_UID) {
4465            synchronized (this) {
4466                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4467                if (app != null && app.thread != null) {
4468                    try {
4469                        app.thread.scheduleSuicide();
4470                    } catch (RemoteException e) {
4471                        // If the other end already died, then our work here is done.
4472                    }
4473                } else {
4474                    Slog.w(TAG, "Process/uid not found attempting kill of "
4475                            + processName + " / " + uid);
4476                }
4477            }
4478        } else {
4479            throw new SecurityException(callerUid + " cannot kill app process: " +
4480                    processName);
4481        }
4482    }
4483
4484    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4485        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4486                false, true, false, UserHandle.getUserId(uid), reason);
4487        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4488                Uri.fromParts("package", packageName, null));
4489        if (!mProcessesReady) {
4490            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4491                    | Intent.FLAG_RECEIVER_FOREGROUND);
4492        }
4493        intent.putExtra(Intent.EXTRA_UID, uid);
4494        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4495        broadcastIntentLocked(null, null, intent,
4496                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4497                false, false,
4498                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4499    }
4500
4501    private void forceStopUserLocked(int userId, String reason) {
4502        forceStopPackageLocked(null, -1, false, false, true, false, userId, reason);
4503        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4504        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4505                | Intent.FLAG_RECEIVER_FOREGROUND);
4506        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4507        broadcastIntentLocked(null, null, intent,
4508                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4509                false, false,
4510                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4511    }
4512
4513    private final boolean killPackageProcessesLocked(String packageName, int appId,
4514            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4515            boolean doit, boolean evenPersistent, String reason) {
4516        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4517
4518        // Remove all processes this package may have touched: all with the
4519        // same UID (except for the system or root user), and all whose name
4520        // matches the package name.
4521        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4522        final int NP = mProcessNames.getMap().size();
4523        for (int ip=0; ip<NP; ip++) {
4524            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4525            final int NA = apps.size();
4526            for (int ia=0; ia<NA; ia++) {
4527                ProcessRecord app = apps.valueAt(ia);
4528                if (app.persistent && !evenPersistent) {
4529                    // we don't kill persistent processes
4530                    continue;
4531                }
4532                if (app.removed) {
4533                    if (doit) {
4534                        procs.add(app);
4535                    }
4536                    continue;
4537                }
4538
4539                // Skip process if it doesn't meet our oom adj requirement.
4540                if (app.setAdj < minOomAdj) {
4541                    continue;
4542                }
4543
4544                // If no package is specified, we call all processes under the
4545                // give user id.
4546                if (packageName == null) {
4547                    if (app.userId != userId) {
4548                        continue;
4549                    }
4550                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4551                        continue;
4552                    }
4553                // Package has been specified, we want to hit all processes
4554                // that match it.  We need to qualify this by the processes
4555                // that are running under the specified app and user ID.
4556                } else {
4557                    if (UserHandle.getAppId(app.uid) != appId) {
4558                        continue;
4559                    }
4560                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4561                        continue;
4562                    }
4563                    if (!app.pkgList.containsKey(packageName)) {
4564                        continue;
4565                    }
4566                }
4567
4568                // Process has passed all conditions, kill it!
4569                if (!doit) {
4570                    return true;
4571                }
4572                app.removed = true;
4573                procs.add(app);
4574            }
4575        }
4576
4577        int N = procs.size();
4578        for (int i=0; i<N; i++) {
4579            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4580        }
4581        updateOomAdjLocked();
4582        return N > 0;
4583    }
4584
4585    private final boolean forceStopPackageLocked(String name, int appId,
4586            boolean callerWillRestart, boolean purgeCache, boolean doit,
4587            boolean evenPersistent, int userId, String reason) {
4588        int i;
4589        int N;
4590
4591        if (userId == UserHandle.USER_ALL && name == null) {
4592            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4593        }
4594
4595        if (appId < 0 && name != null) {
4596            try {
4597                appId = UserHandle.getAppId(
4598                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4599            } catch (RemoteException e) {
4600            }
4601        }
4602
4603        if (doit) {
4604            if (name != null) {
4605                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4606                        + " user=" + userId + ": " + reason);
4607            } else {
4608                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4609            }
4610
4611            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4612            for (int ip=pmap.size()-1; ip>=0; ip--) {
4613                SparseArray<Long> ba = pmap.valueAt(ip);
4614                for (i=ba.size()-1; i>=0; i--) {
4615                    boolean remove = false;
4616                    final int entUid = ba.keyAt(i);
4617                    if (name != null) {
4618                        if (userId == UserHandle.USER_ALL) {
4619                            if (UserHandle.getAppId(entUid) == appId) {
4620                                remove = true;
4621                            }
4622                        } else {
4623                            if (entUid == UserHandle.getUid(userId, appId)) {
4624                                remove = true;
4625                            }
4626                        }
4627                    } else if (UserHandle.getUserId(entUid) == userId) {
4628                        remove = true;
4629                    }
4630                    if (remove) {
4631                        ba.removeAt(i);
4632                    }
4633                }
4634                if (ba.size() == 0) {
4635                    pmap.removeAt(ip);
4636                }
4637            }
4638        }
4639
4640        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4641                -100, callerWillRestart, true, doit, evenPersistent,
4642                name == null ? ("stop user " + userId) : ("stop " + name));
4643
4644        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4645            if (!doit) {
4646                return true;
4647            }
4648            didSomething = true;
4649        }
4650
4651        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4652            if (!doit) {
4653                return true;
4654            }
4655            didSomething = true;
4656        }
4657
4658        if (name == null) {
4659            // Remove all sticky broadcasts from this user.
4660            mStickyBroadcasts.remove(userId);
4661        }
4662
4663        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4664        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4665                userId, providers)) {
4666            if (!doit) {
4667                return true;
4668            }
4669            didSomething = true;
4670        }
4671        N = providers.size();
4672        for (i=0; i<N; i++) {
4673            removeDyingProviderLocked(null, providers.get(i), true);
4674        }
4675
4676        // Remove transient permissions granted from/to this package/user
4677        removeUriPermissionsForPackageLocked(name, userId, false);
4678
4679        if (name == null) {
4680            // Remove pending intents.  For now we only do this when force
4681            // stopping users, because we have some problems when doing this
4682            // for packages -- app widgets are not currently cleaned up for
4683            // such packages, so they can be left with bad pending intents.
4684            if (mIntentSenderRecords.size() > 0) {
4685                Iterator<WeakReference<PendingIntentRecord>> it
4686                        = mIntentSenderRecords.values().iterator();
4687                while (it.hasNext()) {
4688                    WeakReference<PendingIntentRecord> wpir = it.next();
4689                    if (wpir == null) {
4690                        it.remove();
4691                        continue;
4692                    }
4693                    PendingIntentRecord pir = wpir.get();
4694                    if (pir == null) {
4695                        it.remove();
4696                        continue;
4697                    }
4698                    if (name == null) {
4699                        // Stopping user, remove all objects for the user.
4700                        if (pir.key.userId != userId) {
4701                            // Not the same user, skip it.
4702                            continue;
4703                        }
4704                    } else {
4705                        if (UserHandle.getAppId(pir.uid) != appId) {
4706                            // Different app id, skip it.
4707                            continue;
4708                        }
4709                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4710                            // Different user, skip it.
4711                            continue;
4712                        }
4713                        if (!pir.key.packageName.equals(name)) {
4714                            // Different package, skip it.
4715                            continue;
4716                        }
4717                    }
4718                    if (!doit) {
4719                        return true;
4720                    }
4721                    didSomething = true;
4722                    it.remove();
4723                    pir.canceled = true;
4724                    if (pir.key.activity != null) {
4725                        pir.key.activity.pendingResults.remove(pir.ref);
4726                    }
4727                }
4728            }
4729        }
4730
4731        if (doit) {
4732            if (purgeCache && name != null) {
4733                AttributeCache ac = AttributeCache.instance();
4734                if (ac != null) {
4735                    ac.removePackage(name);
4736                }
4737            }
4738            if (mBooted) {
4739                mStackSupervisor.resumeTopActivitiesLocked();
4740                mStackSupervisor.scheduleIdleLocked();
4741            }
4742        }
4743
4744        return didSomething;
4745    }
4746
4747    private final boolean removeProcessLocked(ProcessRecord app,
4748            boolean callerWillRestart, boolean allowRestart, String reason) {
4749        final String name = app.processName;
4750        final int uid = app.uid;
4751        if (DEBUG_PROCESSES) Slog.d(
4752            TAG, "Force removing proc " + app.toShortString() + " (" + name
4753            + "/" + uid + ")");
4754
4755        mProcessNames.remove(name, uid);
4756        mIsolatedProcesses.remove(app.uid);
4757        if (mHeavyWeightProcess == app) {
4758            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4759                    mHeavyWeightProcess.userId, 0));
4760            mHeavyWeightProcess = null;
4761        }
4762        boolean needRestart = false;
4763        if (app.pid > 0 && app.pid != MY_PID) {
4764            int pid = app.pid;
4765            synchronized (mPidsSelfLocked) {
4766                mPidsSelfLocked.remove(pid);
4767                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4768            }
4769            killUnneededProcessLocked(app, reason);
4770            handleAppDiedLocked(app, true, allowRestart);
4771            removeLruProcessLocked(app);
4772
4773            if (app.persistent && !app.isolated) {
4774                if (!callerWillRestart) {
4775                    addAppLocked(app.info, false, null /* ABI override */);
4776                } else {
4777                    needRestart = true;
4778                }
4779            }
4780        } else {
4781            mRemovedProcesses.add(app);
4782        }
4783
4784        return needRestart;
4785    }
4786
4787    private final void processStartTimedOutLocked(ProcessRecord app) {
4788        final int pid = app.pid;
4789        boolean gone = false;
4790        synchronized (mPidsSelfLocked) {
4791            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4792            if (knownApp != null && knownApp.thread == null) {
4793                mPidsSelfLocked.remove(pid);
4794                gone = true;
4795            }
4796        }
4797
4798        if (gone) {
4799            Slog.w(TAG, "Process " + app + " failed to attach");
4800            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4801                    pid, app.uid, app.processName);
4802            mProcessNames.remove(app.processName, app.uid);
4803            mIsolatedProcesses.remove(app.uid);
4804            if (mHeavyWeightProcess == app) {
4805                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4806                        mHeavyWeightProcess.userId, 0));
4807                mHeavyWeightProcess = null;
4808            }
4809            // Take care of any launching providers waiting for this process.
4810            checkAppInLaunchingProvidersLocked(app, true);
4811            // Take care of any services that are waiting for the process.
4812            mServices.processStartTimedOutLocked(app);
4813            killUnneededProcessLocked(app, "start timeout");
4814            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4815                Slog.w(TAG, "Unattached app died before backup, skipping");
4816                try {
4817                    IBackupManager bm = IBackupManager.Stub.asInterface(
4818                            ServiceManager.getService(Context.BACKUP_SERVICE));
4819                    bm.agentDisconnected(app.info.packageName);
4820                } catch (RemoteException e) {
4821                    // Can't happen; the backup manager is local
4822                }
4823            }
4824            if (isPendingBroadcastProcessLocked(pid)) {
4825                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4826                skipPendingBroadcastLocked(pid);
4827            }
4828        } else {
4829            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4830        }
4831    }
4832
4833    private final boolean attachApplicationLocked(IApplicationThread thread,
4834            int pid) {
4835
4836        // Find the application record that is being attached...  either via
4837        // the pid if we are running in multiple processes, or just pull the
4838        // next app record if we are emulating process with anonymous threads.
4839        ProcessRecord app;
4840        if (pid != MY_PID && pid >= 0) {
4841            synchronized (mPidsSelfLocked) {
4842                app = mPidsSelfLocked.get(pid);
4843            }
4844        } else {
4845            app = null;
4846        }
4847
4848        if (app == null) {
4849            Slog.w(TAG, "No pending application record for pid " + pid
4850                    + " (IApplicationThread " + thread + "); dropping process");
4851            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4852            if (pid > 0 && pid != MY_PID) {
4853                Process.killProcessQuiet(pid);
4854            } else {
4855                try {
4856                    thread.scheduleExit();
4857                } catch (Exception e) {
4858                    // Ignore exceptions.
4859                }
4860            }
4861            return false;
4862        }
4863
4864        // If this application record is still attached to a previous
4865        // process, clean it up now.
4866        if (app.thread != null) {
4867            handleAppDiedLocked(app, true, true);
4868        }
4869
4870        // Tell the process all about itself.
4871
4872        if (localLOGV) Slog.v(
4873                TAG, "Binding process pid " + pid + " to record " + app);
4874
4875        final String processName = app.processName;
4876        try {
4877            AppDeathRecipient adr = new AppDeathRecipient(
4878                    app, pid, thread);
4879            thread.asBinder().linkToDeath(adr, 0);
4880            app.deathRecipient = adr;
4881        } catch (RemoteException e) {
4882            app.resetPackageList(mProcessStats);
4883            startProcessLocked(app, "link fail", processName, null /* ABI override */);
4884            return false;
4885        }
4886
4887        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4888
4889        app.makeActive(thread, mProcessStats);
4890        app.curAdj = app.setAdj = -100;
4891        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4892        app.forcingToForeground = null;
4893        app.foregroundServices = false;
4894        app.hasShownUi = false;
4895        app.debugging = false;
4896        app.cached = false;
4897
4898        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4899
4900        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4901        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4902
4903        if (!normalMode) {
4904            Slog.i(TAG, "Launching preboot mode app: " + app);
4905        }
4906
4907        if (localLOGV) Slog.v(
4908            TAG, "New app record " + app
4909            + " thread=" + thread.asBinder() + " pid=" + pid);
4910        try {
4911            int testMode = IApplicationThread.DEBUG_OFF;
4912            if (mDebugApp != null && mDebugApp.equals(processName)) {
4913                testMode = mWaitForDebugger
4914                    ? IApplicationThread.DEBUG_WAIT
4915                    : IApplicationThread.DEBUG_ON;
4916                app.debugging = true;
4917                if (mDebugTransient) {
4918                    mDebugApp = mOrigDebugApp;
4919                    mWaitForDebugger = mOrigWaitForDebugger;
4920                }
4921            }
4922            String profileFile = app.instrumentationProfileFile;
4923            ParcelFileDescriptor profileFd = null;
4924            boolean profileAutoStop = false;
4925            if (mProfileApp != null && mProfileApp.equals(processName)) {
4926                mProfileProc = app;
4927                profileFile = mProfileFile;
4928                profileFd = mProfileFd;
4929                profileAutoStop = mAutoStopProfiler;
4930            }
4931            boolean enableOpenGlTrace = false;
4932            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4933                enableOpenGlTrace = true;
4934                mOpenGlTraceApp = null;
4935            }
4936
4937            // If the app is being launched for restore or full backup, set it up specially
4938            boolean isRestrictedBackupMode = false;
4939            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4940                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4941                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4942                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4943            }
4944
4945            ensurePackageDexOpt(app.instrumentationInfo != null
4946                    ? app.instrumentationInfo.packageName
4947                    : app.info.packageName);
4948            if (app.instrumentationClass != null) {
4949                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4950            }
4951            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4952                    + processName + " with config " + mConfiguration);
4953            ApplicationInfo appInfo = app.instrumentationInfo != null
4954                    ? app.instrumentationInfo : app.info;
4955            app.compat = compatibilityInfoForPackageLocked(appInfo);
4956            if (profileFd != null) {
4957                profileFd = profileFd.dup();
4958            }
4959            thread.bindApplication(processName, appInfo, providers,
4960                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4961                    app.instrumentationArguments, app.instrumentationWatcher,
4962                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4963                    isRestrictedBackupMode || !normalMode, app.persistent,
4964                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4965                    mCoreSettingsObserver.getCoreSettingsLocked());
4966            updateLruProcessLocked(app, false, null);
4967            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4968        } catch (Exception e) {
4969            // todo: Yikes!  What should we do?  For now we will try to
4970            // start another process, but that could easily get us in
4971            // an infinite loop of restarting processes...
4972            Slog.w(TAG, "Exception thrown during bind!", e);
4973
4974            app.resetPackageList(mProcessStats);
4975            app.unlinkDeathRecipient();
4976            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
4977            return false;
4978        }
4979
4980        // Remove this record from the list of starting applications.
4981        mPersistentStartingProcesses.remove(app);
4982        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4983                "Attach application locked removing on hold: " + app);
4984        mProcessesOnHold.remove(app);
4985
4986        boolean badApp = false;
4987        boolean didSomething = false;
4988
4989        // See if the top visible activity is waiting to run in this process...
4990        if (normalMode) {
4991            try {
4992                if (mStackSupervisor.attachApplicationLocked(app)) {
4993                    didSomething = true;
4994                }
4995            } catch (Exception e) {
4996                badApp = true;
4997            }
4998        }
4999
5000        // Find any services that should be running in this process...
5001        if (!badApp) {
5002            try {
5003                didSomething |= mServices.attachApplicationLocked(app, processName);
5004            } catch (Exception e) {
5005                badApp = true;
5006            }
5007        }
5008
5009        // Check if a next-broadcast receiver is in this process...
5010        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5011            try {
5012                didSomething |= sendPendingBroadcastsLocked(app);
5013            } catch (Exception e) {
5014                // If the app died trying to launch the receiver we declare it 'bad'
5015                badApp = true;
5016            }
5017        }
5018
5019        // Check whether the next backup agent is in this process...
5020        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5021            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5022            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5023            try {
5024                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5025                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5026                        mBackupTarget.backupMode);
5027            } catch (Exception e) {
5028                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5029                e.printStackTrace();
5030            }
5031        }
5032
5033        if (badApp) {
5034            // todo: Also need to kill application to deal with all
5035            // kinds of exceptions.
5036            handleAppDiedLocked(app, false, true);
5037            return false;
5038        }
5039
5040        if (!didSomething) {
5041            updateOomAdjLocked();
5042        }
5043
5044        return true;
5045    }
5046
5047    @Override
5048    public final void attachApplication(IApplicationThread thread) {
5049        synchronized (this) {
5050            int callingPid = Binder.getCallingPid();
5051            final long origId = Binder.clearCallingIdentity();
5052            attachApplicationLocked(thread, callingPid);
5053            Binder.restoreCallingIdentity(origId);
5054        }
5055    }
5056
5057    @Override
5058    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5059        final long origId = Binder.clearCallingIdentity();
5060        synchronized (this) {
5061            ActivityStack stack = ActivityRecord.getStackLocked(token);
5062            if (stack != null) {
5063                ActivityRecord r =
5064                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5065                if (stopProfiling) {
5066                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5067                        try {
5068                            mProfileFd.close();
5069                        } catch (IOException e) {
5070                        }
5071                        clearProfilerLocked();
5072                    }
5073                }
5074            }
5075        }
5076        Binder.restoreCallingIdentity(origId);
5077    }
5078
5079    void enableScreenAfterBoot() {
5080        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5081                SystemClock.uptimeMillis());
5082        mWindowManager.enableScreenAfterBoot();
5083
5084        synchronized (this) {
5085            updateEventDispatchingLocked();
5086        }
5087    }
5088
5089    @Override
5090    public void showBootMessage(final CharSequence msg, final boolean always) {
5091        enforceNotIsolatedCaller("showBootMessage");
5092        mWindowManager.showBootMessage(msg, always);
5093    }
5094
5095    @Override
5096    public void dismissKeyguardOnNextActivity() {
5097        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5098        final long token = Binder.clearCallingIdentity();
5099        try {
5100            synchronized (this) {
5101                if (DEBUG_LOCKSCREEN) logLockScreen("");
5102                if (mLockScreenShown) {
5103                    mLockScreenShown = false;
5104                    comeOutOfSleepIfNeededLocked();
5105                }
5106                mStackSupervisor.setDismissKeyguard(true);
5107            }
5108        } finally {
5109            Binder.restoreCallingIdentity(token);
5110        }
5111    }
5112
5113    final void finishBooting() {
5114        IntentFilter pkgFilter = new IntentFilter();
5115        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5116        pkgFilter.addDataScheme("package");
5117        mContext.registerReceiver(new BroadcastReceiver() {
5118            @Override
5119            public void onReceive(Context context, Intent intent) {
5120                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5121                if (pkgs != null) {
5122                    for (String pkg : pkgs) {
5123                        synchronized (ActivityManagerService.this) {
5124                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0,
5125                                    "finished booting")) {
5126                                setResultCode(Activity.RESULT_OK);
5127                                return;
5128                            }
5129                        }
5130                    }
5131                }
5132            }
5133        }, pkgFilter);
5134
5135        synchronized (this) {
5136            // Ensure that any processes we had put on hold are now started
5137            // up.
5138            final int NP = mProcessesOnHold.size();
5139            if (NP > 0) {
5140                ArrayList<ProcessRecord> procs =
5141                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5142                for (int ip=0; ip<NP; ip++) {
5143                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5144                            + procs.get(ip));
5145                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5146                }
5147            }
5148
5149            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5150                // Start looking for apps that are abusing wake locks.
5151                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5152                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5153                // Tell anyone interested that we are done booting!
5154                SystemProperties.set("sys.boot_completed", "1");
5155                SystemProperties.set("dev.bootcomplete", "1");
5156                for (int i=0; i<mStartedUsers.size(); i++) {
5157                    UserStartedState uss = mStartedUsers.valueAt(i);
5158                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5159                        uss.mState = UserStartedState.STATE_RUNNING;
5160                        final int userId = mStartedUsers.keyAt(i);
5161                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5162                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5163                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5164                        broadcastIntentLocked(null, null, intent, null,
5165                                new IIntentReceiver.Stub() {
5166                                    @Override
5167                                    public void performReceive(Intent intent, int resultCode,
5168                                            String data, Bundle extras, boolean ordered,
5169                                            boolean sticky, int sendingUser) {
5170                                        synchronized (ActivityManagerService.this) {
5171                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5172                                                    true, false);
5173                                        }
5174                                    }
5175                                },
5176                                0, null, null,
5177                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5178                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5179                                userId);
5180                    }
5181                }
5182            }
5183        }
5184    }
5185
5186    final void ensureBootCompleted() {
5187        boolean booting;
5188        boolean enableScreen;
5189        synchronized (this) {
5190            booting = mBooting;
5191            mBooting = false;
5192            enableScreen = !mBooted;
5193            mBooted = true;
5194        }
5195
5196        if (booting) {
5197            finishBooting();
5198        }
5199
5200        if (enableScreen) {
5201            enableScreenAfterBoot();
5202        }
5203    }
5204
5205    @Override
5206    public final void activityResumed(IBinder token) {
5207        final long origId = Binder.clearCallingIdentity();
5208        synchronized(this) {
5209            ActivityStack stack = ActivityRecord.getStackLocked(token);
5210            if (stack != null) {
5211                ActivityRecord.activityResumedLocked(token);
5212            }
5213        }
5214        Binder.restoreCallingIdentity(origId);
5215    }
5216
5217    @Override
5218    public final void activityPaused(IBinder token) {
5219        final long origId = Binder.clearCallingIdentity();
5220        synchronized(this) {
5221            ActivityStack stack = ActivityRecord.getStackLocked(token);
5222            if (stack != null) {
5223                stack.activityPausedLocked(token, false);
5224            }
5225        }
5226        Binder.restoreCallingIdentity(origId);
5227    }
5228
5229    @Override
5230    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5231            CharSequence description) {
5232        if (localLOGV) Slog.v(
5233            TAG, "Activity stopped: token=" + token);
5234
5235        // Refuse possible leaked file descriptors
5236        if (icicle != null && icicle.hasFileDescriptors()) {
5237            throw new IllegalArgumentException("File descriptors passed in Bundle");
5238        }
5239
5240        ActivityRecord r = null;
5241
5242        final long origId = Binder.clearCallingIdentity();
5243
5244        synchronized (this) {
5245            r = ActivityRecord.isInStackLocked(token);
5246            if (r != null) {
5247                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5248            }
5249        }
5250
5251        if (r != null) {
5252            sendPendingThumbnail(r, null, null, null, false);
5253        }
5254
5255        trimApplications();
5256
5257        Binder.restoreCallingIdentity(origId);
5258    }
5259
5260    @Override
5261    public final void activityDestroyed(IBinder token) {
5262        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5263        synchronized (this) {
5264            ActivityStack stack = ActivityRecord.getStackLocked(token);
5265            if (stack != null) {
5266                stack.activityDestroyedLocked(token);
5267            }
5268        }
5269    }
5270
5271    @Override
5272    public String getCallingPackage(IBinder token) {
5273        synchronized (this) {
5274            ActivityRecord r = getCallingRecordLocked(token);
5275            return r != null ? r.info.packageName : null;
5276        }
5277    }
5278
5279    @Override
5280    public ComponentName getCallingActivity(IBinder token) {
5281        synchronized (this) {
5282            ActivityRecord r = getCallingRecordLocked(token);
5283            return r != null ? r.intent.getComponent() : null;
5284        }
5285    }
5286
5287    private ActivityRecord getCallingRecordLocked(IBinder token) {
5288        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5289        if (r == null) {
5290            return null;
5291        }
5292        return r.resultTo;
5293    }
5294
5295    @Override
5296    public ComponentName getActivityClassForToken(IBinder token) {
5297        synchronized(this) {
5298            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5299            if (r == null) {
5300                return null;
5301            }
5302            return r.intent.getComponent();
5303        }
5304    }
5305
5306    @Override
5307    public String getPackageForToken(IBinder token) {
5308        synchronized(this) {
5309            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5310            if (r == null) {
5311                return null;
5312            }
5313            return r.packageName;
5314        }
5315    }
5316
5317    @Override
5318    public IIntentSender getIntentSender(int type,
5319            String packageName, IBinder token, String resultWho,
5320            int requestCode, Intent[] intents, String[] resolvedTypes,
5321            int flags, Bundle options, int userId) {
5322        enforceNotIsolatedCaller("getIntentSender");
5323        // Refuse possible leaked file descriptors
5324        if (intents != null) {
5325            if (intents.length < 1) {
5326                throw new IllegalArgumentException("Intents array length must be >= 1");
5327            }
5328            for (int i=0; i<intents.length; i++) {
5329                Intent intent = intents[i];
5330                if (intent != null) {
5331                    if (intent.hasFileDescriptors()) {
5332                        throw new IllegalArgumentException("File descriptors passed in Intent");
5333                    }
5334                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5335                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5336                        throw new IllegalArgumentException(
5337                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5338                    }
5339                    intents[i] = new Intent(intent);
5340                }
5341            }
5342            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5343                throw new IllegalArgumentException(
5344                        "Intent array length does not match resolvedTypes length");
5345            }
5346        }
5347        if (options != null) {
5348            if (options.hasFileDescriptors()) {
5349                throw new IllegalArgumentException("File descriptors passed in options");
5350            }
5351        }
5352
5353        synchronized(this) {
5354            int callingUid = Binder.getCallingUid();
5355            int origUserId = userId;
5356            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5357                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5358                    "getIntentSender", null);
5359            if (origUserId == UserHandle.USER_CURRENT) {
5360                // We don't want to evaluate this until the pending intent is
5361                // actually executed.  However, we do want to always do the
5362                // security checking for it above.
5363                userId = UserHandle.USER_CURRENT;
5364            }
5365            try {
5366                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5367                    int uid = AppGlobals.getPackageManager()
5368                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5369                    if (!UserHandle.isSameApp(callingUid, uid)) {
5370                        String msg = "Permission Denial: getIntentSender() from pid="
5371                            + Binder.getCallingPid()
5372                            + ", uid=" + Binder.getCallingUid()
5373                            + ", (need uid=" + uid + ")"
5374                            + " is not allowed to send as package " + packageName;
5375                        Slog.w(TAG, msg);
5376                        throw new SecurityException(msg);
5377                    }
5378                }
5379
5380                return getIntentSenderLocked(type, packageName, callingUid, userId,
5381                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5382
5383            } catch (RemoteException e) {
5384                throw new SecurityException(e);
5385            }
5386        }
5387    }
5388
5389    IIntentSender getIntentSenderLocked(int type, String packageName,
5390            int callingUid, int userId, IBinder token, String resultWho,
5391            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5392            Bundle options) {
5393        if (DEBUG_MU)
5394            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5395        ActivityRecord activity = null;
5396        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5397            activity = ActivityRecord.isInStackLocked(token);
5398            if (activity == null) {
5399                return null;
5400            }
5401            if (activity.finishing) {
5402                return null;
5403            }
5404        }
5405
5406        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5407        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5408        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5409        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5410                |PendingIntent.FLAG_UPDATE_CURRENT);
5411
5412        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5413                type, packageName, activity, resultWho,
5414                requestCode, intents, resolvedTypes, flags, options, userId);
5415        WeakReference<PendingIntentRecord> ref;
5416        ref = mIntentSenderRecords.get(key);
5417        PendingIntentRecord rec = ref != null ? ref.get() : null;
5418        if (rec != null) {
5419            if (!cancelCurrent) {
5420                if (updateCurrent) {
5421                    if (rec.key.requestIntent != null) {
5422                        rec.key.requestIntent.replaceExtras(intents != null ?
5423                                intents[intents.length - 1] : null);
5424                    }
5425                    if (intents != null) {
5426                        intents[intents.length-1] = rec.key.requestIntent;
5427                        rec.key.allIntents = intents;
5428                        rec.key.allResolvedTypes = resolvedTypes;
5429                    } else {
5430                        rec.key.allIntents = null;
5431                        rec.key.allResolvedTypes = null;
5432                    }
5433                }
5434                return rec;
5435            }
5436            rec.canceled = true;
5437            mIntentSenderRecords.remove(key);
5438        }
5439        if (noCreate) {
5440            return rec;
5441        }
5442        rec = new PendingIntentRecord(this, key, callingUid);
5443        mIntentSenderRecords.put(key, rec.ref);
5444        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5445            if (activity.pendingResults == null) {
5446                activity.pendingResults
5447                        = new HashSet<WeakReference<PendingIntentRecord>>();
5448            }
5449            activity.pendingResults.add(rec.ref);
5450        }
5451        return rec;
5452    }
5453
5454    @Override
5455    public void cancelIntentSender(IIntentSender sender) {
5456        if (!(sender instanceof PendingIntentRecord)) {
5457            return;
5458        }
5459        synchronized(this) {
5460            PendingIntentRecord rec = (PendingIntentRecord)sender;
5461            try {
5462                int uid = AppGlobals.getPackageManager()
5463                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5464                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5465                    String msg = "Permission Denial: cancelIntentSender() from pid="
5466                        + Binder.getCallingPid()
5467                        + ", uid=" + Binder.getCallingUid()
5468                        + " is not allowed to cancel packges "
5469                        + rec.key.packageName;
5470                    Slog.w(TAG, msg);
5471                    throw new SecurityException(msg);
5472                }
5473            } catch (RemoteException e) {
5474                throw new SecurityException(e);
5475            }
5476            cancelIntentSenderLocked(rec, true);
5477        }
5478    }
5479
5480    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5481        rec.canceled = true;
5482        mIntentSenderRecords.remove(rec.key);
5483        if (cleanActivity && rec.key.activity != null) {
5484            rec.key.activity.pendingResults.remove(rec.ref);
5485        }
5486    }
5487
5488    @Override
5489    public String getPackageForIntentSender(IIntentSender pendingResult) {
5490        if (!(pendingResult instanceof PendingIntentRecord)) {
5491            return null;
5492        }
5493        try {
5494            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5495            return res.key.packageName;
5496        } catch (ClassCastException e) {
5497        }
5498        return null;
5499    }
5500
5501    @Override
5502    public int getUidForIntentSender(IIntentSender sender) {
5503        if (sender instanceof PendingIntentRecord) {
5504            try {
5505                PendingIntentRecord res = (PendingIntentRecord)sender;
5506                return res.uid;
5507            } catch (ClassCastException e) {
5508            }
5509        }
5510        return -1;
5511    }
5512
5513    @Override
5514    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5515        if (!(pendingResult instanceof PendingIntentRecord)) {
5516            return false;
5517        }
5518        try {
5519            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5520            if (res.key.allIntents == null) {
5521                return false;
5522            }
5523            for (int i=0; i<res.key.allIntents.length; i++) {
5524                Intent intent = res.key.allIntents[i];
5525                if (intent.getPackage() != null && intent.getComponent() != null) {
5526                    return false;
5527                }
5528            }
5529            return true;
5530        } catch (ClassCastException e) {
5531        }
5532        return false;
5533    }
5534
5535    @Override
5536    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5537        if (!(pendingResult instanceof PendingIntentRecord)) {
5538            return false;
5539        }
5540        try {
5541            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5542            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5543                return true;
5544            }
5545            return false;
5546        } catch (ClassCastException e) {
5547        }
5548        return false;
5549    }
5550
5551    @Override
5552    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5553        if (!(pendingResult instanceof PendingIntentRecord)) {
5554            return null;
5555        }
5556        try {
5557            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5558            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5559        } catch (ClassCastException e) {
5560        }
5561        return null;
5562    }
5563
5564    @Override
5565    public void setProcessLimit(int max) {
5566        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5567                "setProcessLimit()");
5568        synchronized (this) {
5569            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5570            mProcessLimitOverride = max;
5571        }
5572        trimApplications();
5573    }
5574
5575    @Override
5576    public int getProcessLimit() {
5577        synchronized (this) {
5578            return mProcessLimitOverride;
5579        }
5580    }
5581
5582    void foregroundTokenDied(ForegroundToken token) {
5583        synchronized (ActivityManagerService.this) {
5584            synchronized (mPidsSelfLocked) {
5585                ForegroundToken cur
5586                    = mForegroundProcesses.get(token.pid);
5587                if (cur != token) {
5588                    return;
5589                }
5590                mForegroundProcesses.remove(token.pid);
5591                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5592                if (pr == null) {
5593                    return;
5594                }
5595                pr.forcingToForeground = null;
5596                pr.foregroundServices = false;
5597            }
5598            updateOomAdjLocked();
5599        }
5600    }
5601
5602    @Override
5603    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5604        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5605                "setProcessForeground()");
5606        synchronized(this) {
5607            boolean changed = false;
5608
5609            synchronized (mPidsSelfLocked) {
5610                ProcessRecord pr = mPidsSelfLocked.get(pid);
5611                if (pr == null && isForeground) {
5612                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5613                    return;
5614                }
5615                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5616                if (oldToken != null) {
5617                    oldToken.token.unlinkToDeath(oldToken, 0);
5618                    mForegroundProcesses.remove(pid);
5619                    if (pr != null) {
5620                        pr.forcingToForeground = null;
5621                    }
5622                    changed = true;
5623                }
5624                if (isForeground && token != null) {
5625                    ForegroundToken newToken = new ForegroundToken() {
5626                        @Override
5627                        public void binderDied() {
5628                            foregroundTokenDied(this);
5629                        }
5630                    };
5631                    newToken.pid = pid;
5632                    newToken.token = token;
5633                    try {
5634                        token.linkToDeath(newToken, 0);
5635                        mForegroundProcesses.put(pid, newToken);
5636                        pr.forcingToForeground = token;
5637                        changed = true;
5638                    } catch (RemoteException e) {
5639                        // If the process died while doing this, we will later
5640                        // do the cleanup with the process death link.
5641                    }
5642                }
5643            }
5644
5645            if (changed) {
5646                updateOomAdjLocked();
5647            }
5648        }
5649    }
5650
5651    // =========================================================
5652    // PERMISSIONS
5653    // =========================================================
5654
5655    static class PermissionController extends IPermissionController.Stub {
5656        ActivityManagerService mActivityManagerService;
5657        PermissionController(ActivityManagerService activityManagerService) {
5658            mActivityManagerService = activityManagerService;
5659        }
5660
5661        @Override
5662        public boolean checkPermission(String permission, int pid, int uid) {
5663            return mActivityManagerService.checkPermission(permission, pid,
5664                    uid) == PackageManager.PERMISSION_GRANTED;
5665        }
5666    }
5667
5668    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5669        @Override
5670        public int checkComponentPermission(String permission, int pid, int uid,
5671                int owningUid, boolean exported) {
5672            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5673                    owningUid, exported);
5674        }
5675
5676        @Override
5677        public Object getAMSLock() {
5678            return ActivityManagerService.this;
5679        }
5680    }
5681
5682    /**
5683     * This can be called with or without the global lock held.
5684     */
5685    int checkComponentPermission(String permission, int pid, int uid,
5686            int owningUid, boolean exported) {
5687        // We might be performing an operation on behalf of an indirect binder
5688        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5689        // client identity accordingly before proceeding.
5690        Identity tlsIdentity = sCallerIdentity.get();
5691        if (tlsIdentity != null) {
5692            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5693                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5694            uid = tlsIdentity.uid;
5695            pid = tlsIdentity.pid;
5696        }
5697
5698        if (pid == MY_PID) {
5699            return PackageManager.PERMISSION_GRANTED;
5700        }
5701
5702        return ActivityManager.checkComponentPermission(permission, uid,
5703                owningUid, exported);
5704    }
5705
5706    /**
5707     * As the only public entry point for permissions checking, this method
5708     * can enforce the semantic that requesting a check on a null global
5709     * permission is automatically denied.  (Internally a null permission
5710     * string is used when calling {@link #checkComponentPermission} in cases
5711     * when only uid-based security is needed.)
5712     *
5713     * This can be called with or without the global lock held.
5714     */
5715    @Override
5716    public int checkPermission(String permission, int pid, int uid) {
5717        if (permission == null) {
5718            return PackageManager.PERMISSION_DENIED;
5719        }
5720        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5721    }
5722
5723    /**
5724     * Binder IPC calls go through the public entry point.
5725     * This can be called with or without the global lock held.
5726     */
5727    int checkCallingPermission(String permission) {
5728        return checkPermission(permission,
5729                Binder.getCallingPid(),
5730                UserHandle.getAppId(Binder.getCallingUid()));
5731    }
5732
5733    /**
5734     * This can be called with or without the global lock held.
5735     */
5736    void enforceCallingPermission(String permission, String func) {
5737        if (checkCallingPermission(permission)
5738                == PackageManager.PERMISSION_GRANTED) {
5739            return;
5740        }
5741
5742        String msg = "Permission Denial: " + func + " from pid="
5743                + Binder.getCallingPid()
5744                + ", uid=" + Binder.getCallingUid()
5745                + " requires " + permission;
5746        Slog.w(TAG, msg);
5747        throw new SecurityException(msg);
5748    }
5749
5750    /**
5751     * Determine if UID is holding permissions required to access {@link Uri} in
5752     * the given {@link ProviderInfo}. Final permission checking is always done
5753     * in {@link ContentProvider}.
5754     */
5755    private final boolean checkHoldingPermissionsLocked(
5756            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5757        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5758                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5759
5760        if (pi.applicationInfo.uid == uid) {
5761            return true;
5762        } else if (!pi.exported) {
5763            return false;
5764        }
5765
5766        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5767        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5768        try {
5769            // check if target holds top-level <provider> permissions
5770            if (!readMet && pi.readPermission != null
5771                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5772                readMet = true;
5773            }
5774            if (!writeMet && pi.writePermission != null
5775                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5776                writeMet = true;
5777            }
5778
5779            // track if unprotected read/write is allowed; any denied
5780            // <path-permission> below removes this ability
5781            boolean allowDefaultRead = pi.readPermission == null;
5782            boolean allowDefaultWrite = pi.writePermission == null;
5783
5784            // check if target holds any <path-permission> that match uri
5785            final PathPermission[] pps = pi.pathPermissions;
5786            if (pps != null) {
5787                final String path = uri.getPath();
5788                int i = pps.length;
5789                while (i > 0 && (!readMet || !writeMet)) {
5790                    i--;
5791                    PathPermission pp = pps[i];
5792                    if (pp.match(path)) {
5793                        if (!readMet) {
5794                            final String pprperm = pp.getReadPermission();
5795                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5796                                    + pprperm + " for " + pp.getPath()
5797                                    + ": match=" + pp.match(path)
5798                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5799                            if (pprperm != null) {
5800                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5801                                    readMet = true;
5802                                } else {
5803                                    allowDefaultRead = false;
5804                                }
5805                            }
5806                        }
5807                        if (!writeMet) {
5808                            final String ppwperm = pp.getWritePermission();
5809                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5810                                    + ppwperm + " for " + pp.getPath()
5811                                    + ": match=" + pp.match(path)
5812                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5813                            if (ppwperm != null) {
5814                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5815                                    writeMet = true;
5816                                } else {
5817                                    allowDefaultWrite = false;
5818                                }
5819                            }
5820                        }
5821                    }
5822                }
5823            }
5824
5825            // grant unprotected <provider> read/write, if not blocked by
5826            // <path-permission> above
5827            if (allowDefaultRead) readMet = true;
5828            if (allowDefaultWrite) writeMet = true;
5829
5830        } catch (RemoteException e) {
5831            return false;
5832        }
5833
5834        return readMet && writeMet;
5835    }
5836
5837    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5838        ProviderInfo pi = null;
5839        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5840        if (cpr != null) {
5841            pi = cpr.info;
5842        } else {
5843            try {
5844                pi = AppGlobals.getPackageManager().resolveContentProvider(
5845                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5846            } catch (RemoteException ex) {
5847            }
5848        }
5849        return pi;
5850    }
5851
5852    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5853        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5854        if (targetUris != null) {
5855            return targetUris.get(uri);
5856        } else {
5857            return null;
5858        }
5859    }
5860
5861    private UriPermission findOrCreateUriPermissionLocked(
5862            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5863        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5864        if (targetUris == null) {
5865            targetUris = Maps.newArrayMap();
5866            mGrantedUriPermissions.put(targetUid, targetUris);
5867        }
5868
5869        UriPermission perm = targetUris.get(uri);
5870        if (perm == null) {
5871            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5872            targetUris.put(uri, perm);
5873        }
5874
5875        return perm;
5876    }
5877
5878    private final boolean checkUriPermissionLocked(
5879            Uri uri, int uid, int modeFlags, int minStrength) {
5880        // Root gets to do everything.
5881        if (uid == 0) {
5882            return true;
5883        }
5884        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5885        if (perms == null) return false;
5886        UriPermission perm = perms.get(uri);
5887        if (perm == null) return false;
5888        return perm.getStrength(modeFlags) >= minStrength;
5889    }
5890
5891    @Override
5892    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5893        enforceNotIsolatedCaller("checkUriPermission");
5894
5895        // Another redirected-binder-call permissions check as in
5896        // {@link checkComponentPermission}.
5897        Identity tlsIdentity = sCallerIdentity.get();
5898        if (tlsIdentity != null) {
5899            uid = tlsIdentity.uid;
5900            pid = tlsIdentity.pid;
5901        }
5902
5903        // Our own process gets to do everything.
5904        if (pid == MY_PID) {
5905            return PackageManager.PERMISSION_GRANTED;
5906        }
5907        synchronized(this) {
5908            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5909                    ? PackageManager.PERMISSION_GRANTED
5910                    : PackageManager.PERMISSION_DENIED;
5911        }
5912    }
5913
5914    /**
5915     * Check if the targetPkg can be granted permission to access uri by
5916     * the callingUid using the given modeFlags.  Throws a security exception
5917     * if callingUid is not allowed to do this.  Returns the uid of the target
5918     * if the URI permission grant should be performed; returns -1 if it is not
5919     * needed (for example targetPkg already has permission to access the URI).
5920     * If you already know the uid of the target, you can supply it in
5921     * lastTargetUid else set that to -1.
5922     */
5923    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5924            Uri uri, int modeFlags, int lastTargetUid) {
5925        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5926        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5927                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5928        if (modeFlags == 0) {
5929            return -1;
5930        }
5931
5932        if (targetPkg != null) {
5933            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5934                    "Checking grant " + targetPkg + " permission to " + uri);
5935        }
5936
5937        final IPackageManager pm = AppGlobals.getPackageManager();
5938
5939        // If this is not a content: uri, we can't do anything with it.
5940        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5941            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5942                    "Can't grant URI permission for non-content URI: " + uri);
5943            return -1;
5944        }
5945
5946        final String authority = uri.getAuthority();
5947        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5948        if (pi == null) {
5949            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5950            return -1;
5951        }
5952
5953        int targetUid = lastTargetUid;
5954        if (targetUid < 0 && targetPkg != null) {
5955            try {
5956                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5957                if (targetUid < 0) {
5958                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5959                            "Can't grant URI permission no uid for: " + targetPkg);
5960                    return -1;
5961                }
5962            } catch (RemoteException ex) {
5963                return -1;
5964            }
5965        }
5966
5967        if (targetUid >= 0) {
5968            // First...  does the target actually need this permission?
5969            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5970                // No need to grant the target this permission.
5971                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5972                        "Target " + targetPkg + " already has full permission to " + uri);
5973                return -1;
5974            }
5975        } else {
5976            // First...  there is no target package, so can anyone access it?
5977            boolean allowed = pi.exported;
5978            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5979                if (pi.readPermission != null) {
5980                    allowed = false;
5981                }
5982            }
5983            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5984                if (pi.writePermission != null) {
5985                    allowed = false;
5986                }
5987            }
5988            if (allowed) {
5989                return -1;
5990            }
5991        }
5992
5993        // Second...  is the provider allowing granting of URI permissions?
5994        if (!pi.grantUriPermissions) {
5995            throw new SecurityException("Provider " + pi.packageName
5996                    + "/" + pi.name
5997                    + " does not allow granting of Uri permissions (uri "
5998                    + uri + ")");
5999        }
6000        if (pi.uriPermissionPatterns != null) {
6001            final int N = pi.uriPermissionPatterns.length;
6002            boolean allowed = false;
6003            for (int i=0; i<N; i++) {
6004                if (pi.uriPermissionPatterns[i] != null
6005                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6006                    allowed = true;
6007                    break;
6008                }
6009            }
6010            if (!allowed) {
6011                throw new SecurityException("Provider " + pi.packageName
6012                        + "/" + pi.name
6013                        + " does not allow granting of permission to path of Uri "
6014                        + uri);
6015            }
6016        }
6017
6018        // Third...  does the caller itself have permission to access
6019        // this uri?
6020        if (callingUid != Process.myUid()) {
6021            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6022                // Require they hold a strong enough Uri permission
6023                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6024                        : UriPermission.STRENGTH_OWNED;
6025                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6026                    throw new SecurityException("Uid " + callingUid
6027                            + " does not have permission to uri " + uri);
6028                }
6029            }
6030        }
6031
6032        return targetUid;
6033    }
6034
6035    @Override
6036    public int checkGrantUriPermission(int callingUid, String targetPkg,
6037            Uri uri, int modeFlags) {
6038        enforceNotIsolatedCaller("checkGrantUriPermission");
6039        synchronized(this) {
6040            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6041        }
6042    }
6043
6044    void grantUriPermissionUncheckedLocked(
6045            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6046        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6047        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6048                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6049        if (modeFlags == 0) {
6050            return;
6051        }
6052
6053        // So here we are: the caller has the assumed permission
6054        // to the uri, and the target doesn't.  Let's now give this to
6055        // the target.
6056
6057        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6058                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6059
6060        final String authority = uri.getAuthority();
6061        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6062        if (pi == null) {
6063            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6064            return;
6065        }
6066
6067        final UriPermission perm = findOrCreateUriPermissionLocked(
6068                pi.packageName, targetPkg, targetUid, uri);
6069        perm.grantModes(modeFlags, persistable, owner);
6070    }
6071
6072    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6073            int modeFlags, UriPermissionOwner owner) {
6074        if (targetPkg == null) {
6075            throw new NullPointerException("targetPkg");
6076        }
6077
6078        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6079        if (targetUid < 0) {
6080            return;
6081        }
6082
6083        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6084    }
6085
6086    static class NeededUriGrants extends ArrayList<Uri> {
6087        final String targetPkg;
6088        final int targetUid;
6089        final int flags;
6090
6091        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6092            this.targetPkg = targetPkg;
6093            this.targetUid = targetUid;
6094            this.flags = flags;
6095        }
6096    }
6097
6098    /**
6099     * Like checkGrantUriPermissionLocked, but takes an Intent.
6100     */
6101    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6102            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6103        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6104                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6105                + " clip=" + (intent != null ? intent.getClipData() : null)
6106                + " from " + intent + "; flags=0x"
6107                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6108
6109        if (targetPkg == null) {
6110            throw new NullPointerException("targetPkg");
6111        }
6112
6113        if (intent == null) {
6114            return null;
6115        }
6116        Uri data = intent.getData();
6117        ClipData clip = intent.getClipData();
6118        if (data == null && clip == null) {
6119            return null;
6120        }
6121
6122        if (data != null) {
6123            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6124                mode, needed != null ? needed.targetUid : -1);
6125            if (targetUid > 0) {
6126                if (needed == null) {
6127                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6128                }
6129                needed.add(data);
6130            }
6131        }
6132        if (clip != null) {
6133            for (int i=0; i<clip.getItemCount(); i++) {
6134                Uri uri = clip.getItemAt(i).getUri();
6135                if (uri != null) {
6136                    int targetUid = -1;
6137                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6138                            mode, needed != null ? needed.targetUid : -1);
6139                    if (targetUid > 0) {
6140                        if (needed == null) {
6141                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6142                        }
6143                        needed.add(uri);
6144                    }
6145                } else {
6146                    Intent clipIntent = clip.getItemAt(i).getIntent();
6147                    if (clipIntent != null) {
6148                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6149                                callingUid, targetPkg, clipIntent, mode, needed);
6150                        if (newNeeded != null) {
6151                            needed = newNeeded;
6152                        }
6153                    }
6154                }
6155            }
6156        }
6157
6158        return needed;
6159    }
6160
6161    /**
6162     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6163     */
6164    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6165            UriPermissionOwner owner) {
6166        if (needed != null) {
6167            for (int i=0; i<needed.size(); i++) {
6168                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6169                        needed.get(i), needed.flags, owner);
6170            }
6171        }
6172    }
6173
6174    void grantUriPermissionFromIntentLocked(int callingUid,
6175            String targetPkg, Intent intent, UriPermissionOwner owner) {
6176        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6177                intent, intent != null ? intent.getFlags() : 0, null);
6178        if (needed == null) {
6179            return;
6180        }
6181
6182        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6183    }
6184
6185    @Override
6186    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6187            Uri uri, int modeFlags) {
6188        enforceNotIsolatedCaller("grantUriPermission");
6189        synchronized(this) {
6190            final ProcessRecord r = getRecordForAppLocked(caller);
6191            if (r == null) {
6192                throw new SecurityException("Unable to find app for caller "
6193                        + caller
6194                        + " when granting permission to uri " + uri);
6195            }
6196            if (targetPkg == null) {
6197                throw new IllegalArgumentException("null target");
6198            }
6199            if (uri == null) {
6200                throw new IllegalArgumentException("null uri");
6201            }
6202
6203            // Persistable only supported through Intents
6204            Preconditions.checkFlagsArgument(modeFlags,
6205                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6206
6207            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6208                    null);
6209        }
6210    }
6211
6212    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6213        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6214                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6215            ArrayMap<Uri, UriPermission> perms
6216                    = mGrantedUriPermissions.get(perm.targetUid);
6217            if (perms != null) {
6218                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6219                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6220                perms.remove(perm.uri);
6221                if (perms.size() == 0) {
6222                    mGrantedUriPermissions.remove(perm.targetUid);
6223                }
6224            }
6225        }
6226    }
6227
6228    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6229        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6230
6231        final IPackageManager pm = AppGlobals.getPackageManager();
6232        final String authority = uri.getAuthority();
6233        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6234        if (pi == null) {
6235            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6236            return;
6237        }
6238
6239        // Does the caller have this permission on the URI?
6240        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6241            // Right now, if you are not the original owner of the permission,
6242            // you are not allowed to revoke it.
6243            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6244                throw new SecurityException("Uid " + callingUid
6245                        + " does not have permission to uri " + uri);
6246            //}
6247        }
6248
6249        boolean persistChanged = false;
6250
6251        // Go through all of the permissions and remove any that match.
6252        final List<String> SEGMENTS = uri.getPathSegments();
6253        if (SEGMENTS != null) {
6254            final int NS = SEGMENTS.size();
6255            int N = mGrantedUriPermissions.size();
6256            for (int i=0; i<N; i++) {
6257                ArrayMap<Uri, UriPermission> perms
6258                        = mGrantedUriPermissions.valueAt(i);
6259                Iterator<UriPermission> it = perms.values().iterator();
6260            toploop:
6261                while (it.hasNext()) {
6262                    UriPermission perm = it.next();
6263                    Uri targetUri = perm.uri;
6264                    if (!authority.equals(targetUri.getAuthority())) {
6265                        continue;
6266                    }
6267                    List<String> targetSegments = targetUri.getPathSegments();
6268                    if (targetSegments == null) {
6269                        continue;
6270                    }
6271                    if (targetSegments.size() < NS) {
6272                        continue;
6273                    }
6274                    for (int j=0; j<NS; j++) {
6275                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6276                            continue toploop;
6277                        }
6278                    }
6279                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6280                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6281                    persistChanged |= perm.clearModes(modeFlags, true);
6282                    if (perm.modeFlags == 0) {
6283                        it.remove();
6284                    }
6285                }
6286                if (perms.size() == 0) {
6287                    mGrantedUriPermissions.remove(
6288                            mGrantedUriPermissions.keyAt(i));
6289                    N--;
6290                    i--;
6291                }
6292            }
6293        }
6294
6295        if (persistChanged) {
6296            schedulePersistUriGrants();
6297        }
6298    }
6299
6300    @Override
6301    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6302            int modeFlags) {
6303        enforceNotIsolatedCaller("revokeUriPermission");
6304        synchronized(this) {
6305            final ProcessRecord r = getRecordForAppLocked(caller);
6306            if (r == null) {
6307                throw new SecurityException("Unable to find app for caller "
6308                        + caller
6309                        + " when revoking permission to uri " + uri);
6310            }
6311            if (uri == null) {
6312                Slog.w(TAG, "revokeUriPermission: null uri");
6313                return;
6314            }
6315
6316            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6317                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6318            if (modeFlags == 0) {
6319                return;
6320            }
6321
6322            final IPackageManager pm = AppGlobals.getPackageManager();
6323            final String authority = uri.getAuthority();
6324            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6325            if (pi == null) {
6326                Slog.w(TAG, "No content provider found for permission revoke: "
6327                        + uri.toSafeString());
6328                return;
6329            }
6330
6331            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6332        }
6333    }
6334
6335    /**
6336     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6337     * given package.
6338     *
6339     * @param packageName Package name to match, or {@code null} to apply to all
6340     *            packages.
6341     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6342     *            to all users.
6343     * @param persistable If persistable grants should be removed.
6344     */
6345    private void removeUriPermissionsForPackageLocked(
6346            String packageName, int userHandle, boolean persistable) {
6347        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6348            throw new IllegalArgumentException("Must narrow by either package or user");
6349        }
6350
6351        boolean persistChanged = false;
6352
6353        final int size = mGrantedUriPermissions.size();
6354        for (int i = 0; i < size; i++) {
6355            // Only inspect grants matching user
6356            if (userHandle == UserHandle.USER_ALL
6357                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6358                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6359                        .values().iterator();
6360                while (it.hasNext()) {
6361                    final UriPermission perm = it.next();
6362
6363                    // Only inspect grants matching package
6364                    if (packageName == null || perm.sourcePkg.equals(packageName)
6365                            || perm.targetPkg.equals(packageName)) {
6366                        persistChanged |= perm.clearModes(~0, persistable);
6367
6368                        // Only remove when no modes remain; any persisted grants
6369                        // will keep this alive.
6370                        if (perm.modeFlags == 0) {
6371                            it.remove();
6372                        }
6373                    }
6374                }
6375            }
6376        }
6377
6378        if (persistChanged) {
6379            schedulePersistUriGrants();
6380        }
6381    }
6382
6383    @Override
6384    public IBinder newUriPermissionOwner(String name) {
6385        enforceNotIsolatedCaller("newUriPermissionOwner");
6386        synchronized(this) {
6387            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6388            return owner.getExternalTokenLocked();
6389        }
6390    }
6391
6392    @Override
6393    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6394            Uri uri, int modeFlags) {
6395        synchronized(this) {
6396            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6397            if (owner == null) {
6398                throw new IllegalArgumentException("Unknown owner: " + token);
6399            }
6400            if (fromUid != Binder.getCallingUid()) {
6401                if (Binder.getCallingUid() != Process.myUid()) {
6402                    // Only system code can grant URI permissions on behalf
6403                    // of other users.
6404                    throw new SecurityException("nice try");
6405                }
6406            }
6407            if (targetPkg == null) {
6408                throw new IllegalArgumentException("null target");
6409            }
6410            if (uri == null) {
6411                throw new IllegalArgumentException("null uri");
6412            }
6413
6414            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6415        }
6416    }
6417
6418    @Override
6419    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6420        synchronized(this) {
6421            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6422            if (owner == null) {
6423                throw new IllegalArgumentException("Unknown owner: " + token);
6424            }
6425
6426            if (uri == null) {
6427                owner.removeUriPermissionsLocked(mode);
6428            } else {
6429                owner.removeUriPermissionLocked(uri, mode);
6430            }
6431        }
6432    }
6433
6434    private void schedulePersistUriGrants() {
6435        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6436            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6437                    10 * DateUtils.SECOND_IN_MILLIS);
6438        }
6439    }
6440
6441    private void writeGrantedUriPermissions() {
6442        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6443
6444        // Snapshot permissions so we can persist without lock
6445        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6446        synchronized (this) {
6447            final int size = mGrantedUriPermissions.size();
6448            for (int i = 0 ; i < size; i++) {
6449                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6450                    if (perm.persistedModeFlags != 0) {
6451                        persist.add(perm.snapshot());
6452                    }
6453                }
6454            }
6455        }
6456
6457        FileOutputStream fos = null;
6458        try {
6459            fos = mGrantFile.startWrite();
6460
6461            XmlSerializer out = new FastXmlSerializer();
6462            out.setOutput(fos, "utf-8");
6463            out.startDocument(null, true);
6464            out.startTag(null, TAG_URI_GRANTS);
6465            for (UriPermission.Snapshot perm : persist) {
6466                out.startTag(null, TAG_URI_GRANT);
6467                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6468                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6469                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6470                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6471                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6472                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6473                out.endTag(null, TAG_URI_GRANT);
6474            }
6475            out.endTag(null, TAG_URI_GRANTS);
6476            out.endDocument();
6477
6478            mGrantFile.finishWrite(fos);
6479        } catch (IOException e) {
6480            if (fos != null) {
6481                mGrantFile.failWrite(fos);
6482            }
6483        }
6484    }
6485
6486    private void readGrantedUriPermissionsLocked() {
6487        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6488
6489        final long now = System.currentTimeMillis();
6490
6491        FileInputStream fis = null;
6492        try {
6493            fis = mGrantFile.openRead();
6494            final XmlPullParser in = Xml.newPullParser();
6495            in.setInput(fis, null);
6496
6497            int type;
6498            while ((type = in.next()) != END_DOCUMENT) {
6499                final String tag = in.getName();
6500                if (type == START_TAG) {
6501                    if (TAG_URI_GRANT.equals(tag)) {
6502                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6503                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6504                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6505                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6506                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6507                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6508
6509                        // Sanity check that provider still belongs to source package
6510                        final ProviderInfo pi = getProviderInfoLocked(
6511                                uri.getAuthority(), userHandle);
6512                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6513                            int targetUid = -1;
6514                            try {
6515                                targetUid = AppGlobals.getPackageManager()
6516                                        .getPackageUid(targetPkg, userHandle);
6517                            } catch (RemoteException e) {
6518                            }
6519                            if (targetUid != -1) {
6520                                final UriPermission perm = findOrCreateUriPermissionLocked(
6521                                        sourcePkg, targetPkg, targetUid, uri);
6522                                perm.initPersistedModes(modeFlags, createdTime);
6523                            }
6524                        } else {
6525                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6526                                    + " but instead found " + pi);
6527                        }
6528                    }
6529                }
6530            }
6531        } catch (FileNotFoundException e) {
6532            // Missing grants is okay
6533        } catch (IOException e) {
6534            Log.wtf(TAG, "Failed reading Uri grants", e);
6535        } catch (XmlPullParserException e) {
6536            Log.wtf(TAG, "Failed reading Uri grants", e);
6537        } finally {
6538            IoUtils.closeQuietly(fis);
6539        }
6540    }
6541
6542    @Override
6543    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6544        enforceNotIsolatedCaller("takePersistableUriPermission");
6545
6546        Preconditions.checkFlagsArgument(modeFlags,
6547                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6548
6549        synchronized (this) {
6550            final int callingUid = Binder.getCallingUid();
6551            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6552            if (perm == null) {
6553                throw new SecurityException("No permission grant found for UID " + callingUid
6554                        + " and Uri " + uri.toSafeString());
6555            }
6556
6557            boolean persistChanged = perm.takePersistableModes(modeFlags);
6558            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6559
6560            if (persistChanged) {
6561                schedulePersistUriGrants();
6562            }
6563        }
6564    }
6565
6566    @Override
6567    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6568        enforceNotIsolatedCaller("releasePersistableUriPermission");
6569
6570        Preconditions.checkFlagsArgument(modeFlags,
6571                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6572
6573        synchronized (this) {
6574            final int callingUid = Binder.getCallingUid();
6575
6576            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6577            if (perm == null) {
6578                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6579                        + uri.toSafeString());
6580                return;
6581            }
6582
6583            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6584            removeUriPermissionIfNeededLocked(perm);
6585            if (persistChanged) {
6586                schedulePersistUriGrants();
6587            }
6588        }
6589    }
6590
6591    /**
6592     * Prune any older {@link UriPermission} for the given UID until outstanding
6593     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6594     *
6595     * @return if any mutations occured that require persisting.
6596     */
6597    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6598        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6599        if (perms == null) return false;
6600        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6601
6602        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6603        for (UriPermission perm : perms.values()) {
6604            if (perm.persistedModeFlags != 0) {
6605                persisted.add(perm);
6606            }
6607        }
6608
6609        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6610        if (trimCount <= 0) return false;
6611
6612        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6613        for (int i = 0; i < trimCount; i++) {
6614            final UriPermission perm = persisted.get(i);
6615
6616            if (DEBUG_URI_PERMISSION) {
6617                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6618            }
6619
6620            perm.releasePersistableModes(~0);
6621            removeUriPermissionIfNeededLocked(perm);
6622        }
6623
6624        return true;
6625    }
6626
6627    @Override
6628    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6629            String packageName, boolean incoming) {
6630        enforceNotIsolatedCaller("getPersistedUriPermissions");
6631        Preconditions.checkNotNull(packageName, "packageName");
6632
6633        final int callingUid = Binder.getCallingUid();
6634        final IPackageManager pm = AppGlobals.getPackageManager();
6635        try {
6636            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6637            if (packageUid != callingUid) {
6638                throw new SecurityException(
6639                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6640            }
6641        } catch (RemoteException e) {
6642            throw new SecurityException("Failed to verify package name ownership");
6643        }
6644
6645        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6646        synchronized (this) {
6647            if (incoming) {
6648                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6649                if (perms == null) {
6650                    Slog.w(TAG, "No permission grants found for " + packageName);
6651                } else {
6652                    final int size = perms.size();
6653                    for (int i = 0; i < size; i++) {
6654                        final UriPermission perm = perms.valueAt(i);
6655                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6656                            result.add(perm.buildPersistedPublicApiObject());
6657                        }
6658                    }
6659                }
6660            } else {
6661                final int size = mGrantedUriPermissions.size();
6662                for (int i = 0; i < size; i++) {
6663                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6664                    final int permsSize = perms.size();
6665                    for (int j = 0; j < permsSize; j++) {
6666                        final UriPermission perm = perms.valueAt(j);
6667                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6668                            result.add(perm.buildPersistedPublicApiObject());
6669                        }
6670                    }
6671                }
6672            }
6673        }
6674        return new ParceledListSlice<android.content.UriPermission>(result);
6675    }
6676
6677    @Override
6678    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6679        synchronized (this) {
6680            ProcessRecord app =
6681                who != null ? getRecordForAppLocked(who) : null;
6682            if (app == null) return;
6683
6684            Message msg = Message.obtain();
6685            msg.what = WAIT_FOR_DEBUGGER_MSG;
6686            msg.obj = app;
6687            msg.arg1 = waiting ? 1 : 0;
6688            mHandler.sendMessage(msg);
6689        }
6690    }
6691
6692    @Override
6693    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6694        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6695        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6696        outInfo.availMem = Process.getFreeMemory();
6697        outInfo.totalMem = Process.getTotalMemory();
6698        outInfo.threshold = homeAppMem;
6699        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6700        outInfo.hiddenAppThreshold = cachedAppMem;
6701        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6702                ProcessList.SERVICE_ADJ);
6703        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6704                ProcessList.VISIBLE_APP_ADJ);
6705        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6706                ProcessList.FOREGROUND_APP_ADJ);
6707    }
6708
6709    // =========================================================
6710    // TASK MANAGEMENT
6711    // =========================================================
6712
6713    @Override
6714    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6715                         IThumbnailReceiver receiver) {
6716        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6717
6718        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6719        ActivityRecord topRecord = null;
6720
6721        synchronized(this) {
6722            if (localLOGV) Slog.v(
6723                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6724                + ", receiver=" + receiver);
6725
6726            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6727                    != PackageManager.PERMISSION_GRANTED) {
6728                if (receiver != null) {
6729                    // If the caller wants to wait for pending thumbnails,
6730                    // it ain't gonna get them.
6731                    try {
6732                        receiver.finished();
6733                    } catch (RemoteException ex) {
6734                    }
6735                }
6736                String msg = "Permission Denial: getTasks() from pid="
6737                        + Binder.getCallingPid()
6738                        + ", uid=" + Binder.getCallingUid()
6739                        + " requires " + android.Manifest.permission.GET_TASKS;
6740                Slog.w(TAG, msg);
6741                throw new SecurityException(msg);
6742            }
6743
6744            // TODO: Improve with MRU list from all ActivityStacks.
6745            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6746
6747            if (!pending.pendingRecords.isEmpty()) {
6748                mPendingThumbnails.add(pending);
6749            }
6750        }
6751
6752        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6753
6754        if (topRecord != null) {
6755            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6756            try {
6757                IApplicationThread topThumbnail = topRecord.app.thread;
6758                topThumbnail.requestThumbnail(topRecord.appToken);
6759            } catch (Exception e) {
6760                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6761                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6762            }
6763        }
6764
6765        if (pending == null && receiver != null) {
6766            // In this case all thumbnails were available and the client
6767            // is being asked to be told when the remaining ones come in...
6768            // which is unusually, since the top-most currently running
6769            // activity should never have a canned thumbnail!  Oh well.
6770            try {
6771                receiver.finished();
6772            } catch (RemoteException ex) {
6773            }
6774        }
6775
6776        return list;
6777    }
6778
6779    TaskRecord getMostRecentTask() {
6780        return mRecentTasks.get(0);
6781    }
6782
6783    @Override
6784    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6785            int flags, int userId) {
6786        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6787                false, true, "getRecentTasks", null);
6788
6789        synchronized (this) {
6790            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6791                    "getRecentTasks()");
6792            final boolean detailed = checkCallingPermission(
6793                    android.Manifest.permission.GET_DETAILED_TASKS)
6794                    == PackageManager.PERMISSION_GRANTED;
6795
6796            IPackageManager pm = AppGlobals.getPackageManager();
6797
6798            final int N = mRecentTasks.size();
6799            ArrayList<ActivityManager.RecentTaskInfo> res
6800                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6801                            maxNum < N ? maxNum : N);
6802            for (int i=0; i<N && maxNum > 0; i++) {
6803                TaskRecord tr = mRecentTasks.get(i);
6804                // Only add calling user's recent tasks
6805                if (tr.userId != userId) continue;
6806                // Return the entry if desired by the caller.  We always return
6807                // the first entry, because callers always expect this to be the
6808                // foreground app.  We may filter others if the caller has
6809                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6810                // we should exclude the entry.
6811
6812                if (i == 0
6813                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6814                        || (tr.intent == null)
6815                        || ((tr.intent.getFlags()
6816                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6817                    ActivityManager.RecentTaskInfo rti
6818                            = new ActivityManager.RecentTaskInfo();
6819                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6820                    rti.persistentId = tr.taskId;
6821                    rti.baseIntent = new Intent(
6822                            tr.intent != null ? tr.intent : tr.affinityIntent);
6823                    if (!detailed) {
6824                        rti.baseIntent.replaceExtras((Bundle)null);
6825                    }
6826                    rti.origActivity = tr.origActivity;
6827                    rti.description = tr.lastDescription;
6828                    rti.stackId = tr.stack.mStackId;
6829
6830                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6831                        // Check whether this activity is currently available.
6832                        try {
6833                            if (rti.origActivity != null) {
6834                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6835                                        == null) {
6836                                    continue;
6837                                }
6838                            } else if (rti.baseIntent != null) {
6839                                if (pm.queryIntentActivities(rti.baseIntent,
6840                                        null, 0, userId) == null) {
6841                                    continue;
6842                                }
6843                            }
6844                        } catch (RemoteException e) {
6845                            // Will never happen.
6846                        }
6847                    }
6848
6849                    res.add(rti);
6850                    maxNum--;
6851                }
6852            }
6853            return res;
6854        }
6855    }
6856
6857    private TaskRecord recentTaskForIdLocked(int id) {
6858        final int N = mRecentTasks.size();
6859            for (int i=0; i<N; i++) {
6860                TaskRecord tr = mRecentTasks.get(i);
6861                if (tr.taskId == id) {
6862                    return tr;
6863                }
6864            }
6865            return null;
6866    }
6867
6868    @Override
6869    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6870        synchronized (this) {
6871            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6872                    "getTaskThumbnails()");
6873            TaskRecord tr = recentTaskForIdLocked(id);
6874            if (tr != null) {
6875                return tr.getTaskThumbnailsLocked();
6876            }
6877        }
6878        return null;
6879    }
6880
6881    @Override
6882    public Bitmap getTaskTopThumbnail(int id) {
6883        synchronized (this) {
6884            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6885                    "getTaskTopThumbnail()");
6886            TaskRecord tr = recentTaskForIdLocked(id);
6887            if (tr != null) {
6888                return tr.getTaskTopThumbnailLocked();
6889            }
6890        }
6891        return null;
6892    }
6893
6894    @Override
6895    public boolean removeSubTask(int taskId, int subTaskIndex) {
6896        synchronized (this) {
6897            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6898                    "removeSubTask()");
6899            long ident = Binder.clearCallingIdentity();
6900            try {
6901                TaskRecord tr = recentTaskForIdLocked(taskId);
6902                if (tr != null) {
6903                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6904                }
6905                return false;
6906            } finally {
6907                Binder.restoreCallingIdentity(ident);
6908            }
6909        }
6910    }
6911
6912    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6913        if (!pr.killedByAm) {
6914            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6915            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6916                    pr.processName, pr.setAdj, reason);
6917            pr.killedByAm = true;
6918            Process.killProcessQuiet(pr.pid);
6919        }
6920    }
6921
6922    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6923        tr.disposeThumbnail();
6924        mRecentTasks.remove(tr);
6925        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6926        Intent baseIntent = new Intent(
6927                tr.intent != null ? tr.intent : tr.affinityIntent);
6928        ComponentName component = baseIntent.getComponent();
6929        if (component == null) {
6930            Slog.w(TAG, "Now component for base intent of task: " + tr);
6931            return;
6932        }
6933
6934        // Find any running services associated with this app.
6935        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6936
6937        if (killProcesses) {
6938            // Find any running processes associated with this app.
6939            final String pkg = component.getPackageName();
6940            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6941            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6942            for (int i=0; i<pmap.size(); i++) {
6943                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6944                for (int j=0; j<uids.size(); j++) {
6945                    ProcessRecord proc = uids.valueAt(j);
6946                    if (proc.userId != tr.userId) {
6947                        continue;
6948                    }
6949                    if (!proc.pkgList.containsKey(pkg)) {
6950                        continue;
6951                    }
6952                    procs.add(proc);
6953                }
6954            }
6955
6956            // Kill the running processes.
6957            for (int i=0; i<procs.size(); i++) {
6958                ProcessRecord pr = procs.get(i);
6959                if (pr == mHomeProcess) {
6960                    // Don't kill the home process along with tasks from the same package.
6961                    continue;
6962                }
6963                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6964                    killUnneededProcessLocked(pr, "remove task");
6965                } else {
6966                    pr.waitingToKill = "remove task";
6967                }
6968            }
6969        }
6970    }
6971
6972    @Override
6973    public boolean removeTask(int taskId, int flags) {
6974        synchronized (this) {
6975            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6976                    "removeTask()");
6977            long ident = Binder.clearCallingIdentity();
6978            try {
6979                TaskRecord tr = recentTaskForIdLocked(taskId);
6980                if (tr != null) {
6981                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
6982                    if (r != null) {
6983                        cleanUpRemovedTaskLocked(tr, flags);
6984                        return true;
6985                    }
6986                    if (tr.mActivities.size() == 0) {
6987                        // Caller is just removing a recent task that is
6988                        // not actively running.  That is easy!
6989                        cleanUpRemovedTaskLocked(tr, flags);
6990                        return true;
6991                    }
6992                    Slog.w(TAG, "removeTask: task " + taskId
6993                            + " does not have activities to remove, "
6994                            + " but numActivities=" + tr.numActivities
6995                            + ": " + tr);
6996                }
6997            } finally {
6998                Binder.restoreCallingIdentity(ident);
6999            }
7000        }
7001        return false;
7002    }
7003
7004    /**
7005     * TODO: Add mController hook
7006     */
7007    @Override
7008    public void moveTaskToFront(int task, int flags, Bundle options) {
7009        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7010                "moveTaskToFront()");
7011
7012        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
7013        synchronized(this) {
7014            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7015                    Binder.getCallingUid(), "Task to front")) {
7016                ActivityOptions.abort(options);
7017                return;
7018            }
7019            final long origId = Binder.clearCallingIdentity();
7020            try {
7021                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7022            } finally {
7023                Binder.restoreCallingIdentity(origId);
7024            }
7025            ActivityOptions.abort(options);
7026        }
7027    }
7028
7029    @Override
7030    public void moveTaskToBack(int taskId) {
7031        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7032                "moveTaskToBack()");
7033
7034        synchronized(this) {
7035            TaskRecord tr = recentTaskForIdLocked(taskId);
7036            if (tr != null) {
7037                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7038                ActivityStack stack = tr.stack;
7039                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7040                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7041                            Binder.getCallingUid(), "Task to back")) {
7042                        return;
7043                    }
7044                }
7045                final long origId = Binder.clearCallingIdentity();
7046                try {
7047                    stack.moveTaskToBackLocked(taskId, null);
7048                } finally {
7049                    Binder.restoreCallingIdentity(origId);
7050                }
7051            }
7052        }
7053    }
7054
7055    /**
7056     * Moves an activity, and all of the other activities within the same task, to the bottom
7057     * of the history stack.  The activity's order within the task is unchanged.
7058     *
7059     * @param token A reference to the activity we wish to move
7060     * @param nonRoot If false then this only works if the activity is the root
7061     *                of a task; if true it will work for any activity in a task.
7062     * @return Returns true if the move completed, false if not.
7063     */
7064    @Override
7065    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7066        enforceNotIsolatedCaller("moveActivityTaskToBack");
7067        synchronized(this) {
7068            final long origId = Binder.clearCallingIdentity();
7069            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7070            if (taskId >= 0) {
7071                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7072            }
7073            Binder.restoreCallingIdentity(origId);
7074        }
7075        return false;
7076    }
7077
7078    @Override
7079    public void moveTaskBackwards(int task) {
7080        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7081                "moveTaskBackwards()");
7082
7083        synchronized(this) {
7084            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7085                    Binder.getCallingUid(), "Task backwards")) {
7086                return;
7087            }
7088            final long origId = Binder.clearCallingIdentity();
7089            moveTaskBackwardsLocked(task);
7090            Binder.restoreCallingIdentity(origId);
7091        }
7092    }
7093
7094    private final void moveTaskBackwardsLocked(int task) {
7095        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7096    }
7097
7098    @Override
7099    public IBinder getHomeActivityToken() throws RemoteException {
7100        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7101                "getHomeActivityToken()");
7102        synchronized (this) {
7103            return mStackSupervisor.getHomeActivityToken();
7104        }
7105    }
7106
7107    @Override
7108    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7109            IActivityContainerCallback callback) throws RemoteException {
7110        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7111                "createActivityContainer()");
7112        synchronized (this) {
7113            if (parentActivityToken == null) {
7114                throw new IllegalArgumentException("parent token must not be null");
7115            }
7116            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7117            if (r == null) {
7118                return null;
7119            }
7120            if (callback == null) {
7121                throw new IllegalArgumentException("callback must not be null");
7122            }
7123            return mStackSupervisor.createActivityContainer(r, callback);
7124        }
7125    }
7126
7127    @Override
7128    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7129        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7130                "deleteActivityContainer()");
7131        synchronized (this) {
7132            mStackSupervisor.deleteActivityContainer(container);
7133        }
7134    }
7135
7136    @Override
7137    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7138            throws RemoteException {
7139        synchronized (this) {
7140            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7141            if (stack != null) {
7142                return stack.mActivityContainer;
7143            }
7144            return null;
7145        }
7146    }
7147
7148    @Override
7149    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7150        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7151                "moveTaskToStack()");
7152        if (stackId == HOME_STACK_ID) {
7153            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7154                    new RuntimeException("here").fillInStackTrace());
7155        }
7156        synchronized (this) {
7157            long ident = Binder.clearCallingIdentity();
7158            try {
7159                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7160                        + stackId + " toTop=" + toTop);
7161                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7162            } finally {
7163                Binder.restoreCallingIdentity(ident);
7164            }
7165        }
7166    }
7167
7168    @Override
7169    public void resizeStack(int stackBoxId, Rect bounds) {
7170        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7171                "resizeStackBox()");
7172        long ident = Binder.clearCallingIdentity();
7173        try {
7174            mWindowManager.resizeStack(stackBoxId, bounds);
7175        } finally {
7176            Binder.restoreCallingIdentity(ident);
7177        }
7178    }
7179
7180    @Override
7181    public List<StackInfo> getAllStackInfos() {
7182        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7183                "getAllStackInfos()");
7184        long ident = Binder.clearCallingIdentity();
7185        try {
7186            synchronized (this) {
7187                return mStackSupervisor.getAllStackInfosLocked();
7188            }
7189        } finally {
7190            Binder.restoreCallingIdentity(ident);
7191        }
7192    }
7193
7194    @Override
7195    public StackInfo getStackInfo(int stackId) {
7196        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7197                "getStackInfo()");
7198        long ident = Binder.clearCallingIdentity();
7199        try {
7200            synchronized (this) {
7201                return mStackSupervisor.getStackInfoLocked(stackId);
7202            }
7203        } finally {
7204            Binder.restoreCallingIdentity(ident);
7205        }
7206    }
7207
7208    @Override
7209    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7210        synchronized(this) {
7211            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7212        }
7213    }
7214
7215    // =========================================================
7216    // THUMBNAILS
7217    // =========================================================
7218
7219    public void reportThumbnail(IBinder token,
7220            Bitmap thumbnail, CharSequence description) {
7221        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7222        final long origId = Binder.clearCallingIdentity();
7223        sendPendingThumbnail(null, token, thumbnail, description, true);
7224        Binder.restoreCallingIdentity(origId);
7225    }
7226
7227    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7228            Bitmap thumbnail, CharSequence description, boolean always) {
7229        TaskRecord task;
7230        ArrayList<PendingThumbnailsRecord> receivers = null;
7231
7232        //System.out.println("Send pending thumbnail: " + r);
7233
7234        synchronized(this) {
7235            if (r == null) {
7236                r = ActivityRecord.isInStackLocked(token);
7237                if (r == null) {
7238                    return;
7239                }
7240            }
7241            if (thumbnail == null && r.thumbHolder != null) {
7242                thumbnail = r.thumbHolder.lastThumbnail;
7243                description = r.thumbHolder.lastDescription;
7244            }
7245            if (thumbnail == null && !always) {
7246                // If there is no thumbnail, and this entry is not actually
7247                // going away, then abort for now and pick up the next
7248                // thumbnail we get.
7249                return;
7250            }
7251            task = r.task;
7252
7253            int N = mPendingThumbnails.size();
7254            int i=0;
7255            while (i<N) {
7256                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7257                //System.out.println("Looking in " + pr.pendingRecords);
7258                if (pr.pendingRecords.remove(r)) {
7259                    if (receivers == null) {
7260                        receivers = new ArrayList<PendingThumbnailsRecord>();
7261                    }
7262                    receivers.add(pr);
7263                    if (pr.pendingRecords.size() == 0) {
7264                        pr.finished = true;
7265                        mPendingThumbnails.remove(i);
7266                        N--;
7267                        continue;
7268                    }
7269                }
7270                i++;
7271            }
7272        }
7273
7274        if (receivers != null) {
7275            final int N = receivers.size();
7276            for (int i=0; i<N; i++) {
7277                try {
7278                    PendingThumbnailsRecord pr = receivers.get(i);
7279                    pr.receiver.newThumbnail(
7280                        task != null ? task.taskId : -1, thumbnail, description);
7281                    if (pr.finished) {
7282                        pr.receiver.finished();
7283                    }
7284                } catch (Exception e) {
7285                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7286                }
7287            }
7288        }
7289    }
7290
7291    // =========================================================
7292    // CONTENT PROVIDERS
7293    // =========================================================
7294
7295    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7296        List<ProviderInfo> providers = null;
7297        try {
7298            providers = AppGlobals.getPackageManager().
7299                queryContentProviders(app.processName, app.uid,
7300                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7301        } catch (RemoteException ex) {
7302        }
7303        if (DEBUG_MU)
7304            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7305        int userId = app.userId;
7306        if (providers != null) {
7307            int N = providers.size();
7308            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7309            for (int i=0; i<N; i++) {
7310                ProviderInfo cpi =
7311                    (ProviderInfo)providers.get(i);
7312                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7313                        cpi.name, cpi.flags);
7314                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7315                    // This is a singleton provider, but a user besides the
7316                    // default user is asking to initialize a process it runs
7317                    // in...  well, no, it doesn't actually run in this process,
7318                    // it runs in the process of the default user.  Get rid of it.
7319                    providers.remove(i);
7320                    N--;
7321                    i--;
7322                    continue;
7323                }
7324
7325                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7326                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7327                if (cpr == null) {
7328                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7329                    mProviderMap.putProviderByClass(comp, cpr);
7330                }
7331                if (DEBUG_MU)
7332                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7333                app.pubProviders.put(cpi.name, cpr);
7334                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7335                    // Don't add this if it is a platform component that is marked
7336                    // to run in multiple processes, because this is actually
7337                    // part of the framework so doesn't make sense to track as a
7338                    // separate apk in the process.
7339                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7340                }
7341                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7342            }
7343        }
7344        return providers;
7345    }
7346
7347    /**
7348     * Check if {@link ProcessRecord} has a possible chance at accessing the
7349     * given {@link ProviderInfo}. Final permission checking is always done
7350     * in {@link ContentProvider}.
7351     */
7352    private final String checkContentProviderPermissionLocked(
7353            ProviderInfo cpi, ProcessRecord r) {
7354        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7355        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7356        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7357                cpi.applicationInfo.uid, cpi.exported)
7358                == PackageManager.PERMISSION_GRANTED) {
7359            return null;
7360        }
7361        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7362                cpi.applicationInfo.uid, cpi.exported)
7363                == PackageManager.PERMISSION_GRANTED) {
7364            return null;
7365        }
7366
7367        PathPermission[] pps = cpi.pathPermissions;
7368        if (pps != null) {
7369            int i = pps.length;
7370            while (i > 0) {
7371                i--;
7372                PathPermission pp = pps[i];
7373                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7374                        cpi.applicationInfo.uid, cpi.exported)
7375                        == PackageManager.PERMISSION_GRANTED) {
7376                    return null;
7377                }
7378                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7379                        cpi.applicationInfo.uid, cpi.exported)
7380                        == PackageManager.PERMISSION_GRANTED) {
7381                    return null;
7382                }
7383            }
7384        }
7385
7386        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7387        if (perms != null) {
7388            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7389                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7390                    return null;
7391                }
7392            }
7393        }
7394
7395        String msg;
7396        if (!cpi.exported) {
7397            msg = "Permission Denial: opening provider " + cpi.name
7398                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7399                    + ", uid=" + callingUid + ") that is not exported from uid "
7400                    + cpi.applicationInfo.uid;
7401        } else {
7402            msg = "Permission Denial: opening provider " + cpi.name
7403                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7404                    + ", uid=" + callingUid + ") requires "
7405                    + cpi.readPermission + " or " + cpi.writePermission;
7406        }
7407        Slog.w(TAG, msg);
7408        return msg;
7409    }
7410
7411    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7412            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7413        if (r != null) {
7414            for (int i=0; i<r.conProviders.size(); i++) {
7415                ContentProviderConnection conn = r.conProviders.get(i);
7416                if (conn.provider == cpr) {
7417                    if (DEBUG_PROVIDER) Slog.v(TAG,
7418                            "Adding provider requested by "
7419                            + r.processName + " from process "
7420                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7421                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7422                    if (stable) {
7423                        conn.stableCount++;
7424                        conn.numStableIncs++;
7425                    } else {
7426                        conn.unstableCount++;
7427                        conn.numUnstableIncs++;
7428                    }
7429                    return conn;
7430                }
7431            }
7432            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7433            if (stable) {
7434                conn.stableCount = 1;
7435                conn.numStableIncs = 1;
7436            } else {
7437                conn.unstableCount = 1;
7438                conn.numUnstableIncs = 1;
7439            }
7440            cpr.connections.add(conn);
7441            r.conProviders.add(conn);
7442            return conn;
7443        }
7444        cpr.addExternalProcessHandleLocked(externalProcessToken);
7445        return null;
7446    }
7447
7448    boolean decProviderCountLocked(ContentProviderConnection conn,
7449            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7450        if (conn != null) {
7451            cpr = conn.provider;
7452            if (DEBUG_PROVIDER) Slog.v(TAG,
7453                    "Removing provider requested by "
7454                    + conn.client.processName + " from process "
7455                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7456                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7457            if (stable) {
7458                conn.stableCount--;
7459            } else {
7460                conn.unstableCount--;
7461            }
7462            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7463                cpr.connections.remove(conn);
7464                conn.client.conProviders.remove(conn);
7465                return true;
7466            }
7467            return false;
7468        }
7469        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7470        return false;
7471    }
7472
7473    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7474            String name, IBinder token, boolean stable, int userId) {
7475        ContentProviderRecord cpr;
7476        ContentProviderConnection conn = null;
7477        ProviderInfo cpi = null;
7478
7479        synchronized(this) {
7480            ProcessRecord r = null;
7481            if (caller != null) {
7482                r = getRecordForAppLocked(caller);
7483                if (r == null) {
7484                    throw new SecurityException(
7485                            "Unable to find app for caller " + caller
7486                          + " (pid=" + Binder.getCallingPid()
7487                          + ") when getting content provider " + name);
7488                }
7489            }
7490
7491            // First check if this content provider has been published...
7492            cpr = mProviderMap.getProviderByName(name, userId);
7493            boolean providerRunning = cpr != null;
7494            if (providerRunning) {
7495                cpi = cpr.info;
7496                String msg;
7497                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7498                    throw new SecurityException(msg);
7499                }
7500
7501                if (r != null && cpr.canRunHere(r)) {
7502                    // This provider has been published or is in the process
7503                    // of being published...  but it is also allowed to run
7504                    // in the caller's process, so don't make a connection
7505                    // and just let the caller instantiate its own instance.
7506                    ContentProviderHolder holder = cpr.newHolder(null);
7507                    // don't give caller the provider object, it needs
7508                    // to make its own.
7509                    holder.provider = null;
7510                    return holder;
7511                }
7512
7513                final long origId = Binder.clearCallingIdentity();
7514
7515                // In this case the provider instance already exists, so we can
7516                // return it right away.
7517                conn = incProviderCountLocked(r, cpr, token, stable);
7518                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7519                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7520                        // If this is a perceptible app accessing the provider,
7521                        // make sure to count it as being accessed and thus
7522                        // back up on the LRU list.  This is good because
7523                        // content providers are often expensive to start.
7524                        updateLruProcessLocked(cpr.proc, false, null);
7525                    }
7526                }
7527
7528                if (cpr.proc != null) {
7529                    if (false) {
7530                        if (cpr.name.flattenToShortString().equals(
7531                                "com.android.providers.calendar/.CalendarProvider2")) {
7532                            Slog.v(TAG, "****************** KILLING "
7533                                + cpr.name.flattenToShortString());
7534                            Process.killProcess(cpr.proc.pid);
7535                        }
7536                    }
7537                    boolean success = updateOomAdjLocked(cpr.proc);
7538                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7539                    // NOTE: there is still a race here where a signal could be
7540                    // pending on the process even though we managed to update its
7541                    // adj level.  Not sure what to do about this, but at least
7542                    // the race is now smaller.
7543                    if (!success) {
7544                        // Uh oh...  it looks like the provider's process
7545                        // has been killed on us.  We need to wait for a new
7546                        // process to be started, and make sure its death
7547                        // doesn't kill our process.
7548                        Slog.i(TAG,
7549                                "Existing provider " + cpr.name.flattenToShortString()
7550                                + " is crashing; detaching " + r);
7551                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7552                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7553                        if (!lastRef) {
7554                            // This wasn't the last ref our process had on
7555                            // the provider...  we have now been killed, bail.
7556                            return null;
7557                        }
7558                        providerRunning = false;
7559                        conn = null;
7560                    }
7561                }
7562
7563                Binder.restoreCallingIdentity(origId);
7564            }
7565
7566            boolean singleton;
7567            if (!providerRunning) {
7568                try {
7569                    cpi = AppGlobals.getPackageManager().
7570                        resolveContentProvider(name,
7571                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7572                } catch (RemoteException ex) {
7573                }
7574                if (cpi == null) {
7575                    return null;
7576                }
7577                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7578                        cpi.name, cpi.flags);
7579                if (singleton) {
7580                    userId = 0;
7581                }
7582                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7583
7584                String msg;
7585                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7586                    throw new SecurityException(msg);
7587                }
7588
7589                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7590                        && !cpi.processName.equals("system")) {
7591                    // If this content provider does not run in the system
7592                    // process, and the system is not yet ready to run other
7593                    // processes, then fail fast instead of hanging.
7594                    throw new IllegalArgumentException(
7595                            "Attempt to launch content provider before system ready");
7596                }
7597
7598                // Make sure that the user who owns this provider is started.  If not,
7599                // we don't want to allow it to run.
7600                if (mStartedUsers.get(userId) == null) {
7601                    Slog.w(TAG, "Unable to launch app "
7602                            + cpi.applicationInfo.packageName + "/"
7603                            + cpi.applicationInfo.uid + " for provider "
7604                            + name + ": user " + userId + " is stopped");
7605                    return null;
7606                }
7607
7608                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7609                cpr = mProviderMap.getProviderByClass(comp, userId);
7610                final boolean firstClass = cpr == null;
7611                if (firstClass) {
7612                    try {
7613                        ApplicationInfo ai =
7614                            AppGlobals.getPackageManager().
7615                                getApplicationInfo(
7616                                        cpi.applicationInfo.packageName,
7617                                        STOCK_PM_FLAGS, userId);
7618                        if (ai == null) {
7619                            Slog.w(TAG, "No package info for content provider "
7620                                    + cpi.name);
7621                            return null;
7622                        }
7623                        ai = getAppInfoForUser(ai, userId);
7624                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7625                    } catch (RemoteException ex) {
7626                        // pm is in same process, this will never happen.
7627                    }
7628                }
7629
7630                if (r != null && cpr.canRunHere(r)) {
7631                    // If this is a multiprocess provider, then just return its
7632                    // info and allow the caller to instantiate it.  Only do
7633                    // this if the provider is the same user as the caller's
7634                    // process, or can run as root (so can be in any process).
7635                    return cpr.newHolder(null);
7636                }
7637
7638                if (DEBUG_PROVIDER) {
7639                    RuntimeException e = new RuntimeException("here");
7640                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7641                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7642                }
7643
7644                // This is single process, and our app is now connecting to it.
7645                // See if we are already in the process of launching this
7646                // provider.
7647                final int N = mLaunchingProviders.size();
7648                int i;
7649                for (i=0; i<N; i++) {
7650                    if (mLaunchingProviders.get(i) == cpr) {
7651                        break;
7652                    }
7653                }
7654
7655                // If the provider is not already being launched, then get it
7656                // started.
7657                if (i >= N) {
7658                    final long origId = Binder.clearCallingIdentity();
7659
7660                    try {
7661                        // Content provider is now in use, its package can't be stopped.
7662                        try {
7663                            AppGlobals.getPackageManager().setPackageStoppedState(
7664                                    cpr.appInfo.packageName, false, userId);
7665                        } catch (RemoteException e) {
7666                        } catch (IllegalArgumentException e) {
7667                            Slog.w(TAG, "Failed trying to unstop package "
7668                                    + cpr.appInfo.packageName + ": " + e);
7669                        }
7670
7671                        // Use existing process if already started
7672                        ProcessRecord proc = getProcessRecordLocked(
7673                                cpi.processName, cpr.appInfo.uid, false);
7674                        if (proc != null && proc.thread != null) {
7675                            if (DEBUG_PROVIDER) {
7676                                Slog.d(TAG, "Installing in existing process " + proc);
7677                            }
7678                            proc.pubProviders.put(cpi.name, cpr);
7679                            try {
7680                                proc.thread.scheduleInstallProvider(cpi);
7681                            } catch (RemoteException e) {
7682                            }
7683                        } else {
7684                            proc = startProcessLocked(cpi.processName,
7685                                    cpr.appInfo, false, 0, "content provider",
7686                                    new ComponentName(cpi.applicationInfo.packageName,
7687                                            cpi.name), false, false, false);
7688                            if (proc == null) {
7689                                Slog.w(TAG, "Unable to launch app "
7690                                        + cpi.applicationInfo.packageName + "/"
7691                                        + cpi.applicationInfo.uid + " for provider "
7692                                        + name + ": process is bad");
7693                                return null;
7694                            }
7695                        }
7696                        cpr.launchingApp = proc;
7697                        mLaunchingProviders.add(cpr);
7698                    } finally {
7699                        Binder.restoreCallingIdentity(origId);
7700                    }
7701                }
7702
7703                // Make sure the provider is published (the same provider class
7704                // may be published under multiple names).
7705                if (firstClass) {
7706                    mProviderMap.putProviderByClass(comp, cpr);
7707                }
7708
7709                mProviderMap.putProviderByName(name, cpr);
7710                conn = incProviderCountLocked(r, cpr, token, stable);
7711                if (conn != null) {
7712                    conn.waiting = true;
7713                }
7714            }
7715        }
7716
7717        // Wait for the provider to be published...
7718        synchronized (cpr) {
7719            while (cpr.provider == null) {
7720                if (cpr.launchingApp == null) {
7721                    Slog.w(TAG, "Unable to launch app "
7722                            + cpi.applicationInfo.packageName + "/"
7723                            + cpi.applicationInfo.uid + " for provider "
7724                            + name + ": launching app became null");
7725                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7726                            UserHandle.getUserId(cpi.applicationInfo.uid),
7727                            cpi.applicationInfo.packageName,
7728                            cpi.applicationInfo.uid, name);
7729                    return null;
7730                }
7731                try {
7732                    if (DEBUG_MU) {
7733                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7734                                + cpr.launchingApp);
7735                    }
7736                    if (conn != null) {
7737                        conn.waiting = true;
7738                    }
7739                    cpr.wait();
7740                } catch (InterruptedException ex) {
7741                } finally {
7742                    if (conn != null) {
7743                        conn.waiting = false;
7744                    }
7745                }
7746            }
7747        }
7748        return cpr != null ? cpr.newHolder(conn) : null;
7749    }
7750
7751    public final ContentProviderHolder getContentProvider(
7752            IApplicationThread caller, String name, int userId, boolean stable) {
7753        enforceNotIsolatedCaller("getContentProvider");
7754        if (caller == null) {
7755            String msg = "null IApplicationThread when getting content provider "
7756                    + name;
7757            Slog.w(TAG, msg);
7758            throw new SecurityException(msg);
7759        }
7760
7761        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7762                false, true, "getContentProvider", null);
7763        return getContentProviderImpl(caller, name, null, stable, userId);
7764    }
7765
7766    public ContentProviderHolder getContentProviderExternal(
7767            String name, int userId, IBinder token) {
7768        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7769            "Do not have permission in call getContentProviderExternal()");
7770        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7771                false, true, "getContentProvider", null);
7772        return getContentProviderExternalUnchecked(name, token, userId);
7773    }
7774
7775    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7776            IBinder token, int userId) {
7777        return getContentProviderImpl(null, name, token, true, userId);
7778    }
7779
7780    /**
7781     * Drop a content provider from a ProcessRecord's bookkeeping
7782     */
7783    public void removeContentProvider(IBinder connection, boolean stable) {
7784        enforceNotIsolatedCaller("removeContentProvider");
7785        synchronized (this) {
7786            ContentProviderConnection conn;
7787            try {
7788                conn = (ContentProviderConnection)connection;
7789            } catch (ClassCastException e) {
7790                String msg ="removeContentProvider: " + connection
7791                        + " not a ContentProviderConnection";
7792                Slog.w(TAG, msg);
7793                throw new IllegalArgumentException(msg);
7794            }
7795            if (conn == null) {
7796                throw new NullPointerException("connection is null");
7797            }
7798            if (decProviderCountLocked(conn, null, null, stable)) {
7799                updateOomAdjLocked();
7800            }
7801        }
7802    }
7803
7804    public void removeContentProviderExternal(String name, IBinder token) {
7805        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7806            "Do not have permission in call removeContentProviderExternal()");
7807        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7808    }
7809
7810    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7811        synchronized (this) {
7812            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7813            if(cpr == null) {
7814                //remove from mProvidersByClass
7815                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7816                return;
7817            }
7818
7819            //update content provider record entry info
7820            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7821            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7822            if (localCpr.hasExternalProcessHandles()) {
7823                if (localCpr.removeExternalProcessHandleLocked(token)) {
7824                    updateOomAdjLocked();
7825                } else {
7826                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7827                            + " with no external reference for token: "
7828                            + token + ".");
7829                }
7830            } else {
7831                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7832                        + " with no external references.");
7833            }
7834        }
7835    }
7836
7837    public final void publishContentProviders(IApplicationThread caller,
7838            List<ContentProviderHolder> providers) {
7839        if (providers == null) {
7840            return;
7841        }
7842
7843        enforceNotIsolatedCaller("publishContentProviders");
7844        synchronized (this) {
7845            final ProcessRecord r = getRecordForAppLocked(caller);
7846            if (DEBUG_MU)
7847                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7848            if (r == null) {
7849                throw new SecurityException(
7850                        "Unable to find app for caller " + caller
7851                      + " (pid=" + Binder.getCallingPid()
7852                      + ") when publishing content providers");
7853            }
7854
7855            final long origId = Binder.clearCallingIdentity();
7856
7857            final int N = providers.size();
7858            for (int i=0; i<N; i++) {
7859                ContentProviderHolder src = providers.get(i);
7860                if (src == null || src.info == null || src.provider == null) {
7861                    continue;
7862                }
7863                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7864                if (DEBUG_MU)
7865                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7866                if (dst != null) {
7867                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7868                    mProviderMap.putProviderByClass(comp, dst);
7869                    String names[] = dst.info.authority.split(";");
7870                    for (int j = 0; j < names.length; j++) {
7871                        mProviderMap.putProviderByName(names[j], dst);
7872                    }
7873
7874                    int NL = mLaunchingProviders.size();
7875                    int j;
7876                    for (j=0; j<NL; j++) {
7877                        if (mLaunchingProviders.get(j) == dst) {
7878                            mLaunchingProviders.remove(j);
7879                            j--;
7880                            NL--;
7881                        }
7882                    }
7883                    synchronized (dst) {
7884                        dst.provider = src.provider;
7885                        dst.proc = r;
7886                        dst.notifyAll();
7887                    }
7888                    updateOomAdjLocked(r);
7889                }
7890            }
7891
7892            Binder.restoreCallingIdentity(origId);
7893        }
7894    }
7895
7896    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7897        ContentProviderConnection conn;
7898        try {
7899            conn = (ContentProviderConnection)connection;
7900        } catch (ClassCastException e) {
7901            String msg ="refContentProvider: " + connection
7902                    + " not a ContentProviderConnection";
7903            Slog.w(TAG, msg);
7904            throw new IllegalArgumentException(msg);
7905        }
7906        if (conn == null) {
7907            throw new NullPointerException("connection is null");
7908        }
7909
7910        synchronized (this) {
7911            if (stable > 0) {
7912                conn.numStableIncs += stable;
7913            }
7914            stable = conn.stableCount + stable;
7915            if (stable < 0) {
7916                throw new IllegalStateException("stableCount < 0: " + stable);
7917            }
7918
7919            if (unstable > 0) {
7920                conn.numUnstableIncs += unstable;
7921            }
7922            unstable = conn.unstableCount + unstable;
7923            if (unstable < 0) {
7924                throw new IllegalStateException("unstableCount < 0: " + unstable);
7925            }
7926
7927            if ((stable+unstable) <= 0) {
7928                throw new IllegalStateException("ref counts can't go to zero here: stable="
7929                        + stable + " unstable=" + unstable);
7930            }
7931            conn.stableCount = stable;
7932            conn.unstableCount = unstable;
7933            return !conn.dead;
7934        }
7935    }
7936
7937    public void unstableProviderDied(IBinder connection) {
7938        ContentProviderConnection conn;
7939        try {
7940            conn = (ContentProviderConnection)connection;
7941        } catch (ClassCastException e) {
7942            String msg ="refContentProvider: " + connection
7943                    + " not a ContentProviderConnection";
7944            Slog.w(TAG, msg);
7945            throw new IllegalArgumentException(msg);
7946        }
7947        if (conn == null) {
7948            throw new NullPointerException("connection is null");
7949        }
7950
7951        // Safely retrieve the content provider associated with the connection.
7952        IContentProvider provider;
7953        synchronized (this) {
7954            provider = conn.provider.provider;
7955        }
7956
7957        if (provider == null) {
7958            // Um, yeah, we're way ahead of you.
7959            return;
7960        }
7961
7962        // Make sure the caller is being honest with us.
7963        if (provider.asBinder().pingBinder()) {
7964            // Er, no, still looks good to us.
7965            synchronized (this) {
7966                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7967                        + " says " + conn + " died, but we don't agree");
7968                return;
7969            }
7970        }
7971
7972        // Well look at that!  It's dead!
7973        synchronized (this) {
7974            if (conn.provider.provider != provider) {
7975                // But something changed...  good enough.
7976                return;
7977            }
7978
7979            ProcessRecord proc = conn.provider.proc;
7980            if (proc == null || proc.thread == null) {
7981                // Seems like the process is already cleaned up.
7982                return;
7983            }
7984
7985            // As far as we're concerned, this is just like receiving a
7986            // death notification...  just a bit prematurely.
7987            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
7988                    + ") early provider death");
7989            final long ident = Binder.clearCallingIdentity();
7990            try {
7991                appDiedLocked(proc, proc.pid, proc.thread);
7992            } finally {
7993                Binder.restoreCallingIdentity(ident);
7994            }
7995        }
7996    }
7997
7998    @Override
7999    public void appNotRespondingViaProvider(IBinder connection) {
8000        enforceCallingPermission(
8001                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8002
8003        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8004        if (conn == null) {
8005            Slog.w(TAG, "ContentProviderConnection is null");
8006            return;
8007        }
8008
8009        final ProcessRecord host = conn.provider.proc;
8010        if (host == null) {
8011            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8012            return;
8013        }
8014
8015        final long token = Binder.clearCallingIdentity();
8016        try {
8017            appNotResponding(host, null, null, false, "ContentProvider not responding");
8018        } finally {
8019            Binder.restoreCallingIdentity(token);
8020        }
8021    }
8022
8023    public final void installSystemProviders() {
8024        List<ProviderInfo> providers;
8025        synchronized (this) {
8026            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8027            providers = generateApplicationProvidersLocked(app);
8028            if (providers != null) {
8029                for (int i=providers.size()-1; i>=0; i--) {
8030                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8031                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8032                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8033                                + ": not system .apk");
8034                        providers.remove(i);
8035                    }
8036                }
8037            }
8038        }
8039        if (providers != null) {
8040            mSystemThread.installSystemProviders(providers);
8041        }
8042
8043        mCoreSettingsObserver = new CoreSettingsObserver(this);
8044
8045        mUsageStatsService.monitorPackages();
8046    }
8047
8048    /**
8049     * Allows app to retrieve the MIME type of a URI without having permission
8050     * to access its content provider.
8051     *
8052     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8053     *
8054     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8055     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8056     */
8057    public String getProviderMimeType(Uri uri, int userId) {
8058        enforceNotIsolatedCaller("getProviderMimeType");
8059        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8060                userId, false, true, "getProviderMimeType", null);
8061        final String name = uri.getAuthority();
8062        final long ident = Binder.clearCallingIdentity();
8063        ContentProviderHolder holder = null;
8064
8065        try {
8066            holder = getContentProviderExternalUnchecked(name, null, userId);
8067            if (holder != null) {
8068                return holder.provider.getType(uri);
8069            }
8070        } catch (RemoteException e) {
8071            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8072            return null;
8073        } finally {
8074            if (holder != null) {
8075                removeContentProviderExternalUnchecked(name, null, userId);
8076            }
8077            Binder.restoreCallingIdentity(ident);
8078        }
8079
8080        return null;
8081    }
8082
8083    // =========================================================
8084    // GLOBAL MANAGEMENT
8085    // =========================================================
8086
8087    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8088            boolean isolated) {
8089        String proc = customProcess != null ? customProcess : info.processName;
8090        BatteryStatsImpl.Uid.Proc ps = null;
8091        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8092        int uid = info.uid;
8093        if (isolated) {
8094            int userId = UserHandle.getUserId(uid);
8095            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8096            while (true) {
8097                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8098                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8099                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8100                }
8101                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8102                mNextIsolatedProcessUid++;
8103                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8104                    // No process for this uid, use it.
8105                    break;
8106                }
8107                stepsLeft--;
8108                if (stepsLeft <= 0) {
8109                    return null;
8110                }
8111            }
8112        }
8113        return new ProcessRecord(stats, info, proc, uid);
8114    }
8115
8116    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8117            String abiOverride) {
8118        ProcessRecord app;
8119        if (!isolated) {
8120            app = getProcessRecordLocked(info.processName, info.uid, true);
8121        } else {
8122            app = null;
8123        }
8124
8125        if (app == null) {
8126            app = newProcessRecordLocked(info, null, isolated);
8127            mProcessNames.put(info.processName, app.uid, app);
8128            if (isolated) {
8129                mIsolatedProcesses.put(app.uid, app);
8130            }
8131            updateLruProcessLocked(app, false, null);
8132            updateOomAdjLocked();
8133        }
8134
8135        // This package really, really can not be stopped.
8136        try {
8137            AppGlobals.getPackageManager().setPackageStoppedState(
8138                    info.packageName, false, UserHandle.getUserId(app.uid));
8139        } catch (RemoteException e) {
8140        } catch (IllegalArgumentException e) {
8141            Slog.w(TAG, "Failed trying to unstop package "
8142                    + info.packageName + ": " + e);
8143        }
8144
8145        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8146                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8147            app.persistent = true;
8148            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8149        }
8150        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8151            mPersistentStartingProcesses.add(app);
8152            startProcessLocked(app, "added application", app.processName,
8153                    abiOverride);
8154        }
8155
8156        return app;
8157    }
8158
8159    public void unhandledBack() {
8160        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8161                "unhandledBack()");
8162
8163        synchronized(this) {
8164            final long origId = Binder.clearCallingIdentity();
8165            try {
8166                getFocusedStack().unhandledBackLocked();
8167            } finally {
8168                Binder.restoreCallingIdentity(origId);
8169            }
8170        }
8171    }
8172
8173    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8174        enforceNotIsolatedCaller("openContentUri");
8175        final int userId = UserHandle.getCallingUserId();
8176        String name = uri.getAuthority();
8177        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8178        ParcelFileDescriptor pfd = null;
8179        if (cph != null) {
8180            // We record the binder invoker's uid in thread-local storage before
8181            // going to the content provider to open the file.  Later, in the code
8182            // that handles all permissions checks, we look for this uid and use
8183            // that rather than the Activity Manager's own uid.  The effect is that
8184            // we do the check against the caller's permissions even though it looks
8185            // to the content provider like the Activity Manager itself is making
8186            // the request.
8187            sCallerIdentity.set(new Identity(
8188                    Binder.getCallingPid(), Binder.getCallingUid()));
8189            try {
8190                pfd = cph.provider.openFile(null, uri, "r", null);
8191            } catch (FileNotFoundException e) {
8192                // do nothing; pfd will be returned null
8193            } finally {
8194                // Ensure that whatever happens, we clean up the identity state
8195                sCallerIdentity.remove();
8196            }
8197
8198            // We've got the fd now, so we're done with the provider.
8199            removeContentProviderExternalUnchecked(name, null, userId);
8200        } else {
8201            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8202        }
8203        return pfd;
8204    }
8205
8206    // Actually is sleeping or shutting down or whatever else in the future
8207    // is an inactive state.
8208    public boolean isSleepingOrShuttingDown() {
8209        return mSleeping || mShuttingDown;
8210    }
8211
8212    void goingToSleep() {
8213        synchronized(this) {
8214            mWentToSleep = true;
8215            updateEventDispatchingLocked();
8216
8217            if (!mSleeping) {
8218                mSleeping = true;
8219                mStackSupervisor.goingToSleepLocked();
8220
8221                // Initialize the wake times of all processes.
8222                checkExcessivePowerUsageLocked(false);
8223                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8224                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8225                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8226            }
8227        }
8228    }
8229
8230    @Override
8231    public boolean shutdown(int timeout) {
8232        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8233                != PackageManager.PERMISSION_GRANTED) {
8234            throw new SecurityException("Requires permission "
8235                    + android.Manifest.permission.SHUTDOWN);
8236        }
8237
8238        boolean timedout = false;
8239
8240        synchronized(this) {
8241            mShuttingDown = true;
8242            updateEventDispatchingLocked();
8243            timedout = mStackSupervisor.shutdownLocked(timeout);
8244        }
8245
8246        mAppOpsService.shutdown();
8247        mUsageStatsService.shutdown();
8248        mBatteryStatsService.shutdown();
8249        synchronized (this) {
8250            mProcessStats.shutdownLocked();
8251        }
8252
8253        return timedout;
8254    }
8255
8256    public final void activitySlept(IBinder token) {
8257        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8258
8259        final long origId = Binder.clearCallingIdentity();
8260
8261        synchronized (this) {
8262            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8263            if (r != null) {
8264                mStackSupervisor.activitySleptLocked(r);
8265            }
8266        }
8267
8268        Binder.restoreCallingIdentity(origId);
8269    }
8270
8271    void logLockScreen(String msg) {
8272        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8273                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8274                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8275                mStackSupervisor.mDismissKeyguardOnNextActivity);
8276    }
8277
8278    private void comeOutOfSleepIfNeededLocked() {
8279        if (!mWentToSleep && !mLockScreenShown) {
8280            if (mSleeping) {
8281                mSleeping = false;
8282                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8283            }
8284        }
8285    }
8286
8287    void wakingUp() {
8288        synchronized(this) {
8289            mWentToSleep = false;
8290            updateEventDispatchingLocked();
8291            comeOutOfSleepIfNeededLocked();
8292        }
8293    }
8294
8295    private void updateEventDispatchingLocked() {
8296        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8297    }
8298
8299    public void setLockScreenShown(boolean shown) {
8300        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8301                != PackageManager.PERMISSION_GRANTED) {
8302            throw new SecurityException("Requires permission "
8303                    + android.Manifest.permission.DEVICE_POWER);
8304        }
8305
8306        synchronized(this) {
8307            long ident = Binder.clearCallingIdentity();
8308            try {
8309                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8310                mLockScreenShown = shown;
8311                comeOutOfSleepIfNeededLocked();
8312            } finally {
8313                Binder.restoreCallingIdentity(ident);
8314            }
8315        }
8316    }
8317
8318    public void stopAppSwitches() {
8319        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8320                != PackageManager.PERMISSION_GRANTED) {
8321            throw new SecurityException("Requires permission "
8322                    + android.Manifest.permission.STOP_APP_SWITCHES);
8323        }
8324
8325        synchronized(this) {
8326            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8327                    + APP_SWITCH_DELAY_TIME;
8328            mDidAppSwitch = false;
8329            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8330            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8331            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8332        }
8333    }
8334
8335    public void resumeAppSwitches() {
8336        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8337                != PackageManager.PERMISSION_GRANTED) {
8338            throw new SecurityException("Requires permission "
8339                    + android.Manifest.permission.STOP_APP_SWITCHES);
8340        }
8341
8342        synchronized(this) {
8343            // Note that we don't execute any pending app switches... we will
8344            // let those wait until either the timeout, or the next start
8345            // activity request.
8346            mAppSwitchesAllowedTime = 0;
8347        }
8348    }
8349
8350    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8351            String name) {
8352        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8353            return true;
8354        }
8355
8356        final int perm = checkComponentPermission(
8357                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8358                callingUid, -1, true);
8359        if (perm == PackageManager.PERMISSION_GRANTED) {
8360            return true;
8361        }
8362
8363        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8364        return false;
8365    }
8366
8367    public void setDebugApp(String packageName, boolean waitForDebugger,
8368            boolean persistent) {
8369        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8370                "setDebugApp()");
8371
8372        long ident = Binder.clearCallingIdentity();
8373        try {
8374            // Note that this is not really thread safe if there are multiple
8375            // callers into it at the same time, but that's not a situation we
8376            // care about.
8377            if (persistent) {
8378                final ContentResolver resolver = mContext.getContentResolver();
8379                Settings.Global.putString(
8380                    resolver, Settings.Global.DEBUG_APP,
8381                    packageName);
8382                Settings.Global.putInt(
8383                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8384                    waitForDebugger ? 1 : 0);
8385            }
8386
8387            synchronized (this) {
8388                if (!persistent) {
8389                    mOrigDebugApp = mDebugApp;
8390                    mOrigWaitForDebugger = mWaitForDebugger;
8391                }
8392                mDebugApp = packageName;
8393                mWaitForDebugger = waitForDebugger;
8394                mDebugTransient = !persistent;
8395                if (packageName != null) {
8396                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8397                            UserHandle.USER_ALL, "set debug app");
8398                }
8399            }
8400        } finally {
8401            Binder.restoreCallingIdentity(ident);
8402        }
8403    }
8404
8405    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8406        synchronized (this) {
8407            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8408            if (!isDebuggable) {
8409                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8410                    throw new SecurityException("Process not debuggable: " + app.packageName);
8411                }
8412            }
8413
8414            mOpenGlTraceApp = processName;
8415        }
8416    }
8417
8418    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8419            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8420        synchronized (this) {
8421            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8422            if (!isDebuggable) {
8423                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8424                    throw new SecurityException("Process not debuggable: " + app.packageName);
8425                }
8426            }
8427            mProfileApp = processName;
8428            mProfileFile = profileFile;
8429            if (mProfileFd != null) {
8430                try {
8431                    mProfileFd.close();
8432                } catch (IOException e) {
8433                }
8434                mProfileFd = null;
8435            }
8436            mProfileFd = profileFd;
8437            mProfileType = 0;
8438            mAutoStopProfiler = autoStopProfiler;
8439        }
8440    }
8441
8442    @Override
8443    public void setAlwaysFinish(boolean enabled) {
8444        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8445                "setAlwaysFinish()");
8446
8447        Settings.Global.putInt(
8448                mContext.getContentResolver(),
8449                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8450
8451        synchronized (this) {
8452            mAlwaysFinishActivities = enabled;
8453        }
8454    }
8455
8456    @Override
8457    public void setActivityController(IActivityController controller) {
8458        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8459                "setActivityController()");
8460        synchronized (this) {
8461            mController = controller;
8462            Watchdog.getInstance().setActivityController(controller);
8463        }
8464    }
8465
8466    @Override
8467    public void setUserIsMonkey(boolean userIsMonkey) {
8468        synchronized (this) {
8469            synchronized (mPidsSelfLocked) {
8470                final int callingPid = Binder.getCallingPid();
8471                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8472                if (precessRecord == null) {
8473                    throw new SecurityException("Unknown process: " + callingPid);
8474                }
8475                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8476                    throw new SecurityException("Only an instrumentation process "
8477                            + "with a UiAutomation can call setUserIsMonkey");
8478                }
8479            }
8480            mUserIsMonkey = userIsMonkey;
8481        }
8482    }
8483
8484    @Override
8485    public boolean isUserAMonkey() {
8486        synchronized (this) {
8487            // If there is a controller also implies the user is a monkey.
8488            return (mUserIsMonkey || mController != null);
8489        }
8490    }
8491
8492    public void requestBugReport() {
8493        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8494        SystemProperties.set("ctl.start", "bugreport");
8495    }
8496
8497    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8498        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8499    }
8500
8501    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8502        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8503            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8504        }
8505        return KEY_DISPATCHING_TIMEOUT;
8506    }
8507
8508    @Override
8509    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8510        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8511                != PackageManager.PERMISSION_GRANTED) {
8512            throw new SecurityException("Requires permission "
8513                    + android.Manifest.permission.FILTER_EVENTS);
8514        }
8515        ProcessRecord proc;
8516        long timeout;
8517        synchronized (this) {
8518            synchronized (mPidsSelfLocked) {
8519                proc = mPidsSelfLocked.get(pid);
8520            }
8521            timeout = getInputDispatchingTimeoutLocked(proc);
8522        }
8523
8524        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8525            return -1;
8526        }
8527
8528        return timeout;
8529    }
8530
8531    /**
8532     * Handle input dispatching timeouts.
8533     * Returns whether input dispatching should be aborted or not.
8534     */
8535    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8536            final ActivityRecord activity, final ActivityRecord parent,
8537            final boolean aboveSystem, String reason) {
8538        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8539                != PackageManager.PERMISSION_GRANTED) {
8540            throw new SecurityException("Requires permission "
8541                    + android.Manifest.permission.FILTER_EVENTS);
8542        }
8543
8544        final String annotation;
8545        if (reason == null) {
8546            annotation = "Input dispatching timed out";
8547        } else {
8548            annotation = "Input dispatching timed out (" + reason + ")";
8549        }
8550
8551        if (proc != null) {
8552            synchronized (this) {
8553                if (proc.debugging) {
8554                    return false;
8555                }
8556
8557                if (mDidDexOpt) {
8558                    // Give more time since we were dexopting.
8559                    mDidDexOpt = false;
8560                    return false;
8561                }
8562
8563                if (proc.instrumentationClass != null) {
8564                    Bundle info = new Bundle();
8565                    info.putString("shortMsg", "keyDispatchingTimedOut");
8566                    info.putString("longMsg", annotation);
8567                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8568                    return true;
8569                }
8570            }
8571            mHandler.post(new Runnable() {
8572                @Override
8573                public void run() {
8574                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8575                }
8576            });
8577        }
8578
8579        return true;
8580    }
8581
8582    public Bundle getAssistContextExtras(int requestType) {
8583        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8584                "getAssistContextExtras()");
8585        PendingAssistExtras pae;
8586        Bundle extras = new Bundle();
8587        synchronized (this) {
8588            ActivityRecord activity = getFocusedStack().mResumedActivity;
8589            if (activity == null) {
8590                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8591                return null;
8592            }
8593            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8594            if (activity.app == null || activity.app.thread == null) {
8595                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8596                return extras;
8597            }
8598            if (activity.app.pid == Binder.getCallingPid()) {
8599                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8600                return extras;
8601            }
8602            pae = new PendingAssistExtras(activity);
8603            try {
8604                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8605                        requestType);
8606                mPendingAssistExtras.add(pae);
8607                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8608            } catch (RemoteException e) {
8609                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8610                return extras;
8611            }
8612        }
8613        synchronized (pae) {
8614            while (!pae.haveResult) {
8615                try {
8616                    pae.wait();
8617                } catch (InterruptedException e) {
8618                }
8619            }
8620            if (pae.result != null) {
8621                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8622            }
8623        }
8624        synchronized (this) {
8625            mPendingAssistExtras.remove(pae);
8626            mHandler.removeCallbacks(pae);
8627        }
8628        return extras;
8629    }
8630
8631    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8632        PendingAssistExtras pae = (PendingAssistExtras)token;
8633        synchronized (pae) {
8634            pae.result = extras;
8635            pae.haveResult = true;
8636            pae.notifyAll();
8637        }
8638    }
8639
8640    public void registerProcessObserver(IProcessObserver observer) {
8641        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8642                "registerProcessObserver()");
8643        synchronized (this) {
8644            mProcessObservers.register(observer);
8645        }
8646    }
8647
8648    @Override
8649    public void unregisterProcessObserver(IProcessObserver observer) {
8650        synchronized (this) {
8651            mProcessObservers.unregister(observer);
8652        }
8653    }
8654
8655    @Override
8656    public boolean convertFromTranslucent(IBinder token) {
8657        final long origId = Binder.clearCallingIdentity();
8658        try {
8659            synchronized (this) {
8660                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8661                if (r == null) {
8662                    return false;
8663                }
8664                if (r.changeWindowTranslucency(true)) {
8665                    mWindowManager.setAppFullscreen(token, true);
8666                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8667                    return true;
8668                }
8669                return false;
8670            }
8671        } finally {
8672            Binder.restoreCallingIdentity(origId);
8673        }
8674    }
8675
8676    @Override
8677    public boolean convertToTranslucent(IBinder token) {
8678        final long origId = Binder.clearCallingIdentity();
8679        try {
8680            synchronized (this) {
8681                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8682                if (r == null) {
8683                    return false;
8684                }
8685                if (r.changeWindowTranslucency(false)) {
8686                    r.task.stack.convertToTranslucent(r);
8687                    mWindowManager.setAppFullscreen(token, false);
8688                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8689                    return true;
8690                }
8691                return false;
8692            }
8693        } finally {
8694            Binder.restoreCallingIdentity(origId);
8695        }
8696    }
8697
8698    @Override
8699    public void setImmersive(IBinder token, boolean immersive) {
8700        synchronized(this) {
8701            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8702            if (r == null) {
8703                throw new IllegalArgumentException();
8704            }
8705            r.immersive = immersive;
8706
8707            // update associated state if we're frontmost
8708            if (r == mFocusedActivity) {
8709                if (DEBUG_IMMERSIVE) {
8710                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8711                }
8712                applyUpdateLockStateLocked(r);
8713            }
8714        }
8715    }
8716
8717    @Override
8718    public boolean isImmersive(IBinder token) {
8719        synchronized (this) {
8720            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8721            if (r == null) {
8722                throw new IllegalArgumentException();
8723            }
8724            return r.immersive;
8725        }
8726    }
8727
8728    public boolean isTopActivityImmersive() {
8729        enforceNotIsolatedCaller("startActivity");
8730        synchronized (this) {
8731            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8732            return (r != null) ? r.immersive : false;
8733        }
8734    }
8735
8736    public final void enterSafeMode() {
8737        synchronized(this) {
8738            // It only makes sense to do this before the system is ready
8739            // and started launching other packages.
8740            if (!mSystemReady) {
8741                try {
8742                    AppGlobals.getPackageManager().enterSafeMode();
8743                } catch (RemoteException e) {
8744                }
8745            }
8746
8747            mSafeMode = true;
8748        }
8749    }
8750
8751    public final void showSafeModeOverlay() {
8752        View v = LayoutInflater.from(mContext).inflate(
8753                com.android.internal.R.layout.safe_mode, null);
8754        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8755        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8756        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8757        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8758        lp.gravity = Gravity.BOTTOM | Gravity.START;
8759        lp.format = v.getBackground().getOpacity();
8760        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8761                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8762        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8763        ((WindowManager)mContext.getSystemService(
8764                Context.WINDOW_SERVICE)).addView(v, lp);
8765    }
8766
8767    public void noteWakeupAlarm(IIntentSender sender) {
8768        if (!(sender instanceof PendingIntentRecord)) {
8769            return;
8770        }
8771        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8772        synchronized (stats) {
8773            if (mBatteryStatsService.isOnBattery()) {
8774                mBatteryStatsService.enforceCallingPermission();
8775                PendingIntentRecord rec = (PendingIntentRecord)sender;
8776                int MY_UID = Binder.getCallingUid();
8777                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8778                BatteryStatsImpl.Uid.Pkg pkg =
8779                    stats.getPackageStatsLocked(uid, rec.key.packageName);
8780                pkg.incWakeupsLocked();
8781            }
8782        }
8783    }
8784
8785    public boolean killPids(int[] pids, String pReason, boolean secure) {
8786        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8787            throw new SecurityException("killPids only available to the system");
8788        }
8789        String reason = (pReason == null) ? "Unknown" : pReason;
8790        // XXX Note: don't acquire main activity lock here, because the window
8791        // manager calls in with its locks held.
8792
8793        boolean killed = false;
8794        synchronized (mPidsSelfLocked) {
8795            int[] types = new int[pids.length];
8796            int worstType = 0;
8797            for (int i=0; i<pids.length; i++) {
8798                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8799                if (proc != null) {
8800                    int type = proc.setAdj;
8801                    types[i] = type;
8802                    if (type > worstType) {
8803                        worstType = type;
8804                    }
8805                }
8806            }
8807
8808            // If the worst oom_adj is somewhere in the cached proc LRU range,
8809            // then constrain it so we will kill all cached procs.
8810            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8811                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8812                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8813            }
8814
8815            // If this is not a secure call, don't let it kill processes that
8816            // are important.
8817            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8818                worstType = ProcessList.SERVICE_ADJ;
8819            }
8820
8821            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8822            for (int i=0; i<pids.length; i++) {
8823                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8824                if (proc == null) {
8825                    continue;
8826                }
8827                int adj = proc.setAdj;
8828                if (adj >= worstType && !proc.killedByAm) {
8829                    killUnneededProcessLocked(proc, reason);
8830                    killed = true;
8831                }
8832            }
8833        }
8834        return killed;
8835    }
8836
8837    @Override
8838    public void killUid(int uid, String reason) {
8839        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8840            throw new SecurityException("killUid only available to the system");
8841        }
8842        synchronized (this) {
8843            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8844                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8845                    reason != null ? reason : "kill uid");
8846        }
8847    }
8848
8849    @Override
8850    public boolean killProcessesBelowForeground(String reason) {
8851        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8852            throw new SecurityException("killProcessesBelowForeground() only available to system");
8853        }
8854
8855        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8856    }
8857
8858    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8859        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8860            throw new SecurityException("killProcessesBelowAdj() only available to system");
8861        }
8862
8863        boolean killed = false;
8864        synchronized (mPidsSelfLocked) {
8865            final int size = mPidsSelfLocked.size();
8866            for (int i = 0; i < size; i++) {
8867                final int pid = mPidsSelfLocked.keyAt(i);
8868                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8869                if (proc == null) continue;
8870
8871                final int adj = proc.setAdj;
8872                if (adj > belowAdj && !proc.killedByAm) {
8873                    killUnneededProcessLocked(proc, reason);
8874                    killed = true;
8875                }
8876            }
8877        }
8878        return killed;
8879    }
8880
8881    @Override
8882    public void hang(final IBinder who, boolean allowRestart) {
8883        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8884                != PackageManager.PERMISSION_GRANTED) {
8885            throw new SecurityException("Requires permission "
8886                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8887        }
8888
8889        final IBinder.DeathRecipient death = new DeathRecipient() {
8890            @Override
8891            public void binderDied() {
8892                synchronized (this) {
8893                    notifyAll();
8894                }
8895            }
8896        };
8897
8898        try {
8899            who.linkToDeath(death, 0);
8900        } catch (RemoteException e) {
8901            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8902            return;
8903        }
8904
8905        synchronized (this) {
8906            Watchdog.getInstance().setAllowRestart(allowRestart);
8907            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8908            synchronized (death) {
8909                while (who.isBinderAlive()) {
8910                    try {
8911                        death.wait();
8912                    } catch (InterruptedException e) {
8913                    }
8914                }
8915            }
8916            Watchdog.getInstance().setAllowRestart(true);
8917        }
8918    }
8919
8920    @Override
8921    public void restart() {
8922        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8923                != PackageManager.PERMISSION_GRANTED) {
8924            throw new SecurityException("Requires permission "
8925                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8926        }
8927
8928        Log.i(TAG, "Sending shutdown broadcast...");
8929
8930        BroadcastReceiver br = new BroadcastReceiver() {
8931            @Override public void onReceive(Context context, Intent intent) {
8932                // Now the broadcast is done, finish up the low-level shutdown.
8933                Log.i(TAG, "Shutting down activity manager...");
8934                shutdown(10000);
8935                Log.i(TAG, "Shutdown complete, restarting!");
8936                Process.killProcess(Process.myPid());
8937                System.exit(10);
8938            }
8939        };
8940
8941        // First send the high-level shut down broadcast.
8942        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8943        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8944        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8945        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8946        mContext.sendOrderedBroadcastAsUser(intent,
8947                UserHandle.ALL, null, br, mHandler, 0, null, null);
8948        */
8949        br.onReceive(mContext, intent);
8950    }
8951
8952    private long getLowRamTimeSinceIdle(long now) {
8953        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8954    }
8955
8956    @Override
8957    public void performIdleMaintenance() {
8958        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8959                != PackageManager.PERMISSION_GRANTED) {
8960            throw new SecurityException("Requires permission "
8961                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8962        }
8963
8964        synchronized (this) {
8965            final long now = SystemClock.uptimeMillis();
8966            final long timeSinceLastIdle = now - mLastIdleTime;
8967            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
8968            mLastIdleTime = now;
8969            mLowRamTimeSinceLastIdle = 0;
8970            if (mLowRamStartTime != 0) {
8971                mLowRamStartTime = now;
8972            }
8973
8974            StringBuilder sb = new StringBuilder(128);
8975            sb.append("Idle maintenance over ");
8976            TimeUtils.formatDuration(timeSinceLastIdle, sb);
8977            sb.append(" low RAM for ");
8978            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
8979            Slog.i(TAG, sb.toString());
8980
8981            // If at least 1/3 of our time since the last idle period has been spent
8982            // with RAM low, then we want to kill processes.
8983            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
8984
8985            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
8986                ProcessRecord proc = mLruProcesses.get(i);
8987                if (proc.notCachedSinceIdle) {
8988                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
8989                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
8990                        if (doKilling && proc.initialIdlePss != 0
8991                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
8992                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
8993                                    + " from " + proc.initialIdlePss + ")");
8994                        }
8995                    }
8996                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
8997                    proc.notCachedSinceIdle = true;
8998                    proc.initialIdlePss = 0;
8999                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9000                            mSleeping, now);
9001                }
9002            }
9003
9004            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9005            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9006        }
9007    }
9008
9009    private void retrieveSettings() {
9010        final ContentResolver resolver = mContext.getContentResolver();
9011        String debugApp = Settings.Global.getString(
9012            resolver, Settings.Global.DEBUG_APP);
9013        boolean waitForDebugger = Settings.Global.getInt(
9014            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9015        boolean alwaysFinishActivities = Settings.Global.getInt(
9016            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9017        boolean forceRtl = Settings.Global.getInt(
9018                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9019        // Transfer any global setting for forcing RTL layout, into a System Property
9020        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9021
9022        Configuration configuration = new Configuration();
9023        Settings.System.getConfiguration(resolver, configuration);
9024        if (forceRtl) {
9025            // This will take care of setting the correct layout direction flags
9026            configuration.setLayoutDirection(configuration.locale);
9027        }
9028
9029        synchronized (this) {
9030            mDebugApp = mOrigDebugApp = debugApp;
9031            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9032            mAlwaysFinishActivities = alwaysFinishActivities;
9033            // This happens before any activities are started, so we can
9034            // change mConfiguration in-place.
9035            updateConfigurationLocked(configuration, null, false, true);
9036            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9037        }
9038    }
9039
9040    public boolean testIsSystemReady() {
9041        // no need to synchronize(this) just to read & return the value
9042        return mSystemReady;
9043    }
9044
9045    private static File getCalledPreBootReceiversFile() {
9046        File dataDir = Environment.getDataDirectory();
9047        File systemDir = new File(dataDir, "system");
9048        File fname = new File(systemDir, "called_pre_boots.dat");
9049        return fname;
9050    }
9051
9052    static final int LAST_DONE_VERSION = 10000;
9053
9054    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9055        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9056        File file = getCalledPreBootReceiversFile();
9057        FileInputStream fis = null;
9058        try {
9059            fis = new FileInputStream(file);
9060            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9061            int fvers = dis.readInt();
9062            if (fvers == LAST_DONE_VERSION) {
9063                String vers = dis.readUTF();
9064                String codename = dis.readUTF();
9065                String build = dis.readUTF();
9066                if (android.os.Build.VERSION.RELEASE.equals(vers)
9067                        && android.os.Build.VERSION.CODENAME.equals(codename)
9068                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9069                    int num = dis.readInt();
9070                    while (num > 0) {
9071                        num--;
9072                        String pkg = dis.readUTF();
9073                        String cls = dis.readUTF();
9074                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9075                    }
9076                }
9077            }
9078        } catch (FileNotFoundException e) {
9079        } catch (IOException e) {
9080            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9081        } finally {
9082            if (fis != null) {
9083                try {
9084                    fis.close();
9085                } catch (IOException e) {
9086                }
9087            }
9088        }
9089        return lastDoneReceivers;
9090    }
9091
9092    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9093        File file = getCalledPreBootReceiversFile();
9094        FileOutputStream fos = null;
9095        DataOutputStream dos = null;
9096        try {
9097            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9098            fos = new FileOutputStream(file);
9099            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9100            dos.writeInt(LAST_DONE_VERSION);
9101            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9102            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9103            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9104            dos.writeInt(list.size());
9105            for (int i=0; i<list.size(); i++) {
9106                dos.writeUTF(list.get(i).getPackageName());
9107                dos.writeUTF(list.get(i).getClassName());
9108            }
9109        } catch (IOException e) {
9110            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9111            file.delete();
9112        } finally {
9113            FileUtils.sync(fos);
9114            if (dos != null) {
9115                try {
9116                    dos.close();
9117                } catch (IOException e) {
9118                    // TODO Auto-generated catch block
9119                    e.printStackTrace();
9120                }
9121            }
9122        }
9123    }
9124
9125    public void systemReady(final Runnable goingCallback) {
9126        synchronized(this) {
9127            if (mSystemReady) {
9128                if (goingCallback != null) goingCallback.run();
9129                return;
9130            }
9131
9132            // Check to see if there are any update receivers to run.
9133            if (!mDidUpdate) {
9134                if (mWaitingUpdate) {
9135                    return;
9136                }
9137                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9138                List<ResolveInfo> ris = null;
9139                try {
9140                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9141                            intent, null, 0, 0);
9142                } catch (RemoteException e) {
9143                }
9144                if (ris != null) {
9145                    for (int i=ris.size()-1; i>=0; i--) {
9146                        if ((ris.get(i).activityInfo.applicationInfo.flags
9147                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9148                            ris.remove(i);
9149                        }
9150                    }
9151                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9152
9153                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9154
9155                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9156                    for (int i=0; i<ris.size(); i++) {
9157                        ActivityInfo ai = ris.get(i).activityInfo;
9158                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9159                        if (lastDoneReceivers.contains(comp)) {
9160                            // We already did the pre boot receiver for this app with the current
9161                            // platform version, so don't do it again...
9162                            ris.remove(i);
9163                            i--;
9164                            // ...however, do keep it as one that has been done, so we don't
9165                            // forget about it when rewriting the file of last done receivers.
9166                            doneReceivers.add(comp);
9167                        }
9168                    }
9169
9170                    final int[] users = getUsersLocked();
9171                    for (int i=0; i<ris.size(); i++) {
9172                        ActivityInfo ai = ris.get(i).activityInfo;
9173                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9174                        doneReceivers.add(comp);
9175                        intent.setComponent(comp);
9176                        for (int j=0; j<users.length; j++) {
9177                            IIntentReceiver finisher = null;
9178                            if (i == ris.size()-1 && j == users.length-1) {
9179                                finisher = new IIntentReceiver.Stub() {
9180                                    public void performReceive(Intent intent, int resultCode,
9181                                            String data, Bundle extras, boolean ordered,
9182                                            boolean sticky, int sendingUser) {
9183                                        // The raw IIntentReceiver interface is called
9184                                        // with the AM lock held, so redispatch to
9185                                        // execute our code without the lock.
9186                                        mHandler.post(new Runnable() {
9187                                            public void run() {
9188                                                synchronized (ActivityManagerService.this) {
9189                                                    mDidUpdate = true;
9190                                                }
9191                                                writeLastDonePreBootReceivers(doneReceivers);
9192                                                showBootMessage(mContext.getText(
9193                                                        R.string.android_upgrading_complete),
9194                                                        false);
9195                                                systemReady(goingCallback);
9196                                            }
9197                                        });
9198                                    }
9199                                };
9200                            }
9201                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9202                                    + " for user " + users[j]);
9203                            broadcastIntentLocked(null, null, intent, null, finisher,
9204                                    0, null, null, null, AppOpsManager.OP_NONE,
9205                                    true, false, MY_PID, Process.SYSTEM_UID,
9206                                    users[j]);
9207                            if (finisher != null) {
9208                                mWaitingUpdate = true;
9209                            }
9210                        }
9211                    }
9212                }
9213                if (mWaitingUpdate) {
9214                    return;
9215                }
9216                mDidUpdate = true;
9217            }
9218
9219            mAppOpsService.systemReady();
9220            mSystemReady = true;
9221        }
9222
9223        ArrayList<ProcessRecord> procsToKill = null;
9224        synchronized(mPidsSelfLocked) {
9225            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9226                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9227                if (!isAllowedWhileBooting(proc.info)){
9228                    if (procsToKill == null) {
9229                        procsToKill = new ArrayList<ProcessRecord>();
9230                    }
9231                    procsToKill.add(proc);
9232                }
9233            }
9234        }
9235
9236        synchronized(this) {
9237            if (procsToKill != null) {
9238                for (int i=procsToKill.size()-1; i>=0; i--) {
9239                    ProcessRecord proc = procsToKill.get(i);
9240                    Slog.i(TAG, "Removing system update proc: " + proc);
9241                    removeProcessLocked(proc, true, false, "system update done");
9242                }
9243            }
9244
9245            // Now that we have cleaned up any update processes, we
9246            // are ready to start launching real processes and know that
9247            // we won't trample on them any more.
9248            mProcessesReady = true;
9249        }
9250
9251        Slog.i(TAG, "System now ready");
9252        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9253            SystemClock.uptimeMillis());
9254
9255        synchronized(this) {
9256            // Make sure we have no pre-ready processes sitting around.
9257
9258            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9259                ResolveInfo ri = mContext.getPackageManager()
9260                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9261                                STOCK_PM_FLAGS);
9262                CharSequence errorMsg = null;
9263                if (ri != null) {
9264                    ActivityInfo ai = ri.activityInfo;
9265                    ApplicationInfo app = ai.applicationInfo;
9266                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9267                        mTopAction = Intent.ACTION_FACTORY_TEST;
9268                        mTopData = null;
9269                        mTopComponent = new ComponentName(app.packageName,
9270                                ai.name);
9271                    } else {
9272                        errorMsg = mContext.getResources().getText(
9273                                com.android.internal.R.string.factorytest_not_system);
9274                    }
9275                } else {
9276                    errorMsg = mContext.getResources().getText(
9277                            com.android.internal.R.string.factorytest_no_action);
9278                }
9279                if (errorMsg != null) {
9280                    mTopAction = null;
9281                    mTopData = null;
9282                    mTopComponent = null;
9283                    Message msg = Message.obtain();
9284                    msg.what = SHOW_FACTORY_ERROR_MSG;
9285                    msg.getData().putCharSequence("msg", errorMsg);
9286                    mHandler.sendMessage(msg);
9287                }
9288            }
9289        }
9290
9291        retrieveSettings();
9292
9293        synchronized (this) {
9294            readGrantedUriPermissionsLocked();
9295        }
9296
9297        if (goingCallback != null) goingCallback.run();
9298
9299        synchronized (this) {
9300            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9301                try {
9302                    List apps = AppGlobals.getPackageManager().
9303                        getPersistentApplications(STOCK_PM_FLAGS);
9304                    if (apps != null) {
9305                        int N = apps.size();
9306                        int i;
9307                        for (i=0; i<N; i++) {
9308                            ApplicationInfo info
9309                                = (ApplicationInfo)apps.get(i);
9310                            if (info != null &&
9311                                    !info.packageName.equals("android")) {
9312                                addAppLocked(info, false, null /* ABI override */);
9313                            }
9314                        }
9315                    }
9316                } catch (RemoteException ex) {
9317                    // pm is in same process, this will never happen.
9318                }
9319            }
9320
9321            // Start up initial activity.
9322            mBooting = true;
9323
9324            try {
9325                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9326                    Message msg = Message.obtain();
9327                    msg.what = SHOW_UID_ERROR_MSG;
9328                    mHandler.sendMessage(msg);
9329                }
9330            } catch (RemoteException e) {
9331            }
9332
9333            long ident = Binder.clearCallingIdentity();
9334            try {
9335                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9336                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9337                        | Intent.FLAG_RECEIVER_FOREGROUND);
9338                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9339                broadcastIntentLocked(null, null, intent,
9340                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9341                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9342                intent = new Intent(Intent.ACTION_USER_STARTING);
9343                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9344                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9345                broadcastIntentLocked(null, null, intent,
9346                        null, new IIntentReceiver.Stub() {
9347                            @Override
9348                            public void performReceive(Intent intent, int resultCode, String data,
9349                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9350                                    throws RemoteException {
9351                            }
9352                        }, 0, null, null,
9353                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9354                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9355            } finally {
9356                Binder.restoreCallingIdentity(ident);
9357            }
9358            mStackSupervisor.resumeTopActivitiesLocked();
9359            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9360        }
9361    }
9362
9363    private boolean makeAppCrashingLocked(ProcessRecord app,
9364            String shortMsg, String longMsg, String stackTrace) {
9365        app.crashing = true;
9366        app.crashingReport = generateProcessError(app,
9367                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9368        startAppProblemLocked(app);
9369        app.stopFreezingAllLocked();
9370        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9371    }
9372
9373    private void makeAppNotRespondingLocked(ProcessRecord app,
9374            String activity, String shortMsg, String longMsg) {
9375        app.notResponding = true;
9376        app.notRespondingReport = generateProcessError(app,
9377                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9378                activity, shortMsg, longMsg, null);
9379        startAppProblemLocked(app);
9380        app.stopFreezingAllLocked();
9381    }
9382
9383    /**
9384     * Generate a process error record, suitable for attachment to a ProcessRecord.
9385     *
9386     * @param app The ProcessRecord in which the error occurred.
9387     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9388     *                      ActivityManager.AppErrorStateInfo
9389     * @param activity The activity associated with the crash, if known.
9390     * @param shortMsg Short message describing the crash.
9391     * @param longMsg Long message describing the crash.
9392     * @param stackTrace Full crash stack trace, may be null.
9393     *
9394     * @return Returns a fully-formed AppErrorStateInfo record.
9395     */
9396    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9397            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9398        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9399
9400        report.condition = condition;
9401        report.processName = app.processName;
9402        report.pid = app.pid;
9403        report.uid = app.info.uid;
9404        report.tag = activity;
9405        report.shortMsg = shortMsg;
9406        report.longMsg = longMsg;
9407        report.stackTrace = stackTrace;
9408
9409        return report;
9410    }
9411
9412    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9413        synchronized (this) {
9414            app.crashing = false;
9415            app.crashingReport = null;
9416            app.notResponding = false;
9417            app.notRespondingReport = null;
9418            if (app.anrDialog == fromDialog) {
9419                app.anrDialog = null;
9420            }
9421            if (app.waitDialog == fromDialog) {
9422                app.waitDialog = null;
9423            }
9424            if (app.pid > 0 && app.pid != MY_PID) {
9425                handleAppCrashLocked(app, null, null, null);
9426                killUnneededProcessLocked(app, "user request after error");
9427            }
9428        }
9429    }
9430
9431    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9432            String stackTrace) {
9433        long now = SystemClock.uptimeMillis();
9434
9435        Long crashTime;
9436        if (!app.isolated) {
9437            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9438        } else {
9439            crashTime = null;
9440        }
9441        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9442            // This process loses!
9443            Slog.w(TAG, "Process " + app.info.processName
9444                    + " has crashed too many times: killing!");
9445            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9446                    app.userId, app.info.processName, app.uid);
9447            mStackSupervisor.handleAppCrashLocked(app);
9448            if (!app.persistent) {
9449                // We don't want to start this process again until the user
9450                // explicitly does so...  but for persistent process, we really
9451                // need to keep it running.  If a persistent process is actually
9452                // repeatedly crashing, then badness for everyone.
9453                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9454                        app.info.processName);
9455                if (!app.isolated) {
9456                    // XXX We don't have a way to mark isolated processes
9457                    // as bad, since they don't have a peristent identity.
9458                    mBadProcesses.put(app.info.processName, app.uid,
9459                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9460                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9461                }
9462                app.bad = true;
9463                app.removed = true;
9464                // Don't let services in this process be restarted and potentially
9465                // annoy the user repeatedly.  Unless it is persistent, since those
9466                // processes run critical code.
9467                removeProcessLocked(app, false, false, "crash");
9468                mStackSupervisor.resumeTopActivitiesLocked();
9469                return false;
9470            }
9471            mStackSupervisor.resumeTopActivitiesLocked();
9472        } else {
9473            mStackSupervisor.finishTopRunningActivityLocked(app);
9474        }
9475
9476        // Bump up the crash count of any services currently running in the proc.
9477        for (int i=app.services.size()-1; i>=0; i--) {
9478            // Any services running in the application need to be placed
9479            // back in the pending list.
9480            ServiceRecord sr = app.services.valueAt(i);
9481            sr.crashCount++;
9482        }
9483
9484        // If the crashing process is what we consider to be the "home process" and it has been
9485        // replaced by a third-party app, clear the package preferred activities from packages
9486        // with a home activity running in the process to prevent a repeatedly crashing app
9487        // from blocking the user to manually clear the list.
9488        final ArrayList<ActivityRecord> activities = app.activities;
9489        if (app == mHomeProcess && activities.size() > 0
9490                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9491            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9492                final ActivityRecord r = activities.get(activityNdx);
9493                if (r.isHomeActivity()) {
9494                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9495                    try {
9496                        ActivityThread.getPackageManager()
9497                                .clearPackagePreferredActivities(r.packageName);
9498                    } catch (RemoteException c) {
9499                        // pm is in same process, this will never happen.
9500                    }
9501                }
9502            }
9503        }
9504
9505        if (!app.isolated) {
9506            // XXX Can't keep track of crash times for isolated processes,
9507            // because they don't have a perisistent identity.
9508            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9509        }
9510
9511        return true;
9512    }
9513
9514    void startAppProblemLocked(ProcessRecord app) {
9515        if (app.userId == mCurrentUserId) {
9516            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9517                    mContext, app.info.packageName, app.info.flags);
9518        } else {
9519            // If this app is not running under the current user, then we
9520            // can't give it a report button because that would require
9521            // launching the report UI under a different user.
9522            app.errorReportReceiver = null;
9523        }
9524        skipCurrentReceiverLocked(app);
9525    }
9526
9527    void skipCurrentReceiverLocked(ProcessRecord app) {
9528        for (BroadcastQueue queue : mBroadcastQueues) {
9529            queue.skipCurrentReceiverLocked(app);
9530        }
9531    }
9532
9533    /**
9534     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9535     * The application process will exit immediately after this call returns.
9536     * @param app object of the crashing app, null for the system server
9537     * @param crashInfo describing the exception
9538     */
9539    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9540        ProcessRecord r = findAppProcess(app, "Crash");
9541        final String processName = app == null ? "system_server"
9542                : (r == null ? "unknown" : r.processName);
9543
9544        handleApplicationCrashInner("crash", r, processName, crashInfo);
9545    }
9546
9547    /* Native crash reporting uses this inner version because it needs to be somewhat
9548     * decoupled from the AM-managed cleanup lifecycle
9549     */
9550    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9551            ApplicationErrorReport.CrashInfo crashInfo) {
9552        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9553                UserHandle.getUserId(Binder.getCallingUid()), processName,
9554                r == null ? -1 : r.info.flags,
9555                crashInfo.exceptionClassName,
9556                crashInfo.exceptionMessage,
9557                crashInfo.throwFileName,
9558                crashInfo.throwLineNumber);
9559
9560        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9561
9562        crashApplication(r, crashInfo);
9563    }
9564
9565    public void handleApplicationStrictModeViolation(
9566            IBinder app,
9567            int violationMask,
9568            StrictMode.ViolationInfo info) {
9569        ProcessRecord r = findAppProcess(app, "StrictMode");
9570        if (r == null) {
9571            return;
9572        }
9573
9574        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9575            Integer stackFingerprint = info.hashCode();
9576            boolean logIt = true;
9577            synchronized (mAlreadyLoggedViolatedStacks) {
9578                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9579                    logIt = false;
9580                    // TODO: sub-sample into EventLog for these, with
9581                    // the info.durationMillis?  Then we'd get
9582                    // the relative pain numbers, without logging all
9583                    // the stack traces repeatedly.  We'd want to do
9584                    // likewise in the client code, which also does
9585                    // dup suppression, before the Binder call.
9586                } else {
9587                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9588                        mAlreadyLoggedViolatedStacks.clear();
9589                    }
9590                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9591                }
9592            }
9593            if (logIt) {
9594                logStrictModeViolationToDropBox(r, info);
9595            }
9596        }
9597
9598        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9599            AppErrorResult result = new AppErrorResult();
9600            synchronized (this) {
9601                final long origId = Binder.clearCallingIdentity();
9602
9603                Message msg = Message.obtain();
9604                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9605                HashMap<String, Object> data = new HashMap<String, Object>();
9606                data.put("result", result);
9607                data.put("app", r);
9608                data.put("violationMask", violationMask);
9609                data.put("info", info);
9610                msg.obj = data;
9611                mHandler.sendMessage(msg);
9612
9613                Binder.restoreCallingIdentity(origId);
9614            }
9615            int res = result.get();
9616            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9617        }
9618    }
9619
9620    // Depending on the policy in effect, there could be a bunch of
9621    // these in quick succession so we try to batch these together to
9622    // minimize disk writes, number of dropbox entries, and maximize
9623    // compression, by having more fewer, larger records.
9624    private void logStrictModeViolationToDropBox(
9625            ProcessRecord process,
9626            StrictMode.ViolationInfo info) {
9627        if (info == null) {
9628            return;
9629        }
9630        final boolean isSystemApp = process == null ||
9631                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9632                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9633        final String processName = process == null ? "unknown" : process.processName;
9634        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9635        final DropBoxManager dbox = (DropBoxManager)
9636                mContext.getSystemService(Context.DROPBOX_SERVICE);
9637
9638        // Exit early if the dropbox isn't configured to accept this report type.
9639        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9640
9641        boolean bufferWasEmpty;
9642        boolean needsFlush;
9643        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9644        synchronized (sb) {
9645            bufferWasEmpty = sb.length() == 0;
9646            appendDropBoxProcessHeaders(process, processName, sb);
9647            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9648            sb.append("System-App: ").append(isSystemApp).append("\n");
9649            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9650            if (info.violationNumThisLoop != 0) {
9651                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9652            }
9653            if (info.numAnimationsRunning != 0) {
9654                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9655            }
9656            if (info.broadcastIntentAction != null) {
9657                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9658            }
9659            if (info.durationMillis != -1) {
9660                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9661            }
9662            if (info.numInstances != -1) {
9663                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9664            }
9665            if (info.tags != null) {
9666                for (String tag : info.tags) {
9667                    sb.append("Span-Tag: ").append(tag).append("\n");
9668                }
9669            }
9670            sb.append("\n");
9671            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9672                sb.append(info.crashInfo.stackTrace);
9673            }
9674            sb.append("\n");
9675
9676            // Only buffer up to ~64k.  Various logging bits truncate
9677            // things at 128k.
9678            needsFlush = (sb.length() > 64 * 1024);
9679        }
9680
9681        // Flush immediately if the buffer's grown too large, or this
9682        // is a non-system app.  Non-system apps are isolated with a
9683        // different tag & policy and not batched.
9684        //
9685        // Batching is useful during internal testing with
9686        // StrictMode settings turned up high.  Without batching,
9687        // thousands of separate files could be created on boot.
9688        if (!isSystemApp || needsFlush) {
9689            new Thread("Error dump: " + dropboxTag) {
9690                @Override
9691                public void run() {
9692                    String report;
9693                    synchronized (sb) {
9694                        report = sb.toString();
9695                        sb.delete(0, sb.length());
9696                        sb.trimToSize();
9697                    }
9698                    if (report.length() != 0) {
9699                        dbox.addText(dropboxTag, report);
9700                    }
9701                }
9702            }.start();
9703            return;
9704        }
9705
9706        // System app batching:
9707        if (!bufferWasEmpty) {
9708            // An existing dropbox-writing thread is outstanding, so
9709            // we don't need to start it up.  The existing thread will
9710            // catch the buffer appends we just did.
9711            return;
9712        }
9713
9714        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9715        // (After this point, we shouldn't access AMS internal data structures.)
9716        new Thread("Error dump: " + dropboxTag) {
9717            @Override
9718            public void run() {
9719                // 5 second sleep to let stacks arrive and be batched together
9720                try {
9721                    Thread.sleep(5000);  // 5 seconds
9722                } catch (InterruptedException e) {}
9723
9724                String errorReport;
9725                synchronized (mStrictModeBuffer) {
9726                    errorReport = mStrictModeBuffer.toString();
9727                    if (errorReport.length() == 0) {
9728                        return;
9729                    }
9730                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9731                    mStrictModeBuffer.trimToSize();
9732                }
9733                dbox.addText(dropboxTag, errorReport);
9734            }
9735        }.start();
9736    }
9737
9738    /**
9739     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9740     * @param app object of the crashing app, null for the system server
9741     * @param tag reported by the caller
9742     * @param crashInfo describing the context of the error
9743     * @return true if the process should exit immediately (WTF is fatal)
9744     */
9745    public boolean handleApplicationWtf(IBinder app, String tag,
9746            ApplicationErrorReport.CrashInfo crashInfo) {
9747        ProcessRecord r = findAppProcess(app, "WTF");
9748        final String processName = app == null ? "system_server"
9749                : (r == null ? "unknown" : r.processName);
9750
9751        EventLog.writeEvent(EventLogTags.AM_WTF,
9752                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9753                processName,
9754                r == null ? -1 : r.info.flags,
9755                tag, crashInfo.exceptionMessage);
9756
9757        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9758
9759        if (r != null && r.pid != Process.myPid() &&
9760                Settings.Global.getInt(mContext.getContentResolver(),
9761                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9762            crashApplication(r, crashInfo);
9763            return true;
9764        } else {
9765            return false;
9766        }
9767    }
9768
9769    /**
9770     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9771     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9772     */
9773    private ProcessRecord findAppProcess(IBinder app, String reason) {
9774        if (app == null) {
9775            return null;
9776        }
9777
9778        synchronized (this) {
9779            final int NP = mProcessNames.getMap().size();
9780            for (int ip=0; ip<NP; ip++) {
9781                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9782                final int NA = apps.size();
9783                for (int ia=0; ia<NA; ia++) {
9784                    ProcessRecord p = apps.valueAt(ia);
9785                    if (p.thread != null && p.thread.asBinder() == app) {
9786                        return p;
9787                    }
9788                }
9789            }
9790
9791            Slog.w(TAG, "Can't find mystery application for " + reason
9792                    + " from pid=" + Binder.getCallingPid()
9793                    + " uid=" + Binder.getCallingUid() + ": " + app);
9794            return null;
9795        }
9796    }
9797
9798    /**
9799     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9800     * to append various headers to the dropbox log text.
9801     */
9802    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9803            StringBuilder sb) {
9804        // Watchdog thread ends up invoking this function (with
9805        // a null ProcessRecord) to add the stack file to dropbox.
9806        // Do not acquire a lock on this (am) in such cases, as it
9807        // could cause a potential deadlock, if and when watchdog
9808        // is invoked due to unavailability of lock on am and it
9809        // would prevent watchdog from killing system_server.
9810        if (process == null) {
9811            sb.append("Process: ").append(processName).append("\n");
9812            return;
9813        }
9814        // Note: ProcessRecord 'process' is guarded by the service
9815        // instance.  (notably process.pkgList, which could otherwise change
9816        // concurrently during execution of this method)
9817        synchronized (this) {
9818            sb.append("Process: ").append(processName).append("\n");
9819            int flags = process.info.flags;
9820            IPackageManager pm = AppGlobals.getPackageManager();
9821            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9822            for (int ip=0; ip<process.pkgList.size(); ip++) {
9823                String pkg = process.pkgList.keyAt(ip);
9824                sb.append("Package: ").append(pkg);
9825                try {
9826                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9827                    if (pi != null) {
9828                        sb.append(" v").append(pi.versionCode);
9829                        if (pi.versionName != null) {
9830                            sb.append(" (").append(pi.versionName).append(")");
9831                        }
9832                    }
9833                } catch (RemoteException e) {
9834                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9835                }
9836                sb.append("\n");
9837            }
9838        }
9839    }
9840
9841    private static String processClass(ProcessRecord process) {
9842        if (process == null || process.pid == MY_PID) {
9843            return "system_server";
9844        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9845            return "system_app";
9846        } else {
9847            return "data_app";
9848        }
9849    }
9850
9851    /**
9852     * Write a description of an error (crash, WTF, ANR) to the drop box.
9853     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9854     * @param process which caused the error, null means the system server
9855     * @param activity which triggered the error, null if unknown
9856     * @param parent activity related to the error, null if unknown
9857     * @param subject line related to the error, null if absent
9858     * @param report in long form describing the error, null if absent
9859     * @param logFile to include in the report, null if none
9860     * @param crashInfo giving an application stack trace, null if absent
9861     */
9862    public void addErrorToDropBox(String eventType,
9863            ProcessRecord process, String processName, ActivityRecord activity,
9864            ActivityRecord parent, String subject,
9865            final String report, final File logFile,
9866            final ApplicationErrorReport.CrashInfo crashInfo) {
9867        // NOTE -- this must never acquire the ActivityManagerService lock,
9868        // otherwise the watchdog may be prevented from resetting the system.
9869
9870        final String dropboxTag = processClass(process) + "_" + eventType;
9871        final DropBoxManager dbox = (DropBoxManager)
9872                mContext.getSystemService(Context.DROPBOX_SERVICE);
9873
9874        // Exit early if the dropbox isn't configured to accept this report type.
9875        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9876
9877        final StringBuilder sb = new StringBuilder(1024);
9878        appendDropBoxProcessHeaders(process, processName, sb);
9879        if (activity != null) {
9880            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9881        }
9882        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9883            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9884        }
9885        if (parent != null && parent != activity) {
9886            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9887        }
9888        if (subject != null) {
9889            sb.append("Subject: ").append(subject).append("\n");
9890        }
9891        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9892        if (Debug.isDebuggerConnected()) {
9893            sb.append("Debugger: Connected\n");
9894        }
9895        sb.append("\n");
9896
9897        // Do the rest in a worker thread to avoid blocking the caller on I/O
9898        // (After this point, we shouldn't access AMS internal data structures.)
9899        Thread worker = new Thread("Error dump: " + dropboxTag) {
9900            @Override
9901            public void run() {
9902                if (report != null) {
9903                    sb.append(report);
9904                }
9905                if (logFile != null) {
9906                    try {
9907                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9908                                    "\n\n[[TRUNCATED]]"));
9909                    } catch (IOException e) {
9910                        Slog.e(TAG, "Error reading " + logFile, e);
9911                    }
9912                }
9913                if (crashInfo != null && crashInfo.stackTrace != null) {
9914                    sb.append(crashInfo.stackTrace);
9915                }
9916
9917                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9918                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9919                if (lines > 0) {
9920                    sb.append("\n");
9921
9922                    // Merge several logcat streams, and take the last N lines
9923                    InputStreamReader input = null;
9924                    try {
9925                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9926                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9927                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9928
9929                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9930                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9931                        input = new InputStreamReader(logcat.getInputStream());
9932
9933                        int num;
9934                        char[] buf = new char[8192];
9935                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9936                    } catch (IOException e) {
9937                        Slog.e(TAG, "Error running logcat", e);
9938                    } finally {
9939                        if (input != null) try { input.close(); } catch (IOException e) {}
9940                    }
9941                }
9942
9943                dbox.addText(dropboxTag, sb.toString());
9944            }
9945        };
9946
9947        if (process == null) {
9948            // If process is null, we are being called from some internal code
9949            // and may be about to die -- run this synchronously.
9950            worker.run();
9951        } else {
9952            worker.start();
9953        }
9954    }
9955
9956    /**
9957     * Bring up the "unexpected error" dialog box for a crashing app.
9958     * Deal with edge cases (intercepts from instrumented applications,
9959     * ActivityController, error intent receivers, that sort of thing).
9960     * @param r the application crashing
9961     * @param crashInfo describing the failure
9962     */
9963    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
9964        long timeMillis = System.currentTimeMillis();
9965        String shortMsg = crashInfo.exceptionClassName;
9966        String longMsg = crashInfo.exceptionMessage;
9967        String stackTrace = crashInfo.stackTrace;
9968        if (shortMsg != null && longMsg != null) {
9969            longMsg = shortMsg + ": " + longMsg;
9970        } else if (shortMsg != null) {
9971            longMsg = shortMsg;
9972        }
9973
9974        AppErrorResult result = new AppErrorResult();
9975        synchronized (this) {
9976            if (mController != null) {
9977                try {
9978                    String name = r != null ? r.processName : null;
9979                    int pid = r != null ? r.pid : Binder.getCallingPid();
9980                    if (!mController.appCrashed(name, pid,
9981                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
9982                        Slog.w(TAG, "Force-killing crashed app " + name
9983                                + " at watcher's request");
9984                        Process.killProcess(pid);
9985                        return;
9986                    }
9987                } catch (RemoteException e) {
9988                    mController = null;
9989                    Watchdog.getInstance().setActivityController(null);
9990                }
9991            }
9992
9993            final long origId = Binder.clearCallingIdentity();
9994
9995            // If this process is running instrumentation, finish it.
9996            if (r != null && r.instrumentationClass != null) {
9997                Slog.w(TAG, "Error in app " + r.processName
9998                      + " running instrumentation " + r.instrumentationClass + ":");
9999                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10000                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10001                Bundle info = new Bundle();
10002                info.putString("shortMsg", shortMsg);
10003                info.putString("longMsg", longMsg);
10004                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10005                Binder.restoreCallingIdentity(origId);
10006                return;
10007            }
10008
10009            // If we can't identify the process or it's already exceeded its crash quota,
10010            // quit right away without showing a crash dialog.
10011            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10012                Binder.restoreCallingIdentity(origId);
10013                return;
10014            }
10015
10016            Message msg = Message.obtain();
10017            msg.what = SHOW_ERROR_MSG;
10018            HashMap data = new HashMap();
10019            data.put("result", result);
10020            data.put("app", r);
10021            msg.obj = data;
10022            mHandler.sendMessage(msg);
10023
10024            Binder.restoreCallingIdentity(origId);
10025        }
10026
10027        int res = result.get();
10028
10029        Intent appErrorIntent = null;
10030        synchronized (this) {
10031            if (r != null && !r.isolated) {
10032                // XXX Can't keep track of crash time for isolated processes,
10033                // since they don't have a persistent identity.
10034                mProcessCrashTimes.put(r.info.processName, r.uid,
10035                        SystemClock.uptimeMillis());
10036            }
10037            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10038                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10039            }
10040        }
10041
10042        if (appErrorIntent != null) {
10043            try {
10044                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10045            } catch (ActivityNotFoundException e) {
10046                Slog.w(TAG, "bug report receiver dissappeared", e);
10047            }
10048        }
10049    }
10050
10051    Intent createAppErrorIntentLocked(ProcessRecord r,
10052            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10053        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10054        if (report == null) {
10055            return null;
10056        }
10057        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10058        result.setComponent(r.errorReportReceiver);
10059        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10060        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10061        return result;
10062    }
10063
10064    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10065            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10066        if (r.errorReportReceiver == null) {
10067            return null;
10068        }
10069
10070        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10071            return null;
10072        }
10073
10074        ApplicationErrorReport report = new ApplicationErrorReport();
10075        report.packageName = r.info.packageName;
10076        report.installerPackageName = r.errorReportReceiver.getPackageName();
10077        report.processName = r.processName;
10078        report.time = timeMillis;
10079        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10080
10081        if (r.crashing || r.forceCrashReport) {
10082            report.type = ApplicationErrorReport.TYPE_CRASH;
10083            report.crashInfo = crashInfo;
10084        } else if (r.notResponding) {
10085            report.type = ApplicationErrorReport.TYPE_ANR;
10086            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10087
10088            report.anrInfo.activity = r.notRespondingReport.tag;
10089            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10090            report.anrInfo.info = r.notRespondingReport.longMsg;
10091        }
10092
10093        return report;
10094    }
10095
10096    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10097        enforceNotIsolatedCaller("getProcessesInErrorState");
10098        // assume our apps are happy - lazy create the list
10099        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10100
10101        final boolean allUsers = ActivityManager.checkUidPermission(
10102                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10103                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10104        int userId = UserHandle.getUserId(Binder.getCallingUid());
10105
10106        synchronized (this) {
10107
10108            // iterate across all processes
10109            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10110                ProcessRecord app = mLruProcesses.get(i);
10111                if (!allUsers && app.userId != userId) {
10112                    continue;
10113                }
10114                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10115                    // This one's in trouble, so we'll generate a report for it
10116                    // crashes are higher priority (in case there's a crash *and* an anr)
10117                    ActivityManager.ProcessErrorStateInfo report = null;
10118                    if (app.crashing) {
10119                        report = app.crashingReport;
10120                    } else if (app.notResponding) {
10121                        report = app.notRespondingReport;
10122                    }
10123
10124                    if (report != null) {
10125                        if (errList == null) {
10126                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10127                        }
10128                        errList.add(report);
10129                    } else {
10130                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10131                                " crashing = " + app.crashing +
10132                                " notResponding = " + app.notResponding);
10133                    }
10134                }
10135            }
10136        }
10137
10138        return errList;
10139    }
10140
10141    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10142        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10143            if (currApp != null) {
10144                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10145            }
10146            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10147        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10148            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10149        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10150            if (currApp != null) {
10151                currApp.lru = 0;
10152            }
10153            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10154        } else if (adj >= ProcessList.SERVICE_ADJ) {
10155            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10156        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10157            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10158        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10159            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10160        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10161            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10162        } else {
10163            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10164        }
10165    }
10166
10167    private void fillInProcMemInfo(ProcessRecord app,
10168            ActivityManager.RunningAppProcessInfo outInfo) {
10169        outInfo.pid = app.pid;
10170        outInfo.uid = app.info.uid;
10171        if (mHeavyWeightProcess == app) {
10172            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10173        }
10174        if (app.persistent) {
10175            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10176        }
10177        if (app.activities.size() > 0) {
10178            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10179        }
10180        outInfo.lastTrimLevel = app.trimMemoryLevel;
10181        int adj = app.curAdj;
10182        outInfo.importance = oomAdjToImportance(adj, outInfo);
10183        outInfo.importanceReasonCode = app.adjTypeCode;
10184    }
10185
10186    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10187        enforceNotIsolatedCaller("getRunningAppProcesses");
10188        // Lazy instantiation of list
10189        List<ActivityManager.RunningAppProcessInfo> runList = null;
10190        final boolean allUsers = ActivityManager.checkUidPermission(
10191                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10192                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10193        int userId = UserHandle.getUserId(Binder.getCallingUid());
10194        synchronized (this) {
10195            // Iterate across all processes
10196            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10197                ProcessRecord app = mLruProcesses.get(i);
10198                if (!allUsers && app.userId != userId) {
10199                    continue;
10200                }
10201                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10202                    // Generate process state info for running application
10203                    ActivityManager.RunningAppProcessInfo currApp =
10204                        new ActivityManager.RunningAppProcessInfo(app.processName,
10205                                app.pid, app.getPackageList());
10206                    fillInProcMemInfo(app, currApp);
10207                    if (app.adjSource instanceof ProcessRecord) {
10208                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10209                        currApp.importanceReasonImportance = oomAdjToImportance(
10210                                app.adjSourceOom, null);
10211                    } else if (app.adjSource instanceof ActivityRecord) {
10212                        ActivityRecord r = (ActivityRecord)app.adjSource;
10213                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10214                    }
10215                    if (app.adjTarget instanceof ComponentName) {
10216                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10217                    }
10218                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10219                    //        + " lru=" + currApp.lru);
10220                    if (runList == null) {
10221                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10222                    }
10223                    runList.add(currApp);
10224                }
10225            }
10226        }
10227        return runList;
10228    }
10229
10230    public List<ApplicationInfo> getRunningExternalApplications() {
10231        enforceNotIsolatedCaller("getRunningExternalApplications");
10232        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10233        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10234        if (runningApps != null && runningApps.size() > 0) {
10235            Set<String> extList = new HashSet<String>();
10236            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10237                if (app.pkgList != null) {
10238                    for (String pkg : app.pkgList) {
10239                        extList.add(pkg);
10240                    }
10241                }
10242            }
10243            IPackageManager pm = AppGlobals.getPackageManager();
10244            for (String pkg : extList) {
10245                try {
10246                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10247                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10248                        retList.add(info);
10249                    }
10250                } catch (RemoteException e) {
10251                }
10252            }
10253        }
10254        return retList;
10255    }
10256
10257    @Override
10258    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10259        enforceNotIsolatedCaller("getMyMemoryState");
10260        synchronized (this) {
10261            ProcessRecord proc;
10262            synchronized (mPidsSelfLocked) {
10263                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10264            }
10265            fillInProcMemInfo(proc, outInfo);
10266        }
10267    }
10268
10269    @Override
10270    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10271        if (checkCallingPermission(android.Manifest.permission.DUMP)
10272                != PackageManager.PERMISSION_GRANTED) {
10273            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10274                    + Binder.getCallingPid()
10275                    + ", uid=" + Binder.getCallingUid()
10276                    + " without permission "
10277                    + android.Manifest.permission.DUMP);
10278            return;
10279        }
10280
10281        boolean dumpAll = false;
10282        boolean dumpClient = false;
10283        String dumpPackage = null;
10284
10285        int opti = 0;
10286        while (opti < args.length) {
10287            String opt = args[opti];
10288            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10289                break;
10290            }
10291            opti++;
10292            if ("-a".equals(opt)) {
10293                dumpAll = true;
10294            } else if ("-c".equals(opt)) {
10295                dumpClient = true;
10296            } else if ("-h".equals(opt)) {
10297                pw.println("Activity manager dump options:");
10298                pw.println("  [-a] [-c] [-h] [cmd] ...");
10299                pw.println("  cmd may be one of:");
10300                pw.println("    a[ctivities]: activity stack state");
10301                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10302                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10303                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10304                pw.println("    o[om]: out of memory management");
10305                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10306                pw.println("    provider [COMP_SPEC]: provider client-side state");
10307                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10308                pw.println("    service [COMP_SPEC]: service client-side state");
10309                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10310                pw.println("    all: dump all activities");
10311                pw.println("    top: dump the top activity");
10312                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10313                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10314                pw.println("    a partial substring in a component name, a");
10315                pw.println("    hex object identifier.");
10316                pw.println("  -a: include all available server state.");
10317                pw.println("  -c: include client state.");
10318                return;
10319            } else {
10320                pw.println("Unknown argument: " + opt + "; use -h for help");
10321            }
10322        }
10323
10324        long origId = Binder.clearCallingIdentity();
10325        boolean more = false;
10326        // Is the caller requesting to dump a particular piece of data?
10327        if (opti < args.length) {
10328            String cmd = args[opti];
10329            opti++;
10330            if ("activities".equals(cmd) || "a".equals(cmd)) {
10331                synchronized (this) {
10332                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10333                }
10334            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10335                String[] newArgs;
10336                String name;
10337                if (opti >= args.length) {
10338                    name = null;
10339                    newArgs = EMPTY_STRING_ARRAY;
10340                } else {
10341                    name = args[opti];
10342                    opti++;
10343                    newArgs = new String[args.length - opti];
10344                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10345                            args.length - opti);
10346                }
10347                synchronized (this) {
10348                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10349                }
10350            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10351                String[] newArgs;
10352                String name;
10353                if (opti >= args.length) {
10354                    name = null;
10355                    newArgs = EMPTY_STRING_ARRAY;
10356                } else {
10357                    name = args[opti];
10358                    opti++;
10359                    newArgs = new String[args.length - opti];
10360                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10361                            args.length - opti);
10362                }
10363                synchronized (this) {
10364                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10365                }
10366            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10367                String[] newArgs;
10368                String name;
10369                if (opti >= args.length) {
10370                    name = null;
10371                    newArgs = EMPTY_STRING_ARRAY;
10372                } else {
10373                    name = args[opti];
10374                    opti++;
10375                    newArgs = new String[args.length - opti];
10376                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10377                            args.length - opti);
10378                }
10379                synchronized (this) {
10380                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10381                }
10382            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10383                synchronized (this) {
10384                    dumpOomLocked(fd, pw, args, opti, true);
10385                }
10386            } else if ("provider".equals(cmd)) {
10387                String[] newArgs;
10388                String name;
10389                if (opti >= args.length) {
10390                    name = null;
10391                    newArgs = EMPTY_STRING_ARRAY;
10392                } else {
10393                    name = args[opti];
10394                    opti++;
10395                    newArgs = new String[args.length - opti];
10396                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10397                }
10398                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10399                    pw.println("No providers match: " + name);
10400                    pw.println("Use -h for help.");
10401                }
10402            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10403                synchronized (this) {
10404                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10405                }
10406            } else if ("service".equals(cmd)) {
10407                String[] newArgs;
10408                String name;
10409                if (opti >= args.length) {
10410                    name = null;
10411                    newArgs = EMPTY_STRING_ARRAY;
10412                } else {
10413                    name = args[opti];
10414                    opti++;
10415                    newArgs = new String[args.length - opti];
10416                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10417                            args.length - opti);
10418                }
10419                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10420                    pw.println("No services match: " + name);
10421                    pw.println("Use -h for help.");
10422                }
10423            } else if ("package".equals(cmd)) {
10424                String[] newArgs;
10425                if (opti >= args.length) {
10426                    pw.println("package: no package name specified");
10427                    pw.println("Use -h for help.");
10428                } else {
10429                    dumpPackage = args[opti];
10430                    opti++;
10431                    newArgs = new String[args.length - opti];
10432                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10433                            args.length - opti);
10434                    args = newArgs;
10435                    opti = 0;
10436                    more = true;
10437                }
10438            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10439                synchronized (this) {
10440                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10441                }
10442            } else {
10443                // Dumping a single activity?
10444                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10445                    pw.println("Bad activity command, or no activities match: " + cmd);
10446                    pw.println("Use -h for help.");
10447                }
10448            }
10449            if (!more) {
10450                Binder.restoreCallingIdentity(origId);
10451                return;
10452            }
10453        }
10454
10455        // No piece of data specified, dump everything.
10456        synchronized (this) {
10457            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10458            pw.println();
10459            if (dumpAll) {
10460                pw.println("-------------------------------------------------------------------------------");
10461            }
10462            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10463            pw.println();
10464            if (dumpAll) {
10465                pw.println("-------------------------------------------------------------------------------");
10466            }
10467            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10468            pw.println();
10469            if (dumpAll) {
10470                pw.println("-------------------------------------------------------------------------------");
10471            }
10472            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10473            pw.println();
10474            if (dumpAll) {
10475                pw.println("-------------------------------------------------------------------------------");
10476            }
10477            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10478            pw.println();
10479            if (dumpAll) {
10480                pw.println("-------------------------------------------------------------------------------");
10481            }
10482            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10483        }
10484        Binder.restoreCallingIdentity(origId);
10485    }
10486
10487    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10488            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10489        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10490
10491        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10492                dumpPackage);
10493        boolean needSep = printedAnything;
10494
10495        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10496                dumpPackage, needSep, "  mFocusedActivity: ");
10497        if (printed) {
10498            printedAnything = true;
10499            needSep = false;
10500        }
10501
10502        if (dumpPackage == null) {
10503            if (needSep) {
10504                pw.println();
10505            }
10506            needSep = true;
10507            printedAnything = true;
10508            mStackSupervisor.dump(pw, "  ");
10509        }
10510
10511        if (mRecentTasks.size() > 0) {
10512            boolean printedHeader = false;
10513
10514            final int N = mRecentTasks.size();
10515            for (int i=0; i<N; i++) {
10516                TaskRecord tr = mRecentTasks.get(i);
10517                if (dumpPackage != null) {
10518                    if (tr.realActivity == null ||
10519                            !dumpPackage.equals(tr.realActivity)) {
10520                        continue;
10521                    }
10522                }
10523                if (!printedHeader) {
10524                    if (needSep) {
10525                        pw.println();
10526                    }
10527                    pw.println("  Recent tasks:");
10528                    printedHeader = true;
10529                    printedAnything = true;
10530                }
10531                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10532                        pw.println(tr);
10533                if (dumpAll) {
10534                    mRecentTasks.get(i).dump(pw, "    ");
10535                }
10536            }
10537        }
10538
10539        if (!printedAnything) {
10540            pw.println("  (nothing)");
10541        }
10542    }
10543
10544    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10545            int opti, boolean dumpAll, String dumpPackage) {
10546        boolean needSep = false;
10547        boolean printedAnything = false;
10548        int numPers = 0;
10549
10550        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10551
10552        if (dumpAll) {
10553            final int NP = mProcessNames.getMap().size();
10554            for (int ip=0; ip<NP; ip++) {
10555                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10556                final int NA = procs.size();
10557                for (int ia=0; ia<NA; ia++) {
10558                    ProcessRecord r = procs.valueAt(ia);
10559                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10560                        continue;
10561                    }
10562                    if (!needSep) {
10563                        pw.println("  All known processes:");
10564                        needSep = true;
10565                        printedAnything = true;
10566                    }
10567                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10568                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10569                        pw.print(" "); pw.println(r);
10570                    r.dump(pw, "    ");
10571                    if (r.persistent) {
10572                        numPers++;
10573                    }
10574                }
10575            }
10576        }
10577
10578        if (mIsolatedProcesses.size() > 0) {
10579            boolean printed = false;
10580            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10581                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10582                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10583                    continue;
10584                }
10585                if (!printed) {
10586                    if (needSep) {
10587                        pw.println();
10588                    }
10589                    pw.println("  Isolated process list (sorted by uid):");
10590                    printedAnything = true;
10591                    printed = true;
10592                    needSep = true;
10593                }
10594                pw.println(String.format("%sIsolated #%2d: %s",
10595                        "    ", i, r.toString()));
10596            }
10597        }
10598
10599        if (mLruProcesses.size() > 0) {
10600            if (needSep) {
10601                pw.println();
10602            }
10603            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10604                    pw.print(" total, non-act at ");
10605                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10606                    pw.print(", non-svc at ");
10607                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10608                    pw.println("):");
10609            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10610            needSep = true;
10611            printedAnything = true;
10612        }
10613
10614        if (dumpAll || dumpPackage != null) {
10615            synchronized (mPidsSelfLocked) {
10616                boolean printed = false;
10617                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10618                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10619                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10620                        continue;
10621                    }
10622                    if (!printed) {
10623                        if (needSep) pw.println();
10624                        needSep = true;
10625                        pw.println("  PID mappings:");
10626                        printed = true;
10627                        printedAnything = true;
10628                    }
10629                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10630                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10631                }
10632            }
10633        }
10634
10635        if (mForegroundProcesses.size() > 0) {
10636            synchronized (mPidsSelfLocked) {
10637                boolean printed = false;
10638                for (int i=0; i<mForegroundProcesses.size(); i++) {
10639                    ProcessRecord r = mPidsSelfLocked.get(
10640                            mForegroundProcesses.valueAt(i).pid);
10641                    if (dumpPackage != null && (r == null
10642                            || !r.pkgList.containsKey(dumpPackage))) {
10643                        continue;
10644                    }
10645                    if (!printed) {
10646                        if (needSep) pw.println();
10647                        needSep = true;
10648                        pw.println("  Foreground Processes:");
10649                        printed = true;
10650                        printedAnything = true;
10651                    }
10652                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10653                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10654                }
10655            }
10656        }
10657
10658        if (mPersistentStartingProcesses.size() > 0) {
10659            if (needSep) pw.println();
10660            needSep = true;
10661            printedAnything = true;
10662            pw.println("  Persisent processes that are starting:");
10663            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10664                    "Starting Norm", "Restarting PERS", dumpPackage);
10665        }
10666
10667        if (mRemovedProcesses.size() > 0) {
10668            if (needSep) pw.println();
10669            needSep = true;
10670            printedAnything = true;
10671            pw.println("  Processes that are being removed:");
10672            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10673                    "Removed Norm", "Removed PERS", dumpPackage);
10674        }
10675
10676        if (mProcessesOnHold.size() > 0) {
10677            if (needSep) pw.println();
10678            needSep = true;
10679            printedAnything = true;
10680            pw.println("  Processes that are on old until the system is ready:");
10681            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10682                    "OnHold Norm", "OnHold PERS", dumpPackage);
10683        }
10684
10685        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10686
10687        if (mProcessCrashTimes.getMap().size() > 0) {
10688            boolean printed = false;
10689            long now = SystemClock.uptimeMillis();
10690            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10691            final int NP = pmap.size();
10692            for (int ip=0; ip<NP; ip++) {
10693                String pname = pmap.keyAt(ip);
10694                SparseArray<Long> uids = pmap.valueAt(ip);
10695                final int N = uids.size();
10696                for (int i=0; i<N; i++) {
10697                    int puid = uids.keyAt(i);
10698                    ProcessRecord r = mProcessNames.get(pname, puid);
10699                    if (dumpPackage != null && (r == null
10700                            || !r.pkgList.containsKey(dumpPackage))) {
10701                        continue;
10702                    }
10703                    if (!printed) {
10704                        if (needSep) pw.println();
10705                        needSep = true;
10706                        pw.println("  Time since processes crashed:");
10707                        printed = true;
10708                        printedAnything = true;
10709                    }
10710                    pw.print("    Process "); pw.print(pname);
10711                            pw.print(" uid "); pw.print(puid);
10712                            pw.print(": last crashed ");
10713                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10714                            pw.println(" ago");
10715                }
10716            }
10717        }
10718
10719        if (mBadProcesses.getMap().size() > 0) {
10720            boolean printed = false;
10721            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10722            final int NP = pmap.size();
10723            for (int ip=0; ip<NP; ip++) {
10724                String pname = pmap.keyAt(ip);
10725                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10726                final int N = uids.size();
10727                for (int i=0; i<N; i++) {
10728                    int puid = uids.keyAt(i);
10729                    ProcessRecord r = mProcessNames.get(pname, puid);
10730                    if (dumpPackage != null && (r == null
10731                            || !r.pkgList.containsKey(dumpPackage))) {
10732                        continue;
10733                    }
10734                    if (!printed) {
10735                        if (needSep) pw.println();
10736                        needSep = true;
10737                        pw.println("  Bad processes:");
10738                        printedAnything = true;
10739                    }
10740                    BadProcessInfo info = uids.valueAt(i);
10741                    pw.print("    Bad process "); pw.print(pname);
10742                            pw.print(" uid "); pw.print(puid);
10743                            pw.print(": crashed at time "); pw.println(info.time);
10744                    if (info.shortMsg != null) {
10745                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10746                    }
10747                    if (info.longMsg != null) {
10748                        pw.print("      Long msg: "); pw.println(info.longMsg);
10749                    }
10750                    if (info.stack != null) {
10751                        pw.println("      Stack:");
10752                        int lastPos = 0;
10753                        for (int pos=0; pos<info.stack.length(); pos++) {
10754                            if (info.stack.charAt(pos) == '\n') {
10755                                pw.print("        ");
10756                                pw.write(info.stack, lastPos, pos-lastPos);
10757                                pw.println();
10758                                lastPos = pos+1;
10759                            }
10760                        }
10761                        if (lastPos < info.stack.length()) {
10762                            pw.print("        ");
10763                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10764                            pw.println();
10765                        }
10766                    }
10767                }
10768            }
10769        }
10770
10771        if (dumpPackage == null) {
10772            pw.println();
10773            needSep = false;
10774            pw.println("  mStartedUsers:");
10775            for (int i=0; i<mStartedUsers.size(); i++) {
10776                UserStartedState uss = mStartedUsers.valueAt(i);
10777                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10778                        pw.print(": "); uss.dump("", pw);
10779            }
10780            pw.print("  mStartedUserArray: [");
10781            for (int i=0; i<mStartedUserArray.length; i++) {
10782                if (i > 0) pw.print(", ");
10783                pw.print(mStartedUserArray[i]);
10784            }
10785            pw.println("]");
10786            pw.print("  mUserLru: [");
10787            for (int i=0; i<mUserLru.size(); i++) {
10788                if (i > 0) pw.print(", ");
10789                pw.print(mUserLru.get(i));
10790            }
10791            pw.println("]");
10792            if (dumpAll) {
10793                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10794            }
10795        }
10796        if (mHomeProcess != null && (dumpPackage == null
10797                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10798            if (needSep) {
10799                pw.println();
10800                needSep = false;
10801            }
10802            pw.println("  mHomeProcess: " + mHomeProcess);
10803        }
10804        if (mPreviousProcess != null && (dumpPackage == null
10805                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10806            if (needSep) {
10807                pw.println();
10808                needSep = false;
10809            }
10810            pw.println("  mPreviousProcess: " + mPreviousProcess);
10811        }
10812        if (dumpAll) {
10813            StringBuilder sb = new StringBuilder(128);
10814            sb.append("  mPreviousProcessVisibleTime: ");
10815            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10816            pw.println(sb);
10817        }
10818        if (mHeavyWeightProcess != null && (dumpPackage == null
10819                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10820            if (needSep) {
10821                pw.println();
10822                needSep = false;
10823            }
10824            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10825        }
10826        if (dumpPackage == null) {
10827            pw.println("  mConfiguration: " + mConfiguration);
10828        }
10829        if (dumpAll) {
10830            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10831            if (mCompatModePackages.getPackages().size() > 0) {
10832                boolean printed = false;
10833                for (Map.Entry<String, Integer> entry
10834                        : mCompatModePackages.getPackages().entrySet()) {
10835                    String pkg = entry.getKey();
10836                    int mode = entry.getValue();
10837                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10838                        continue;
10839                    }
10840                    if (!printed) {
10841                        pw.println("  mScreenCompatPackages:");
10842                        printed = true;
10843                    }
10844                    pw.print("    "); pw.print(pkg); pw.print(": ");
10845                            pw.print(mode); pw.println();
10846                }
10847            }
10848        }
10849        if (dumpPackage == null) {
10850            if (mSleeping || mWentToSleep || mLockScreenShown) {
10851                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10852                        + " mLockScreenShown " + mLockScreenShown);
10853            }
10854            if (mShuttingDown) {
10855                pw.println("  mShuttingDown=" + mShuttingDown);
10856            }
10857        }
10858        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10859                || mOrigWaitForDebugger) {
10860            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10861                    || dumpPackage.equals(mOrigDebugApp)) {
10862                if (needSep) {
10863                    pw.println();
10864                    needSep = false;
10865                }
10866                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10867                        + " mDebugTransient=" + mDebugTransient
10868                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10869            }
10870        }
10871        if (mOpenGlTraceApp != null) {
10872            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10873                if (needSep) {
10874                    pw.println();
10875                    needSep = false;
10876                }
10877                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10878            }
10879        }
10880        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10881                || mProfileFd != null) {
10882            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10883                if (needSep) {
10884                    pw.println();
10885                    needSep = false;
10886                }
10887                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10888                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10889                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10890                        + mAutoStopProfiler);
10891            }
10892        }
10893        if (dumpPackage == null) {
10894            if (mAlwaysFinishActivities || mController != null) {
10895                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10896                        + " mController=" + mController);
10897            }
10898            if (dumpAll) {
10899                pw.println("  Total persistent processes: " + numPers);
10900                pw.println("  mProcessesReady=" + mProcessesReady
10901                        + " mSystemReady=" + mSystemReady);
10902                pw.println("  mBooting=" + mBooting
10903                        + " mBooted=" + mBooted
10904                        + " mFactoryTest=" + mFactoryTest);
10905                pw.print("  mLastPowerCheckRealtime=");
10906                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10907                        pw.println("");
10908                pw.print("  mLastPowerCheckUptime=");
10909                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10910                        pw.println("");
10911                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10912                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10913                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10914                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10915                        + " (" + mLruProcesses.size() + " total)"
10916                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10917                        + " mNumServiceProcs=" + mNumServiceProcs
10918                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10919                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10920                        + " mLastMemoryLevel" + mLastMemoryLevel
10921                        + " mLastNumProcesses" + mLastNumProcesses);
10922                long now = SystemClock.uptimeMillis();
10923                pw.print("  mLastIdleTime=");
10924                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10925                        pw.print(" mLowRamSinceLastIdle=");
10926                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10927                        pw.println();
10928            }
10929        }
10930
10931        if (!printedAnything) {
10932            pw.println("  (nothing)");
10933        }
10934    }
10935
10936    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10937            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10938        if (mProcessesToGc.size() > 0) {
10939            boolean printed = false;
10940            long now = SystemClock.uptimeMillis();
10941            for (int i=0; i<mProcessesToGc.size(); i++) {
10942                ProcessRecord proc = mProcessesToGc.get(i);
10943                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10944                    continue;
10945                }
10946                if (!printed) {
10947                    if (needSep) pw.println();
10948                    needSep = true;
10949                    pw.println("  Processes that are waiting to GC:");
10950                    printed = true;
10951                }
10952                pw.print("    Process "); pw.println(proc);
10953                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
10954                        pw.print(", last gced=");
10955                        pw.print(now-proc.lastRequestedGc);
10956                        pw.print(" ms ago, last lowMem=");
10957                        pw.print(now-proc.lastLowMemory);
10958                        pw.println(" ms ago");
10959
10960            }
10961        }
10962        return needSep;
10963    }
10964
10965    void printOomLevel(PrintWriter pw, String name, int adj) {
10966        pw.print("    ");
10967        if (adj >= 0) {
10968            pw.print(' ');
10969            if (adj < 10) pw.print(' ');
10970        } else {
10971            if (adj > -10) pw.print(' ');
10972        }
10973        pw.print(adj);
10974        pw.print(": ");
10975        pw.print(name);
10976        pw.print(" (");
10977        pw.print(mProcessList.getMemLevel(adj)/1024);
10978        pw.println(" kB)");
10979    }
10980
10981    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10982            int opti, boolean dumpAll) {
10983        boolean needSep = false;
10984
10985        if (mLruProcesses.size() > 0) {
10986            if (needSep) pw.println();
10987            needSep = true;
10988            pw.println("  OOM levels:");
10989            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
10990            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
10991            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
10992            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
10993            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
10994            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
10995            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
10996            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
10997            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
10998            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
10999            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11000            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11001            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11002
11003            if (needSep) pw.println();
11004            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11005                    pw.print(" total, non-act at ");
11006                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11007                    pw.print(", non-svc at ");
11008                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11009                    pw.println("):");
11010            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11011            needSep = true;
11012        }
11013
11014        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11015
11016        pw.println();
11017        pw.println("  mHomeProcess: " + mHomeProcess);
11018        pw.println("  mPreviousProcess: " + mPreviousProcess);
11019        if (mHeavyWeightProcess != null) {
11020            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11021        }
11022
11023        return true;
11024    }
11025
11026    /**
11027     * There are three ways to call this:
11028     *  - no provider specified: dump all the providers
11029     *  - a flattened component name that matched an existing provider was specified as the
11030     *    first arg: dump that one provider
11031     *  - the first arg isn't the flattened component name of an existing provider:
11032     *    dump all providers whose component contains the first arg as a substring
11033     */
11034    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11035            int opti, boolean dumpAll) {
11036        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11037    }
11038
11039    static class ItemMatcher {
11040        ArrayList<ComponentName> components;
11041        ArrayList<String> strings;
11042        ArrayList<Integer> objects;
11043        boolean all;
11044
11045        ItemMatcher() {
11046            all = true;
11047        }
11048
11049        void build(String name) {
11050            ComponentName componentName = ComponentName.unflattenFromString(name);
11051            if (componentName != null) {
11052                if (components == null) {
11053                    components = new ArrayList<ComponentName>();
11054                }
11055                components.add(componentName);
11056                all = false;
11057            } else {
11058                int objectId = 0;
11059                // Not a '/' separated full component name; maybe an object ID?
11060                try {
11061                    objectId = Integer.parseInt(name, 16);
11062                    if (objects == null) {
11063                        objects = new ArrayList<Integer>();
11064                    }
11065                    objects.add(objectId);
11066                    all = false;
11067                } catch (RuntimeException e) {
11068                    // Not an integer; just do string match.
11069                    if (strings == null) {
11070                        strings = new ArrayList<String>();
11071                    }
11072                    strings.add(name);
11073                    all = false;
11074                }
11075            }
11076        }
11077
11078        int build(String[] args, int opti) {
11079            for (; opti<args.length; opti++) {
11080                String name = args[opti];
11081                if ("--".equals(name)) {
11082                    return opti+1;
11083                }
11084                build(name);
11085            }
11086            return opti;
11087        }
11088
11089        boolean match(Object object, ComponentName comp) {
11090            if (all) {
11091                return true;
11092            }
11093            if (components != null) {
11094                for (int i=0; i<components.size(); i++) {
11095                    if (components.get(i).equals(comp)) {
11096                        return true;
11097                    }
11098                }
11099            }
11100            if (objects != null) {
11101                for (int i=0; i<objects.size(); i++) {
11102                    if (System.identityHashCode(object) == objects.get(i)) {
11103                        return true;
11104                    }
11105                }
11106            }
11107            if (strings != null) {
11108                String flat = comp.flattenToString();
11109                for (int i=0; i<strings.size(); i++) {
11110                    if (flat.contains(strings.get(i))) {
11111                        return true;
11112                    }
11113                }
11114            }
11115            return false;
11116        }
11117    }
11118
11119    /**
11120     * There are three things that cmd can be:
11121     *  - a flattened component name that matches an existing activity
11122     *  - the cmd arg isn't the flattened component name of an existing activity:
11123     *    dump all activity whose component contains the cmd as a substring
11124     *  - A hex number of the ActivityRecord object instance.
11125     */
11126    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11127            int opti, boolean dumpAll) {
11128        ArrayList<ActivityRecord> activities;
11129
11130        synchronized (this) {
11131            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11132        }
11133
11134        if (activities.size() <= 0) {
11135            return false;
11136        }
11137
11138        String[] newArgs = new String[args.length - opti];
11139        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11140
11141        TaskRecord lastTask = null;
11142        boolean needSep = false;
11143        for (int i=activities.size()-1; i>=0; i--) {
11144            ActivityRecord r = activities.get(i);
11145            if (needSep) {
11146                pw.println();
11147            }
11148            needSep = true;
11149            synchronized (this) {
11150                if (lastTask != r.task) {
11151                    lastTask = r.task;
11152                    pw.print("TASK "); pw.print(lastTask.affinity);
11153                            pw.print(" id="); pw.println(lastTask.taskId);
11154                    if (dumpAll) {
11155                        lastTask.dump(pw, "  ");
11156                    }
11157                }
11158            }
11159            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11160        }
11161        return true;
11162    }
11163
11164    /**
11165     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11166     * there is a thread associated with the activity.
11167     */
11168    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11169            final ActivityRecord r, String[] args, boolean dumpAll) {
11170        String innerPrefix = prefix + "  ";
11171        synchronized (this) {
11172            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11173                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11174                    pw.print(" pid=");
11175                    if (r.app != null) pw.println(r.app.pid);
11176                    else pw.println("(not running)");
11177            if (dumpAll) {
11178                r.dump(pw, innerPrefix);
11179            }
11180        }
11181        if (r.app != null && r.app.thread != null) {
11182            // flush anything that is already in the PrintWriter since the thread is going
11183            // to write to the file descriptor directly
11184            pw.flush();
11185            try {
11186                TransferPipe tp = new TransferPipe();
11187                try {
11188                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11189                            r.appToken, innerPrefix, args);
11190                    tp.go(fd);
11191                } finally {
11192                    tp.kill();
11193                }
11194            } catch (IOException e) {
11195                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11196            } catch (RemoteException e) {
11197                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11198            }
11199        }
11200    }
11201
11202    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11203            int opti, boolean dumpAll, String dumpPackage) {
11204        boolean needSep = false;
11205        boolean onlyHistory = false;
11206        boolean printedAnything = false;
11207
11208        if ("history".equals(dumpPackage)) {
11209            if (opti < args.length && "-s".equals(args[opti])) {
11210                dumpAll = false;
11211            }
11212            onlyHistory = true;
11213            dumpPackage = null;
11214        }
11215
11216        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11217        if (!onlyHistory && dumpAll) {
11218            if (mRegisteredReceivers.size() > 0) {
11219                boolean printed = false;
11220                Iterator it = mRegisteredReceivers.values().iterator();
11221                while (it.hasNext()) {
11222                    ReceiverList r = (ReceiverList)it.next();
11223                    if (dumpPackage != null && (r.app == null ||
11224                            !dumpPackage.equals(r.app.info.packageName))) {
11225                        continue;
11226                    }
11227                    if (!printed) {
11228                        pw.println("  Registered Receivers:");
11229                        needSep = true;
11230                        printed = true;
11231                        printedAnything = true;
11232                    }
11233                    pw.print("  * "); pw.println(r);
11234                    r.dump(pw, "    ");
11235                }
11236            }
11237
11238            if (mReceiverResolver.dump(pw, needSep ?
11239                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11240                    "    ", dumpPackage, false)) {
11241                needSep = true;
11242                printedAnything = true;
11243            }
11244        }
11245
11246        for (BroadcastQueue q : mBroadcastQueues) {
11247            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11248            printedAnything |= needSep;
11249        }
11250
11251        needSep = true;
11252
11253        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11254            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11255                if (needSep) {
11256                    pw.println();
11257                }
11258                needSep = true;
11259                printedAnything = true;
11260                pw.print("  Sticky broadcasts for user ");
11261                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11262                StringBuilder sb = new StringBuilder(128);
11263                for (Map.Entry<String, ArrayList<Intent>> ent
11264                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11265                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11266                    if (dumpAll) {
11267                        pw.println(":");
11268                        ArrayList<Intent> intents = ent.getValue();
11269                        final int N = intents.size();
11270                        for (int i=0; i<N; i++) {
11271                            sb.setLength(0);
11272                            sb.append("    Intent: ");
11273                            intents.get(i).toShortString(sb, false, true, false, false);
11274                            pw.println(sb.toString());
11275                            Bundle bundle = intents.get(i).getExtras();
11276                            if (bundle != null) {
11277                                pw.print("      ");
11278                                pw.println(bundle.toString());
11279                            }
11280                        }
11281                    } else {
11282                        pw.println("");
11283                    }
11284                }
11285            }
11286        }
11287
11288        if (!onlyHistory && dumpAll) {
11289            pw.println();
11290            for (BroadcastQueue queue : mBroadcastQueues) {
11291                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11292                        + queue.mBroadcastsScheduled);
11293            }
11294            pw.println("  mHandler:");
11295            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11296            needSep = true;
11297            printedAnything = true;
11298        }
11299
11300        if (!printedAnything) {
11301            pw.println("  (nothing)");
11302        }
11303    }
11304
11305    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11306            int opti, boolean dumpAll, String dumpPackage) {
11307        boolean needSep;
11308        boolean printedAnything = false;
11309
11310        ItemMatcher matcher = new ItemMatcher();
11311        matcher.build(args, opti);
11312
11313        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11314
11315        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11316        printedAnything |= needSep;
11317
11318        if (mLaunchingProviders.size() > 0) {
11319            boolean printed = false;
11320            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11321                ContentProviderRecord r = mLaunchingProviders.get(i);
11322                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11323                    continue;
11324                }
11325                if (!printed) {
11326                    if (needSep) pw.println();
11327                    needSep = true;
11328                    pw.println("  Launching content providers:");
11329                    printed = true;
11330                    printedAnything = true;
11331                }
11332                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11333                        pw.println(r);
11334            }
11335        }
11336
11337        if (mGrantedUriPermissions.size() > 0) {
11338            boolean printed = false;
11339            int dumpUid = -2;
11340            if (dumpPackage != null) {
11341                try {
11342                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11343                } catch (NameNotFoundException e) {
11344                    dumpUid = -1;
11345                }
11346            }
11347            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11348                int uid = mGrantedUriPermissions.keyAt(i);
11349                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11350                    continue;
11351                }
11352                ArrayMap<Uri, UriPermission> perms
11353                        = mGrantedUriPermissions.valueAt(i);
11354                if (!printed) {
11355                    if (needSep) pw.println();
11356                    needSep = true;
11357                    pw.println("  Granted Uri Permissions:");
11358                    printed = true;
11359                    printedAnything = true;
11360                }
11361                pw.print("  * UID "); pw.print(uid);
11362                        pw.println(" holds:");
11363                for (UriPermission perm : perms.values()) {
11364                    pw.print("    "); pw.println(perm);
11365                    if (dumpAll) {
11366                        perm.dump(pw, "      ");
11367                    }
11368                }
11369            }
11370        }
11371
11372        if (!printedAnything) {
11373            pw.println("  (nothing)");
11374        }
11375    }
11376
11377    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11378            int opti, boolean dumpAll, String dumpPackage) {
11379        boolean printed = false;
11380
11381        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11382
11383        if (mIntentSenderRecords.size() > 0) {
11384            Iterator<WeakReference<PendingIntentRecord>> it
11385                    = mIntentSenderRecords.values().iterator();
11386            while (it.hasNext()) {
11387                WeakReference<PendingIntentRecord> ref = it.next();
11388                PendingIntentRecord rec = ref != null ? ref.get(): null;
11389                if (dumpPackage != null && (rec == null
11390                        || !dumpPackage.equals(rec.key.packageName))) {
11391                    continue;
11392                }
11393                printed = true;
11394                if (rec != null) {
11395                    pw.print("  * "); pw.println(rec);
11396                    if (dumpAll) {
11397                        rec.dump(pw, "    ");
11398                    }
11399                } else {
11400                    pw.print("  * "); pw.println(ref);
11401                }
11402            }
11403        }
11404
11405        if (!printed) {
11406            pw.println("  (nothing)");
11407        }
11408    }
11409
11410    private static final int dumpProcessList(PrintWriter pw,
11411            ActivityManagerService service, List list,
11412            String prefix, String normalLabel, String persistentLabel,
11413            String dumpPackage) {
11414        int numPers = 0;
11415        final int N = list.size()-1;
11416        for (int i=N; i>=0; i--) {
11417            ProcessRecord r = (ProcessRecord)list.get(i);
11418            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11419                continue;
11420            }
11421            pw.println(String.format("%s%s #%2d: %s",
11422                    prefix, (r.persistent ? persistentLabel : normalLabel),
11423                    i, r.toString()));
11424            if (r.persistent) {
11425                numPers++;
11426            }
11427        }
11428        return numPers;
11429    }
11430
11431    private static final boolean dumpProcessOomList(PrintWriter pw,
11432            ActivityManagerService service, List<ProcessRecord> origList,
11433            String prefix, String normalLabel, String persistentLabel,
11434            boolean inclDetails, String dumpPackage) {
11435
11436        ArrayList<Pair<ProcessRecord, Integer>> list
11437                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11438        for (int i=0; i<origList.size(); i++) {
11439            ProcessRecord r = origList.get(i);
11440            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11441                continue;
11442            }
11443            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11444        }
11445
11446        if (list.size() <= 0) {
11447            return false;
11448        }
11449
11450        Comparator<Pair<ProcessRecord, Integer>> comparator
11451                = new Comparator<Pair<ProcessRecord, Integer>>() {
11452            @Override
11453            public int compare(Pair<ProcessRecord, Integer> object1,
11454                    Pair<ProcessRecord, Integer> object2) {
11455                if (object1.first.setAdj != object2.first.setAdj) {
11456                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11457                }
11458                if (object1.second.intValue() != object2.second.intValue()) {
11459                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11460                }
11461                return 0;
11462            }
11463        };
11464
11465        Collections.sort(list, comparator);
11466
11467        final long curRealtime = SystemClock.elapsedRealtime();
11468        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11469        final long curUptime = SystemClock.uptimeMillis();
11470        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11471
11472        for (int i=list.size()-1; i>=0; i--) {
11473            ProcessRecord r = list.get(i).first;
11474            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11475            char schedGroup;
11476            switch (r.setSchedGroup) {
11477                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11478                    schedGroup = 'B';
11479                    break;
11480                case Process.THREAD_GROUP_DEFAULT:
11481                    schedGroup = 'F';
11482                    break;
11483                default:
11484                    schedGroup = '?';
11485                    break;
11486            }
11487            char foreground;
11488            if (r.foregroundActivities) {
11489                foreground = 'A';
11490            } else if (r.foregroundServices) {
11491                foreground = 'S';
11492            } else {
11493                foreground = ' ';
11494            }
11495            String procState = ProcessList.makeProcStateString(r.curProcState);
11496            pw.print(prefix);
11497            pw.print(r.persistent ? persistentLabel : normalLabel);
11498            pw.print(" #");
11499            int num = (origList.size()-1)-list.get(i).second;
11500            if (num < 10) pw.print(' ');
11501            pw.print(num);
11502            pw.print(": ");
11503            pw.print(oomAdj);
11504            pw.print(' ');
11505            pw.print(schedGroup);
11506            pw.print('/');
11507            pw.print(foreground);
11508            pw.print('/');
11509            pw.print(procState);
11510            pw.print(" trm:");
11511            if (r.trimMemoryLevel < 10) pw.print(' ');
11512            pw.print(r.trimMemoryLevel);
11513            pw.print(' ');
11514            pw.print(r.toShortString());
11515            pw.print(" (");
11516            pw.print(r.adjType);
11517            pw.println(')');
11518            if (r.adjSource != null || r.adjTarget != null) {
11519                pw.print(prefix);
11520                pw.print("    ");
11521                if (r.adjTarget instanceof ComponentName) {
11522                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11523                } else if (r.adjTarget != null) {
11524                    pw.print(r.adjTarget.toString());
11525                } else {
11526                    pw.print("{null}");
11527                }
11528                pw.print("<=");
11529                if (r.adjSource instanceof ProcessRecord) {
11530                    pw.print("Proc{");
11531                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11532                    pw.println("}");
11533                } else if (r.adjSource != null) {
11534                    pw.println(r.adjSource.toString());
11535                } else {
11536                    pw.println("{null}");
11537                }
11538            }
11539            if (inclDetails) {
11540                pw.print(prefix);
11541                pw.print("    ");
11542                pw.print("oom: max="); pw.print(r.maxAdj);
11543                pw.print(" curRaw="); pw.print(r.curRawAdj);
11544                pw.print(" setRaw="); pw.print(r.setRawAdj);
11545                pw.print(" cur="); pw.print(r.curAdj);
11546                pw.print(" set="); pw.println(r.setAdj);
11547                pw.print(prefix);
11548                pw.print("    ");
11549                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11550                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11551                pw.print(" lastPss="); pw.print(r.lastPss);
11552                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11553                pw.print(prefix);
11554                pw.print("    ");
11555                pw.print("keeping="); pw.print(r.keeping);
11556                pw.print(" cached="); pw.print(r.cached);
11557                pw.print(" empty="); pw.print(r.empty);
11558                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11559
11560                if (!r.keeping) {
11561                    if (r.lastWakeTime != 0) {
11562                        long wtime;
11563                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11564                        synchronized (stats) {
11565                            wtime = stats.getProcessWakeTime(r.info.uid,
11566                                    r.pid, curRealtime);
11567                        }
11568                        long timeUsed = wtime - r.lastWakeTime;
11569                        pw.print(prefix);
11570                        pw.print("    ");
11571                        pw.print("keep awake over ");
11572                        TimeUtils.formatDuration(realtimeSince, pw);
11573                        pw.print(" used ");
11574                        TimeUtils.formatDuration(timeUsed, pw);
11575                        pw.print(" (");
11576                        pw.print((timeUsed*100)/realtimeSince);
11577                        pw.println("%)");
11578                    }
11579                    if (r.lastCpuTime != 0) {
11580                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11581                        pw.print(prefix);
11582                        pw.print("    ");
11583                        pw.print("run cpu over ");
11584                        TimeUtils.formatDuration(uptimeSince, pw);
11585                        pw.print(" used ");
11586                        TimeUtils.formatDuration(timeUsed, pw);
11587                        pw.print(" (");
11588                        pw.print((timeUsed*100)/uptimeSince);
11589                        pw.println("%)");
11590                    }
11591                }
11592            }
11593        }
11594        return true;
11595    }
11596
11597    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11598        ArrayList<ProcessRecord> procs;
11599        synchronized (this) {
11600            if (args != null && args.length > start
11601                    && args[start].charAt(0) != '-') {
11602                procs = new ArrayList<ProcessRecord>();
11603                int pid = -1;
11604                try {
11605                    pid = Integer.parseInt(args[start]);
11606                } catch (NumberFormatException e) {
11607                }
11608                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11609                    ProcessRecord proc = mLruProcesses.get(i);
11610                    if (proc.pid == pid) {
11611                        procs.add(proc);
11612                    } else if (proc.processName.equals(args[start])) {
11613                        procs.add(proc);
11614                    }
11615                }
11616                if (procs.size() <= 0) {
11617                    return null;
11618                }
11619            } else {
11620                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11621            }
11622        }
11623        return procs;
11624    }
11625
11626    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11627            PrintWriter pw, String[] args) {
11628        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11629        if (procs == null) {
11630            pw.println("No process found for: " + args[0]);
11631            return;
11632        }
11633
11634        long uptime = SystemClock.uptimeMillis();
11635        long realtime = SystemClock.elapsedRealtime();
11636        pw.println("Applications Graphics Acceleration Info:");
11637        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11638
11639        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11640            ProcessRecord r = procs.get(i);
11641            if (r.thread != null) {
11642                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11643                pw.flush();
11644                try {
11645                    TransferPipe tp = new TransferPipe();
11646                    try {
11647                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11648                        tp.go(fd);
11649                    } finally {
11650                        tp.kill();
11651                    }
11652                } catch (IOException e) {
11653                    pw.println("Failure while dumping the app: " + r);
11654                    pw.flush();
11655                } catch (RemoteException e) {
11656                    pw.println("Got a RemoteException while dumping the app " + r);
11657                    pw.flush();
11658                }
11659            }
11660        }
11661    }
11662
11663    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11664        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11665        if (procs == null) {
11666            pw.println("No process found for: " + args[0]);
11667            return;
11668        }
11669
11670        pw.println("Applications Database Info:");
11671
11672        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11673            ProcessRecord r = procs.get(i);
11674            if (r.thread != null) {
11675                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11676                pw.flush();
11677                try {
11678                    TransferPipe tp = new TransferPipe();
11679                    try {
11680                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11681                        tp.go(fd);
11682                    } finally {
11683                        tp.kill();
11684                    }
11685                } catch (IOException e) {
11686                    pw.println("Failure while dumping the app: " + r);
11687                    pw.flush();
11688                } catch (RemoteException e) {
11689                    pw.println("Got a RemoteException while dumping the app " + r);
11690                    pw.flush();
11691                }
11692            }
11693        }
11694    }
11695
11696    final static class MemItem {
11697        final boolean isProc;
11698        final String label;
11699        final String shortLabel;
11700        final long pss;
11701        final int id;
11702        final boolean hasActivities;
11703        ArrayList<MemItem> subitems;
11704
11705        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11706                boolean _hasActivities) {
11707            isProc = true;
11708            label = _label;
11709            shortLabel = _shortLabel;
11710            pss = _pss;
11711            id = _id;
11712            hasActivities = _hasActivities;
11713        }
11714
11715        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11716            isProc = false;
11717            label = _label;
11718            shortLabel = _shortLabel;
11719            pss = _pss;
11720            id = _id;
11721            hasActivities = false;
11722        }
11723    }
11724
11725    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11726            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11727        if (sort && !isCompact) {
11728            Collections.sort(items, new Comparator<MemItem>() {
11729                @Override
11730                public int compare(MemItem lhs, MemItem rhs) {
11731                    if (lhs.pss < rhs.pss) {
11732                        return 1;
11733                    } else if (lhs.pss > rhs.pss) {
11734                        return -1;
11735                    }
11736                    return 0;
11737                }
11738            });
11739        }
11740
11741        for (int i=0; i<items.size(); i++) {
11742            MemItem mi = items.get(i);
11743            if (!isCompact) {
11744                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11745            } else if (mi.isProc) {
11746                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11747                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11748                pw.println(mi.hasActivities ? ",a" : ",e");
11749            } else {
11750                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11751                pw.println(mi.pss);
11752            }
11753            if (mi.subitems != null) {
11754                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11755                        true, isCompact);
11756            }
11757        }
11758    }
11759
11760    // These are in KB.
11761    static final long[] DUMP_MEM_BUCKETS = new long[] {
11762        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11763        120*1024, 160*1024, 200*1024,
11764        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11765        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11766    };
11767
11768    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11769            boolean stackLike) {
11770        int start = label.lastIndexOf('.');
11771        if (start >= 0) start++;
11772        else start = 0;
11773        int end = label.length();
11774        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11775            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11776                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11777                out.append(bucket);
11778                out.append(stackLike ? "MB." : "MB ");
11779                out.append(label, start, end);
11780                return;
11781            }
11782        }
11783        out.append(memKB/1024);
11784        out.append(stackLike ? "MB." : "MB ");
11785        out.append(label, start, end);
11786    }
11787
11788    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11789            ProcessList.NATIVE_ADJ,
11790            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11791            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11792            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11793            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11794            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11795    };
11796    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11797            "Native",
11798            "System", "Persistent", "Foreground",
11799            "Visible", "Perceptible",
11800            "Heavy Weight", "Backup",
11801            "A Services", "Home",
11802            "Previous", "B Services", "Cached"
11803    };
11804    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11805            "native",
11806            "sys", "pers", "fore",
11807            "vis", "percept",
11808            "heavy", "backup",
11809            "servicea", "home",
11810            "prev", "serviceb", "cached"
11811    };
11812
11813    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11814            long realtime, boolean isCheckinRequest, boolean isCompact) {
11815        if (isCheckinRequest || isCompact) {
11816            // short checkin version
11817            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11818        } else {
11819            pw.println("Applications Memory Usage (kB):");
11820            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11821        }
11822    }
11823
11824    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11825            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11826        boolean dumpDetails = false;
11827        boolean dumpFullDetails = false;
11828        boolean dumpDalvik = false;
11829        boolean oomOnly = false;
11830        boolean isCompact = false;
11831        boolean localOnly = false;
11832
11833        int opti = 0;
11834        while (opti < args.length) {
11835            String opt = args[opti];
11836            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11837                break;
11838            }
11839            opti++;
11840            if ("-a".equals(opt)) {
11841                dumpDetails = true;
11842                dumpFullDetails = true;
11843                dumpDalvik = true;
11844            } else if ("-d".equals(opt)) {
11845                dumpDalvik = true;
11846            } else if ("-c".equals(opt)) {
11847                isCompact = true;
11848            } else if ("--oom".equals(opt)) {
11849                oomOnly = true;
11850            } else if ("--local".equals(opt)) {
11851                localOnly = true;
11852            } else if ("-h".equals(opt)) {
11853                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11854                pw.println("  -a: include all available information for each process.");
11855                pw.println("  -d: include dalvik details when dumping process details.");
11856                pw.println("  -c: dump in a compact machine-parseable representation.");
11857                pw.println("  --oom: only show processes organized by oom adj.");
11858                pw.println("  --local: only collect details locally, don't call process.");
11859                pw.println("If [process] is specified it can be the name or ");
11860                pw.println("pid of a specific process to dump.");
11861                return;
11862            } else {
11863                pw.println("Unknown argument: " + opt + "; use -h for help");
11864            }
11865        }
11866
11867        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11868        long uptime = SystemClock.uptimeMillis();
11869        long realtime = SystemClock.elapsedRealtime();
11870        final long[] tmpLong = new long[1];
11871
11872        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11873        if (procs == null) {
11874            // No Java processes.  Maybe they want to print a native process.
11875            if (args != null && args.length > opti
11876                    && args[opti].charAt(0) != '-') {
11877                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11878                        = new ArrayList<ProcessCpuTracker.Stats>();
11879                updateCpuStatsNow();
11880                int findPid = -1;
11881                try {
11882                    findPid = Integer.parseInt(args[opti]);
11883                } catch (NumberFormatException e) {
11884                }
11885                synchronized (mProcessCpuThread) {
11886                    final int N = mProcessCpuTracker.countStats();
11887                    for (int i=0; i<N; i++) {
11888                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11889                        if (st.pid == findPid || (st.baseName != null
11890                                && st.baseName.equals(args[opti]))) {
11891                            nativeProcs.add(st);
11892                        }
11893                    }
11894                }
11895                if (nativeProcs.size() > 0) {
11896                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11897                            isCompact);
11898                    Debug.MemoryInfo mi = null;
11899                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11900                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11901                        final int pid = r.pid;
11902                        if (!isCheckinRequest && dumpDetails) {
11903                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11904                        }
11905                        if (mi == null) {
11906                            mi = new Debug.MemoryInfo();
11907                        }
11908                        if (dumpDetails || (!brief && !oomOnly)) {
11909                            Debug.getMemoryInfo(pid, mi);
11910                        } else {
11911                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11912                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11913                        }
11914                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11915                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11916                        if (isCheckinRequest) {
11917                            pw.println();
11918                        }
11919                    }
11920                    return;
11921                }
11922            }
11923            pw.println("No process found for: " + args[opti]);
11924            return;
11925        }
11926
11927        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11928            dumpDetails = true;
11929        }
11930
11931        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11932
11933        String[] innerArgs = new String[args.length-opti];
11934        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11935
11936        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11937        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11938        long nativePss=0, dalvikPss=0, otherPss=0;
11939        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11940
11941        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11942        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11943                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11944
11945        long totalPss = 0;
11946        long cachedPss = 0;
11947
11948        Debug.MemoryInfo mi = null;
11949        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11950            final ProcessRecord r = procs.get(i);
11951            final IApplicationThread thread;
11952            final int pid;
11953            final int oomAdj;
11954            final boolean hasActivities;
11955            synchronized (this) {
11956                thread = r.thread;
11957                pid = r.pid;
11958                oomAdj = r.getSetAdjWithServices();
11959                hasActivities = r.activities.size() > 0;
11960            }
11961            if (thread != null) {
11962                if (!isCheckinRequest && dumpDetails) {
11963                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
11964                }
11965                if (mi == null) {
11966                    mi = new Debug.MemoryInfo();
11967                }
11968                if (dumpDetails || (!brief && !oomOnly)) {
11969                    Debug.getMemoryInfo(pid, mi);
11970                } else {
11971                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11972                    mi.dalvikPrivateDirty = (int)tmpLong[0];
11973                }
11974                if (dumpDetails) {
11975                    if (localOnly) {
11976                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11977                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
11978                        if (isCheckinRequest) {
11979                            pw.println();
11980                        }
11981                    } else {
11982                        try {
11983                            pw.flush();
11984                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
11985                                    dumpDalvik, innerArgs);
11986                        } catch (RemoteException e) {
11987                            if (!isCheckinRequest) {
11988                                pw.println("Got RemoteException!");
11989                                pw.flush();
11990                            }
11991                        }
11992                    }
11993                }
11994
11995                final long myTotalPss = mi.getTotalPss();
11996                final long myTotalUss = mi.getTotalUss();
11997
11998                synchronized (this) {
11999                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12000                        // Record this for posterity if the process has been stable.
12001                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12002                    }
12003                }
12004
12005                if (!isCheckinRequest && mi != null) {
12006                    totalPss += myTotalPss;
12007                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12008                            (hasActivities ? " / activities)" : ")"),
12009                            r.processName, myTotalPss, pid, hasActivities);
12010                    procMems.add(pssItem);
12011                    procMemsMap.put(pid, pssItem);
12012
12013                    nativePss += mi.nativePss;
12014                    dalvikPss += mi.dalvikPss;
12015                    otherPss += mi.otherPss;
12016                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12017                        long mem = mi.getOtherPss(j);
12018                        miscPss[j] += mem;
12019                        otherPss -= mem;
12020                    }
12021
12022                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12023                        cachedPss += myTotalPss;
12024                    }
12025
12026                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12027                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12028                                || oomIndex == (oomPss.length-1)) {
12029                            oomPss[oomIndex] += myTotalPss;
12030                            if (oomProcs[oomIndex] == null) {
12031                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12032                            }
12033                            oomProcs[oomIndex].add(pssItem);
12034                            break;
12035                        }
12036                    }
12037                }
12038            }
12039        }
12040
12041        if (!isCheckinRequest && procs.size() > 1) {
12042            // If we are showing aggregations, also look for native processes to
12043            // include so that our aggregations are more accurate.
12044            updateCpuStatsNow();
12045            synchronized (mProcessCpuThread) {
12046                final int N = mProcessCpuTracker.countStats();
12047                for (int i=0; i<N; i++) {
12048                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12049                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12050                        if (mi == null) {
12051                            mi = new Debug.MemoryInfo();
12052                        }
12053                        if (!brief && !oomOnly) {
12054                            Debug.getMemoryInfo(st.pid, mi);
12055                        } else {
12056                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12057                            mi.nativePrivateDirty = (int)tmpLong[0];
12058                        }
12059
12060                        final long myTotalPss = mi.getTotalPss();
12061                        totalPss += myTotalPss;
12062
12063                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12064                                st.name, myTotalPss, st.pid, false);
12065                        procMems.add(pssItem);
12066
12067                        nativePss += mi.nativePss;
12068                        dalvikPss += mi.dalvikPss;
12069                        otherPss += mi.otherPss;
12070                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12071                            long mem = mi.getOtherPss(j);
12072                            miscPss[j] += mem;
12073                            otherPss -= mem;
12074                        }
12075                        oomPss[0] += myTotalPss;
12076                        if (oomProcs[0] == null) {
12077                            oomProcs[0] = new ArrayList<MemItem>();
12078                        }
12079                        oomProcs[0].add(pssItem);
12080                    }
12081                }
12082            }
12083
12084            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12085
12086            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12087            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12088            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12089            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12090                String label = Debug.MemoryInfo.getOtherLabel(j);
12091                catMems.add(new MemItem(label, label, miscPss[j], j));
12092            }
12093
12094            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12095            for (int j=0; j<oomPss.length; j++) {
12096                if (oomPss[j] != 0) {
12097                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12098                            : DUMP_MEM_OOM_LABEL[j];
12099                    MemItem item = new MemItem(label, label, oomPss[j],
12100                            DUMP_MEM_OOM_ADJ[j]);
12101                    item.subitems = oomProcs[j];
12102                    oomMems.add(item);
12103                }
12104            }
12105
12106            if (!brief && !oomOnly && !isCompact) {
12107                pw.println();
12108                pw.println("Total PSS by process:");
12109                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12110                pw.println();
12111            }
12112            if (!isCompact) {
12113                pw.println("Total PSS by OOM adjustment:");
12114            }
12115            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12116            if (!brief && !oomOnly) {
12117                PrintWriter out = categoryPw != null ? categoryPw : pw;
12118                if (!isCompact) {
12119                    out.println();
12120                    out.println("Total PSS by category:");
12121                }
12122                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12123            }
12124            if (!isCompact) {
12125                pw.println();
12126            }
12127            MemInfoReader memInfo = new MemInfoReader();
12128            memInfo.readMemInfo();
12129            if (!brief) {
12130                if (!isCompact) {
12131                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12132                    pw.println(" kB");
12133                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12134                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12135                            pw.print(cachedPss); pw.print(" cached pss + ");
12136                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12137                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12138                } else {
12139                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12140                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12141                            + memInfo.getFreeSizeKb()); pw.print(",");
12142                    pw.println(totalPss - cachedPss);
12143                }
12144            }
12145            if (!isCompact) {
12146                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12147                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12148                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12149                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12150                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12151                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12152                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12153                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12154                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12155                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12156                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12157            }
12158            if (!brief) {
12159                if (memInfo.getZramTotalSizeKb() != 0) {
12160                    if (!isCompact) {
12161                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12162                                pw.print(" kB physical used for ");
12163                                pw.print(memInfo.getSwapTotalSizeKb()
12164                                        - memInfo.getSwapFreeSizeKb());
12165                                pw.print(" kB in swap (");
12166                                pw.print(memInfo.getSwapTotalSizeKb());
12167                                pw.println(" kB total swap)");
12168                    } else {
12169                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12170                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12171                                pw.println(memInfo.getSwapFreeSizeKb());
12172                    }
12173                }
12174                final int[] SINGLE_LONG_FORMAT = new int[] {
12175                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12176                };
12177                long[] longOut = new long[1];
12178                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12179                        SINGLE_LONG_FORMAT, null, longOut, null);
12180                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12181                longOut[0] = 0;
12182                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12183                        SINGLE_LONG_FORMAT, null, longOut, null);
12184                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12185                longOut[0] = 0;
12186                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12187                        SINGLE_LONG_FORMAT, null, longOut, null);
12188                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12189                longOut[0] = 0;
12190                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12191                        SINGLE_LONG_FORMAT, null, longOut, null);
12192                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12193                if (!isCompact) {
12194                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12195                        pw.print("      KSM: "); pw.print(sharing);
12196                                pw.print(" kB saved from shared ");
12197                                pw.print(shared); pw.println(" kB");
12198                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12199                                pw.print(voltile); pw.println(" kB volatile");
12200                    }
12201                    pw.print("   Tuning: ");
12202                    pw.print(ActivityManager.staticGetMemoryClass());
12203                    pw.print(" (large ");
12204                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12205                    pw.print("), oom ");
12206                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12207                    pw.print(" kB");
12208                    pw.print(", restore limit ");
12209                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12210                    pw.print(" kB");
12211                    if (ActivityManager.isLowRamDeviceStatic()) {
12212                        pw.print(" (low-ram)");
12213                    }
12214                    if (ActivityManager.isHighEndGfx()) {
12215                        pw.print(" (high-end-gfx)");
12216                    }
12217                    pw.println();
12218                } else {
12219                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12220                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12221                    pw.println(voltile);
12222                    pw.print("tuning,");
12223                    pw.print(ActivityManager.staticGetMemoryClass());
12224                    pw.print(',');
12225                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12226                    pw.print(',');
12227                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12228                    if (ActivityManager.isLowRamDeviceStatic()) {
12229                        pw.print(",low-ram");
12230                    }
12231                    if (ActivityManager.isHighEndGfx()) {
12232                        pw.print(",high-end-gfx");
12233                    }
12234                    pw.println();
12235                }
12236            }
12237        }
12238    }
12239
12240    /**
12241     * Searches array of arguments for the specified string
12242     * @param args array of argument strings
12243     * @param value value to search for
12244     * @return true if the value is contained in the array
12245     */
12246    private static boolean scanArgs(String[] args, String value) {
12247        if (args != null) {
12248            for (String arg : args) {
12249                if (value.equals(arg)) {
12250                    return true;
12251                }
12252            }
12253        }
12254        return false;
12255    }
12256
12257    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12258            ContentProviderRecord cpr, boolean always) {
12259        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12260
12261        if (!inLaunching || always) {
12262            synchronized (cpr) {
12263                cpr.launchingApp = null;
12264                cpr.notifyAll();
12265            }
12266            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12267            String names[] = cpr.info.authority.split(";");
12268            for (int j = 0; j < names.length; j++) {
12269                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12270            }
12271        }
12272
12273        for (int i=0; i<cpr.connections.size(); i++) {
12274            ContentProviderConnection conn = cpr.connections.get(i);
12275            if (conn.waiting) {
12276                // If this connection is waiting for the provider, then we don't
12277                // need to mess with its process unless we are always removing
12278                // or for some reason the provider is not currently launching.
12279                if (inLaunching && !always) {
12280                    continue;
12281                }
12282            }
12283            ProcessRecord capp = conn.client;
12284            conn.dead = true;
12285            if (conn.stableCount > 0) {
12286                if (!capp.persistent && capp.thread != null
12287                        && capp.pid != 0
12288                        && capp.pid != MY_PID) {
12289                    killUnneededProcessLocked(capp, "depends on provider "
12290                            + cpr.name.flattenToShortString()
12291                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12292                }
12293            } else if (capp.thread != null && conn.provider.provider != null) {
12294                try {
12295                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12296                } catch (RemoteException e) {
12297                }
12298                // In the protocol here, we don't expect the client to correctly
12299                // clean up this connection, we'll just remove it.
12300                cpr.connections.remove(i);
12301                conn.client.conProviders.remove(conn);
12302            }
12303        }
12304
12305        if (inLaunching && always) {
12306            mLaunchingProviders.remove(cpr);
12307        }
12308        return inLaunching;
12309    }
12310
12311    /**
12312     * Main code for cleaning up a process when it has gone away.  This is
12313     * called both as a result of the process dying, or directly when stopping
12314     * a process when running in single process mode.
12315     */
12316    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12317            boolean restarting, boolean allowRestart, int index) {
12318        if (index >= 0) {
12319            removeLruProcessLocked(app);
12320            ProcessList.remove(app.pid);
12321        }
12322
12323        mProcessesToGc.remove(app);
12324        mPendingPssProcesses.remove(app);
12325
12326        // Dismiss any open dialogs.
12327        if (app.crashDialog != null && !app.forceCrashReport) {
12328            app.crashDialog.dismiss();
12329            app.crashDialog = null;
12330        }
12331        if (app.anrDialog != null) {
12332            app.anrDialog.dismiss();
12333            app.anrDialog = null;
12334        }
12335        if (app.waitDialog != null) {
12336            app.waitDialog.dismiss();
12337            app.waitDialog = null;
12338        }
12339
12340        app.crashing = false;
12341        app.notResponding = false;
12342
12343        app.resetPackageList(mProcessStats);
12344        app.unlinkDeathRecipient();
12345        app.makeInactive(mProcessStats);
12346        app.waitingToKill = null;
12347        app.forcingToForeground = null;
12348        app.foregroundServices = false;
12349        app.foregroundActivities = false;
12350        app.hasShownUi = false;
12351        app.hasAboveClient = false;
12352        app.hasClientActivities = false;
12353
12354        mServices.killServicesLocked(app, allowRestart);
12355
12356        boolean restart = false;
12357
12358        // Remove published content providers.
12359        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12360            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12361            final boolean always = app.bad || !allowRestart;
12362            if (removeDyingProviderLocked(app, cpr, always) || always) {
12363                // We left the provider in the launching list, need to
12364                // restart it.
12365                restart = true;
12366            }
12367
12368            cpr.provider = null;
12369            cpr.proc = null;
12370        }
12371        app.pubProviders.clear();
12372
12373        // Take care of any launching providers waiting for this process.
12374        if (checkAppInLaunchingProvidersLocked(app, false)) {
12375            restart = true;
12376        }
12377
12378        // Unregister from connected content providers.
12379        if (!app.conProviders.isEmpty()) {
12380            for (int i=0; i<app.conProviders.size(); i++) {
12381                ContentProviderConnection conn = app.conProviders.get(i);
12382                conn.provider.connections.remove(conn);
12383            }
12384            app.conProviders.clear();
12385        }
12386
12387        // At this point there may be remaining entries in mLaunchingProviders
12388        // where we were the only one waiting, so they are no longer of use.
12389        // Look for these and clean up if found.
12390        // XXX Commented out for now.  Trying to figure out a way to reproduce
12391        // the actual situation to identify what is actually going on.
12392        if (false) {
12393            for (int i=0; i<mLaunchingProviders.size(); i++) {
12394                ContentProviderRecord cpr = (ContentProviderRecord)
12395                        mLaunchingProviders.get(i);
12396                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12397                    synchronized (cpr) {
12398                        cpr.launchingApp = null;
12399                        cpr.notifyAll();
12400                    }
12401                }
12402            }
12403        }
12404
12405        skipCurrentReceiverLocked(app);
12406
12407        // Unregister any receivers.
12408        for (int i=app.receivers.size()-1; i>=0; i--) {
12409            removeReceiverLocked(app.receivers.valueAt(i));
12410        }
12411        app.receivers.clear();
12412
12413        // If the app is undergoing backup, tell the backup manager about it
12414        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12415            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12416                    + mBackupTarget.appInfo + " died during backup");
12417            try {
12418                IBackupManager bm = IBackupManager.Stub.asInterface(
12419                        ServiceManager.getService(Context.BACKUP_SERVICE));
12420                bm.agentDisconnected(app.info.packageName);
12421            } catch (RemoteException e) {
12422                // can't happen; backup manager is local
12423            }
12424        }
12425
12426        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12427            ProcessChangeItem item = mPendingProcessChanges.get(i);
12428            if (item.pid == app.pid) {
12429                mPendingProcessChanges.remove(i);
12430                mAvailProcessChanges.add(item);
12431            }
12432        }
12433        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12434
12435        // If the caller is restarting this app, then leave it in its
12436        // current lists and let the caller take care of it.
12437        if (restarting) {
12438            return;
12439        }
12440
12441        if (!app.persistent || app.isolated) {
12442            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12443                    "Removing non-persistent process during cleanup: " + app);
12444            mProcessNames.remove(app.processName, app.uid);
12445            mIsolatedProcesses.remove(app.uid);
12446            if (mHeavyWeightProcess == app) {
12447                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12448                        mHeavyWeightProcess.userId, 0));
12449                mHeavyWeightProcess = null;
12450            }
12451        } else if (!app.removed) {
12452            // This app is persistent, so we need to keep its record around.
12453            // If it is not already on the pending app list, add it there
12454            // and start a new process for it.
12455            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12456                mPersistentStartingProcesses.add(app);
12457                restart = true;
12458            }
12459        }
12460        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12461                "Clean-up removing on hold: " + app);
12462        mProcessesOnHold.remove(app);
12463
12464        if (app == mHomeProcess) {
12465            mHomeProcess = null;
12466        }
12467        if (app == mPreviousProcess) {
12468            mPreviousProcess = null;
12469        }
12470
12471        if (restart && !app.isolated) {
12472            // We have components that still need to be running in the
12473            // process, so re-launch it.
12474            mProcessNames.put(app.processName, app.uid, app);
12475            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
12476        } else if (app.pid > 0 && app.pid != MY_PID) {
12477            // Goodbye!
12478            synchronized (mPidsSelfLocked) {
12479                mPidsSelfLocked.remove(app.pid);
12480                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12481            }
12482            app.setPid(0);
12483        }
12484    }
12485
12486    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12487        // Look through the content providers we are waiting to have launched,
12488        // and if any run in this process then either schedule a restart of
12489        // the process or kill the client waiting for it if this process has
12490        // gone bad.
12491        int NL = mLaunchingProviders.size();
12492        boolean restart = false;
12493        for (int i=0; i<NL; i++) {
12494            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12495            if (cpr.launchingApp == app) {
12496                if (!alwaysBad && !app.bad) {
12497                    restart = true;
12498                } else {
12499                    removeDyingProviderLocked(app, cpr, true);
12500                    // cpr should have been removed from mLaunchingProviders
12501                    NL = mLaunchingProviders.size();
12502                    i--;
12503                }
12504            }
12505        }
12506        return restart;
12507    }
12508
12509    // =========================================================
12510    // SERVICES
12511    // =========================================================
12512
12513    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12514            int flags) {
12515        enforceNotIsolatedCaller("getServices");
12516        synchronized (this) {
12517            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12518        }
12519    }
12520
12521    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12522        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12523        synchronized (this) {
12524            return mServices.getRunningServiceControlPanelLocked(name);
12525        }
12526    }
12527
12528    public ComponentName startService(IApplicationThread caller, Intent service,
12529            String resolvedType, int userId) {
12530        enforceNotIsolatedCaller("startService");
12531        // Refuse possible leaked file descriptors
12532        if (service != null && service.hasFileDescriptors() == true) {
12533            throw new IllegalArgumentException("File descriptors passed in Intent");
12534        }
12535
12536        if (DEBUG_SERVICE)
12537            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12538        synchronized(this) {
12539            final int callingPid = Binder.getCallingPid();
12540            final int callingUid = Binder.getCallingUid();
12541            final long origId = Binder.clearCallingIdentity();
12542            ComponentName res = mServices.startServiceLocked(caller, service,
12543                    resolvedType, callingPid, callingUid, userId);
12544            Binder.restoreCallingIdentity(origId);
12545            return res;
12546        }
12547    }
12548
12549    ComponentName startServiceInPackage(int uid,
12550            Intent service, String resolvedType, int userId) {
12551        synchronized(this) {
12552            if (DEBUG_SERVICE)
12553                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12554            final long origId = Binder.clearCallingIdentity();
12555            ComponentName res = mServices.startServiceLocked(null, service,
12556                    resolvedType, -1, uid, userId);
12557            Binder.restoreCallingIdentity(origId);
12558            return res;
12559        }
12560    }
12561
12562    public int stopService(IApplicationThread caller, Intent service,
12563            String resolvedType, int userId) {
12564        enforceNotIsolatedCaller("stopService");
12565        // Refuse possible leaked file descriptors
12566        if (service != null && service.hasFileDescriptors() == true) {
12567            throw new IllegalArgumentException("File descriptors passed in Intent");
12568        }
12569
12570        synchronized(this) {
12571            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12572        }
12573    }
12574
12575    public IBinder peekService(Intent service, String resolvedType) {
12576        enforceNotIsolatedCaller("peekService");
12577        // Refuse possible leaked file descriptors
12578        if (service != null && service.hasFileDescriptors() == true) {
12579            throw new IllegalArgumentException("File descriptors passed in Intent");
12580        }
12581        synchronized(this) {
12582            return mServices.peekServiceLocked(service, resolvedType);
12583        }
12584    }
12585
12586    public boolean stopServiceToken(ComponentName className, IBinder token,
12587            int startId) {
12588        synchronized(this) {
12589            return mServices.stopServiceTokenLocked(className, token, startId);
12590        }
12591    }
12592
12593    public void setServiceForeground(ComponentName className, IBinder token,
12594            int id, Notification notification, boolean removeNotification) {
12595        synchronized(this) {
12596            mServices.setServiceForegroundLocked(className, token, id, notification,
12597                    removeNotification);
12598        }
12599    }
12600
12601    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12602            boolean requireFull, String name, String callerPackage) {
12603        final int callingUserId = UserHandle.getUserId(callingUid);
12604        if (callingUserId != userId) {
12605            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12606                if ((requireFull || checkComponentPermission(
12607                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12608                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12609                        && checkComponentPermission(
12610                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12611                                callingPid, callingUid, -1, true)
12612                                != PackageManager.PERMISSION_GRANTED) {
12613                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12614                        // In this case, they would like to just execute as their
12615                        // owner user instead of failing.
12616                        userId = callingUserId;
12617                    } else {
12618                        StringBuilder builder = new StringBuilder(128);
12619                        builder.append("Permission Denial: ");
12620                        builder.append(name);
12621                        if (callerPackage != null) {
12622                            builder.append(" from ");
12623                            builder.append(callerPackage);
12624                        }
12625                        builder.append(" asks to run as user ");
12626                        builder.append(userId);
12627                        builder.append(" but is calling from user ");
12628                        builder.append(UserHandle.getUserId(callingUid));
12629                        builder.append("; this requires ");
12630                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12631                        if (!requireFull) {
12632                            builder.append(" or ");
12633                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12634                        }
12635                        String msg = builder.toString();
12636                        Slog.w(TAG, msg);
12637                        throw new SecurityException(msg);
12638                    }
12639                }
12640            }
12641            if (userId == UserHandle.USER_CURRENT
12642                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12643                // Note that we may be accessing this outside of a lock...
12644                // shouldn't be a big deal, if this is being called outside
12645                // of a locked context there is intrinsically a race with
12646                // the value the caller will receive and someone else changing it.
12647                userId = mCurrentUserId;
12648            }
12649            if (!allowAll && userId < 0) {
12650                throw new IllegalArgumentException(
12651                        "Call does not support special user #" + userId);
12652            }
12653        }
12654        return userId;
12655    }
12656
12657    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12658            String className, int flags) {
12659        boolean result = false;
12660        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12661            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12662                if (ActivityManager.checkUidPermission(
12663                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12664                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12665                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12666                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12667                            + " requests FLAG_SINGLE_USER, but app does not hold "
12668                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12669                    Slog.w(TAG, msg);
12670                    throw new SecurityException(msg);
12671                }
12672                result = true;
12673            }
12674        } else if (componentProcessName == aInfo.packageName) {
12675            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12676        } else if ("system".equals(componentProcessName)) {
12677            result = true;
12678        }
12679        if (DEBUG_MU) {
12680            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12681                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12682        }
12683        return result;
12684    }
12685
12686    public int bindService(IApplicationThread caller, IBinder token,
12687            Intent service, String resolvedType,
12688            IServiceConnection connection, int flags, int userId) {
12689        enforceNotIsolatedCaller("bindService");
12690        // Refuse possible leaked file descriptors
12691        if (service != null && service.hasFileDescriptors() == true) {
12692            throw new IllegalArgumentException("File descriptors passed in Intent");
12693        }
12694
12695        synchronized(this) {
12696            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12697                    connection, flags, userId);
12698        }
12699    }
12700
12701    public boolean unbindService(IServiceConnection connection) {
12702        synchronized (this) {
12703            return mServices.unbindServiceLocked(connection);
12704        }
12705    }
12706
12707    public void publishService(IBinder token, Intent intent, IBinder service) {
12708        // Refuse possible leaked file descriptors
12709        if (intent != null && intent.hasFileDescriptors() == true) {
12710            throw new IllegalArgumentException("File descriptors passed in Intent");
12711        }
12712
12713        synchronized(this) {
12714            if (!(token instanceof ServiceRecord)) {
12715                throw new IllegalArgumentException("Invalid service token");
12716            }
12717            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12718        }
12719    }
12720
12721    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12722        // Refuse possible leaked file descriptors
12723        if (intent != null && intent.hasFileDescriptors() == true) {
12724            throw new IllegalArgumentException("File descriptors passed in Intent");
12725        }
12726
12727        synchronized(this) {
12728            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12729        }
12730    }
12731
12732    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12733        synchronized(this) {
12734            if (!(token instanceof ServiceRecord)) {
12735                throw new IllegalArgumentException("Invalid service token");
12736            }
12737            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12738        }
12739    }
12740
12741    // =========================================================
12742    // BACKUP AND RESTORE
12743    // =========================================================
12744
12745    // Cause the target app to be launched if necessary and its backup agent
12746    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12747    // activity manager to announce its creation.
12748    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12749        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12750        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12751
12752        synchronized(this) {
12753            // !!! TODO: currently no check here that we're already bound
12754            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12755            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12756            synchronized (stats) {
12757                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12758            }
12759
12760            // Backup agent is now in use, its package can't be stopped.
12761            try {
12762                AppGlobals.getPackageManager().setPackageStoppedState(
12763                        app.packageName, false, UserHandle.getUserId(app.uid));
12764            } catch (RemoteException e) {
12765            } catch (IllegalArgumentException e) {
12766                Slog.w(TAG, "Failed trying to unstop package "
12767                        + app.packageName + ": " + e);
12768            }
12769
12770            BackupRecord r = new BackupRecord(ss, app, backupMode);
12771            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12772                    ? new ComponentName(app.packageName, app.backupAgentName)
12773                    : new ComponentName("android", "FullBackupAgent");
12774            // startProcessLocked() returns existing proc's record if it's already running
12775            ProcessRecord proc = startProcessLocked(app.processName, app,
12776                    false, 0, "backup", hostingName, false, false, false);
12777            if (proc == null) {
12778                Slog.e(TAG, "Unable to start backup agent process " + r);
12779                return false;
12780            }
12781
12782            r.app = proc;
12783            mBackupTarget = r;
12784            mBackupAppName = app.packageName;
12785
12786            // Try not to kill the process during backup
12787            updateOomAdjLocked(proc);
12788
12789            // If the process is already attached, schedule the creation of the backup agent now.
12790            // If it is not yet live, this will be done when it attaches to the framework.
12791            if (proc.thread != null) {
12792                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12793                try {
12794                    proc.thread.scheduleCreateBackupAgent(app,
12795                            compatibilityInfoForPackageLocked(app), backupMode);
12796                } catch (RemoteException e) {
12797                    // Will time out on the backup manager side
12798                }
12799            } else {
12800                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12801            }
12802            // Invariants: at this point, the target app process exists and the application
12803            // is either already running or in the process of coming up.  mBackupTarget and
12804            // mBackupAppName describe the app, so that when it binds back to the AM we
12805            // know that it's scheduled for a backup-agent operation.
12806        }
12807
12808        return true;
12809    }
12810
12811    @Override
12812    public void clearPendingBackup() {
12813        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12814        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12815
12816        synchronized (this) {
12817            mBackupTarget = null;
12818            mBackupAppName = null;
12819        }
12820    }
12821
12822    // A backup agent has just come up
12823    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12824        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12825                + " = " + agent);
12826
12827        synchronized(this) {
12828            if (!agentPackageName.equals(mBackupAppName)) {
12829                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12830                return;
12831            }
12832        }
12833
12834        long oldIdent = Binder.clearCallingIdentity();
12835        try {
12836            IBackupManager bm = IBackupManager.Stub.asInterface(
12837                    ServiceManager.getService(Context.BACKUP_SERVICE));
12838            bm.agentConnected(agentPackageName, agent);
12839        } catch (RemoteException e) {
12840            // can't happen; the backup manager service is local
12841        } catch (Exception e) {
12842            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12843            e.printStackTrace();
12844        } finally {
12845            Binder.restoreCallingIdentity(oldIdent);
12846        }
12847    }
12848
12849    // done with this agent
12850    public void unbindBackupAgent(ApplicationInfo appInfo) {
12851        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12852        if (appInfo == null) {
12853            Slog.w(TAG, "unbind backup agent for null app");
12854            return;
12855        }
12856
12857        synchronized(this) {
12858            try {
12859                if (mBackupAppName == null) {
12860                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12861                    return;
12862                }
12863
12864                if (!mBackupAppName.equals(appInfo.packageName)) {
12865                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12866                    return;
12867                }
12868
12869                // Not backing this app up any more; reset its OOM adjustment
12870                final ProcessRecord proc = mBackupTarget.app;
12871                updateOomAdjLocked(proc);
12872
12873                // If the app crashed during backup, 'thread' will be null here
12874                if (proc.thread != null) {
12875                    try {
12876                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12877                                compatibilityInfoForPackageLocked(appInfo));
12878                    } catch (Exception e) {
12879                        Slog.e(TAG, "Exception when unbinding backup agent:");
12880                        e.printStackTrace();
12881                    }
12882                }
12883            } finally {
12884                mBackupTarget = null;
12885                mBackupAppName = null;
12886            }
12887        }
12888    }
12889    // =========================================================
12890    // BROADCASTS
12891    // =========================================================
12892
12893    private final List getStickiesLocked(String action, IntentFilter filter,
12894            List cur, int userId) {
12895        final ContentResolver resolver = mContext.getContentResolver();
12896        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12897        if (stickies == null) {
12898            return cur;
12899        }
12900        final ArrayList<Intent> list = stickies.get(action);
12901        if (list == null) {
12902            return cur;
12903        }
12904        int N = list.size();
12905        for (int i=0; i<N; i++) {
12906            Intent intent = list.get(i);
12907            if (filter.match(resolver, intent, true, TAG) >= 0) {
12908                if (cur == null) {
12909                    cur = new ArrayList<Intent>();
12910                }
12911                cur.add(intent);
12912            }
12913        }
12914        return cur;
12915    }
12916
12917    boolean isPendingBroadcastProcessLocked(int pid) {
12918        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12919                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12920    }
12921
12922    void skipPendingBroadcastLocked(int pid) {
12923            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12924            for (BroadcastQueue queue : mBroadcastQueues) {
12925                queue.skipPendingBroadcastLocked(pid);
12926            }
12927    }
12928
12929    // The app just attached; send any pending broadcasts that it should receive
12930    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12931        boolean didSomething = false;
12932        for (BroadcastQueue queue : mBroadcastQueues) {
12933            didSomething |= queue.sendPendingBroadcastsLocked(app);
12934        }
12935        return didSomething;
12936    }
12937
12938    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12939            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
12940        enforceNotIsolatedCaller("registerReceiver");
12941        int callingUid;
12942        int callingPid;
12943        synchronized(this) {
12944            ProcessRecord callerApp = null;
12945            if (caller != null) {
12946                callerApp = getRecordForAppLocked(caller);
12947                if (callerApp == null) {
12948                    throw new SecurityException(
12949                            "Unable to find app for caller " + caller
12950                            + " (pid=" + Binder.getCallingPid()
12951                            + ") when registering receiver " + receiver);
12952                }
12953                if (callerApp.info.uid != Process.SYSTEM_UID &&
12954                        !callerApp.pkgList.containsKey(callerPackage) &&
12955                        !"android".equals(callerPackage)) {
12956                    throw new SecurityException("Given caller package " + callerPackage
12957                            + " is not running in process " + callerApp);
12958                }
12959                callingUid = callerApp.info.uid;
12960                callingPid = callerApp.pid;
12961            } else {
12962                callerPackage = null;
12963                callingUid = Binder.getCallingUid();
12964                callingPid = Binder.getCallingPid();
12965            }
12966
12967            userId = this.handleIncomingUser(callingPid, callingUid, userId,
12968                    true, true, "registerReceiver", callerPackage);
12969
12970            List allSticky = null;
12971
12972            // Look for any matching sticky broadcasts...
12973            Iterator actions = filter.actionsIterator();
12974            if (actions != null) {
12975                while (actions.hasNext()) {
12976                    String action = (String)actions.next();
12977                    allSticky = getStickiesLocked(action, filter, allSticky,
12978                            UserHandle.USER_ALL);
12979                    allSticky = getStickiesLocked(action, filter, allSticky,
12980                            UserHandle.getUserId(callingUid));
12981                }
12982            } else {
12983                allSticky = getStickiesLocked(null, filter, allSticky,
12984                        UserHandle.USER_ALL);
12985                allSticky = getStickiesLocked(null, filter, allSticky,
12986                        UserHandle.getUserId(callingUid));
12987            }
12988
12989            // The first sticky in the list is returned directly back to
12990            // the client.
12991            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12992
12993            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
12994                    + ": " + sticky);
12995
12996            if (receiver == null) {
12997                return sticky;
12998            }
12999
13000            ReceiverList rl
13001                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13002            if (rl == null) {
13003                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13004                        userId, receiver);
13005                if (rl.app != null) {
13006                    rl.app.receivers.add(rl);
13007                } else {
13008                    try {
13009                        receiver.asBinder().linkToDeath(rl, 0);
13010                    } catch (RemoteException e) {
13011                        return sticky;
13012                    }
13013                    rl.linkedToDeath = true;
13014                }
13015                mRegisteredReceivers.put(receiver.asBinder(), rl);
13016            } else if (rl.uid != callingUid) {
13017                throw new IllegalArgumentException(
13018                        "Receiver requested to register for uid " + callingUid
13019                        + " was previously registered for uid " + rl.uid);
13020            } else if (rl.pid != callingPid) {
13021                throw new IllegalArgumentException(
13022                        "Receiver requested to register for pid " + callingPid
13023                        + " was previously registered for pid " + rl.pid);
13024            } else if (rl.userId != userId) {
13025                throw new IllegalArgumentException(
13026                        "Receiver requested to register for user " + userId
13027                        + " was previously registered for user " + rl.userId);
13028            }
13029            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13030                    permission, callingUid, userId);
13031            rl.add(bf);
13032            if (!bf.debugCheck()) {
13033                Slog.w(TAG, "==> For Dynamic broadast");
13034            }
13035            mReceiverResolver.addFilter(bf);
13036
13037            // Enqueue broadcasts for all existing stickies that match
13038            // this filter.
13039            if (allSticky != null) {
13040                ArrayList receivers = new ArrayList();
13041                receivers.add(bf);
13042
13043                int N = allSticky.size();
13044                for (int i=0; i<N; i++) {
13045                    Intent intent = (Intent)allSticky.get(i);
13046                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13047                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13048                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13049                            null, null, false, true, true, -1);
13050                    queue.enqueueParallelBroadcastLocked(r);
13051                    queue.scheduleBroadcastsLocked();
13052                }
13053            }
13054
13055            return sticky;
13056        }
13057    }
13058
13059    public void unregisterReceiver(IIntentReceiver receiver) {
13060        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13061
13062        final long origId = Binder.clearCallingIdentity();
13063        try {
13064            boolean doTrim = false;
13065
13066            synchronized(this) {
13067                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13068                if (rl != null) {
13069                    if (rl.curBroadcast != null) {
13070                        BroadcastRecord r = rl.curBroadcast;
13071                        final boolean doNext = finishReceiverLocked(
13072                                receiver.asBinder(), r.resultCode, r.resultData,
13073                                r.resultExtras, r.resultAbort);
13074                        if (doNext) {
13075                            doTrim = true;
13076                            r.queue.processNextBroadcast(false);
13077                        }
13078                    }
13079
13080                    if (rl.app != null) {
13081                        rl.app.receivers.remove(rl);
13082                    }
13083                    removeReceiverLocked(rl);
13084                    if (rl.linkedToDeath) {
13085                        rl.linkedToDeath = false;
13086                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13087                    }
13088                }
13089            }
13090
13091            // If we actually concluded any broadcasts, we might now be able
13092            // to trim the recipients' apps from our working set
13093            if (doTrim) {
13094                trimApplications();
13095                return;
13096            }
13097
13098        } finally {
13099            Binder.restoreCallingIdentity(origId);
13100        }
13101    }
13102
13103    void removeReceiverLocked(ReceiverList rl) {
13104        mRegisteredReceivers.remove(rl.receiver.asBinder());
13105        int N = rl.size();
13106        for (int i=0; i<N; i++) {
13107            mReceiverResolver.removeFilter(rl.get(i));
13108        }
13109    }
13110
13111    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13112        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13113            ProcessRecord r = mLruProcesses.get(i);
13114            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13115                try {
13116                    r.thread.dispatchPackageBroadcast(cmd, packages);
13117                } catch (RemoteException ex) {
13118                }
13119            }
13120        }
13121    }
13122
13123    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13124            int[] users) {
13125        List<ResolveInfo> receivers = null;
13126        try {
13127            HashSet<ComponentName> singleUserReceivers = null;
13128            boolean scannedFirstReceivers = false;
13129            for (int user : users) {
13130                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13131                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13132                if (user != 0 && newReceivers != null) {
13133                    // If this is not the primary user, we need to check for
13134                    // any receivers that should be filtered out.
13135                    for (int i=0; i<newReceivers.size(); i++) {
13136                        ResolveInfo ri = newReceivers.get(i);
13137                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13138                            newReceivers.remove(i);
13139                            i--;
13140                        }
13141                    }
13142                }
13143                if (newReceivers != null && newReceivers.size() == 0) {
13144                    newReceivers = null;
13145                }
13146                if (receivers == null) {
13147                    receivers = newReceivers;
13148                } else if (newReceivers != null) {
13149                    // We need to concatenate the additional receivers
13150                    // found with what we have do far.  This would be easy,
13151                    // but we also need to de-dup any receivers that are
13152                    // singleUser.
13153                    if (!scannedFirstReceivers) {
13154                        // Collect any single user receivers we had already retrieved.
13155                        scannedFirstReceivers = true;
13156                        for (int i=0; i<receivers.size(); i++) {
13157                            ResolveInfo ri = receivers.get(i);
13158                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13159                                ComponentName cn = new ComponentName(
13160                                        ri.activityInfo.packageName, ri.activityInfo.name);
13161                                if (singleUserReceivers == null) {
13162                                    singleUserReceivers = new HashSet<ComponentName>();
13163                                }
13164                                singleUserReceivers.add(cn);
13165                            }
13166                        }
13167                    }
13168                    // Add the new results to the existing results, tracking
13169                    // and de-dupping single user receivers.
13170                    for (int i=0; i<newReceivers.size(); i++) {
13171                        ResolveInfo ri = newReceivers.get(i);
13172                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13173                            ComponentName cn = new ComponentName(
13174                                    ri.activityInfo.packageName, ri.activityInfo.name);
13175                            if (singleUserReceivers == null) {
13176                                singleUserReceivers = new HashSet<ComponentName>();
13177                            }
13178                            if (!singleUserReceivers.contains(cn)) {
13179                                singleUserReceivers.add(cn);
13180                                receivers.add(ri);
13181                            }
13182                        } else {
13183                            receivers.add(ri);
13184                        }
13185                    }
13186                }
13187            }
13188        } catch (RemoteException ex) {
13189            // pm is in same process, this will never happen.
13190        }
13191        return receivers;
13192    }
13193
13194    private final int broadcastIntentLocked(ProcessRecord callerApp,
13195            String callerPackage, Intent intent, String resolvedType,
13196            IIntentReceiver resultTo, int resultCode, String resultData,
13197            Bundle map, String requiredPermission, int appOp,
13198            boolean ordered, boolean sticky, int callingPid, int callingUid,
13199            int userId) {
13200        intent = new Intent(intent);
13201
13202        // By default broadcasts do not go to stopped apps.
13203        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13204
13205        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13206            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13207            + " ordered=" + ordered + " userid=" + userId);
13208        if ((resultTo != null) && !ordered) {
13209            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13210        }
13211
13212        userId = handleIncomingUser(callingPid, callingUid, userId,
13213                true, false, "broadcast", callerPackage);
13214
13215        // Make sure that the user who is receiving this broadcast is started.
13216        // If not, we will just skip it.
13217        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13218            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13219                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13220                Slog.w(TAG, "Skipping broadcast of " + intent
13221                        + ": user " + userId + " is stopped");
13222                return ActivityManager.BROADCAST_SUCCESS;
13223            }
13224        }
13225
13226        /*
13227         * Prevent non-system code (defined here to be non-persistent
13228         * processes) from sending protected broadcasts.
13229         */
13230        int callingAppId = UserHandle.getAppId(callingUid);
13231        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13232            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13233            callingUid == 0) {
13234            // Always okay.
13235        } else if (callerApp == null || !callerApp.persistent) {
13236            try {
13237                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13238                        intent.getAction())) {
13239                    String msg = "Permission Denial: not allowed to send broadcast "
13240                            + intent.getAction() + " from pid="
13241                            + callingPid + ", uid=" + callingUid;
13242                    Slog.w(TAG, msg);
13243                    throw new SecurityException(msg);
13244                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13245                    // Special case for compatibility: we don't want apps to send this,
13246                    // but historically it has not been protected and apps may be using it
13247                    // to poke their own app widget.  So, instead of making it protected,
13248                    // just limit it to the caller.
13249                    if (callerApp == null) {
13250                        String msg = "Permission Denial: not allowed to send broadcast "
13251                                + intent.getAction() + " from unknown caller.";
13252                        Slog.w(TAG, msg);
13253                        throw new SecurityException(msg);
13254                    } else if (intent.getComponent() != null) {
13255                        // They are good enough to send to an explicit component...  verify
13256                        // it is being sent to the calling app.
13257                        if (!intent.getComponent().getPackageName().equals(
13258                                callerApp.info.packageName)) {
13259                            String msg = "Permission Denial: not allowed to send broadcast "
13260                                    + intent.getAction() + " to "
13261                                    + intent.getComponent().getPackageName() + " from "
13262                                    + callerApp.info.packageName;
13263                            Slog.w(TAG, msg);
13264                            throw new SecurityException(msg);
13265                        }
13266                    } else {
13267                        // Limit broadcast to their own package.
13268                        intent.setPackage(callerApp.info.packageName);
13269                    }
13270                }
13271            } catch (RemoteException e) {
13272                Slog.w(TAG, "Remote exception", e);
13273                return ActivityManager.BROADCAST_SUCCESS;
13274            }
13275        }
13276
13277        // Handle special intents: if this broadcast is from the package
13278        // manager about a package being removed, we need to remove all of
13279        // its activities from the history stack.
13280        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13281                intent.getAction());
13282        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13283                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13284                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13285                || uidRemoved) {
13286            if (checkComponentPermission(
13287                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13288                    callingPid, callingUid, -1, true)
13289                    == PackageManager.PERMISSION_GRANTED) {
13290                if (uidRemoved) {
13291                    final Bundle intentExtras = intent.getExtras();
13292                    final int uid = intentExtras != null
13293                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13294                    if (uid >= 0) {
13295                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13296                        synchronized (bs) {
13297                            bs.removeUidStatsLocked(uid);
13298                        }
13299                        mAppOpsService.uidRemoved(uid);
13300                    }
13301                } else {
13302                    // If resources are unavailable just force stop all
13303                    // those packages and flush the attribute cache as well.
13304                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13305                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13306                        if (list != null && (list.length > 0)) {
13307                            for (String pkg : list) {
13308                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
13309                                        "storage unmount");
13310                            }
13311                            sendPackageBroadcastLocked(
13312                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13313                        }
13314                    } else {
13315                        Uri data = intent.getData();
13316                        String ssp;
13317                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13318                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13319                                    intent.getAction());
13320                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13321                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13322                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13323                                        false, userId, removed ? "pkg removed" : "pkg changed");
13324                            }
13325                            if (removed) {
13326                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13327                                        new String[] {ssp}, userId);
13328                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13329                                    mAppOpsService.packageRemoved(
13330                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13331
13332                                    // Remove all permissions granted from/to this package
13333                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13334                                }
13335                            }
13336                        }
13337                    }
13338                }
13339            } else {
13340                String msg = "Permission Denial: " + intent.getAction()
13341                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13342                        + ", uid=" + callingUid + ")"
13343                        + " requires "
13344                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13345                Slog.w(TAG, msg);
13346                throw new SecurityException(msg);
13347            }
13348
13349        // Special case for adding a package: by default turn on compatibility
13350        // mode.
13351        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13352            Uri data = intent.getData();
13353            String ssp;
13354            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13355                mCompatModePackages.handlePackageAddedLocked(ssp,
13356                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13357            }
13358        }
13359
13360        /*
13361         * If this is the time zone changed action, queue up a message that will reset the timezone
13362         * of all currently running processes. This message will get queued up before the broadcast
13363         * happens.
13364         */
13365        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13366            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13367        }
13368
13369        /*
13370         * If the user set the time, let all running processes know.
13371         */
13372        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13373            final int is24Hour = intent.getBooleanExtra(
13374                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13375            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13376        }
13377
13378        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13379            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13380        }
13381
13382        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13383            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13384            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13385        }
13386
13387        // Add to the sticky list if requested.
13388        if (sticky) {
13389            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13390                    callingPid, callingUid)
13391                    != PackageManager.PERMISSION_GRANTED) {
13392                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13393                        + callingPid + ", uid=" + callingUid
13394                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13395                Slog.w(TAG, msg);
13396                throw new SecurityException(msg);
13397            }
13398            if (requiredPermission != null) {
13399                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13400                        + " and enforce permission " + requiredPermission);
13401                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13402            }
13403            if (intent.getComponent() != null) {
13404                throw new SecurityException(
13405                        "Sticky broadcasts can't target a specific component");
13406            }
13407            // We use userId directly here, since the "all" target is maintained
13408            // as a separate set of sticky broadcasts.
13409            if (userId != UserHandle.USER_ALL) {
13410                // But first, if this is not a broadcast to all users, then
13411                // make sure it doesn't conflict with an existing broadcast to
13412                // all users.
13413                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13414                        UserHandle.USER_ALL);
13415                if (stickies != null) {
13416                    ArrayList<Intent> list = stickies.get(intent.getAction());
13417                    if (list != null) {
13418                        int N = list.size();
13419                        int i;
13420                        for (i=0; i<N; i++) {
13421                            if (intent.filterEquals(list.get(i))) {
13422                                throw new IllegalArgumentException(
13423                                        "Sticky broadcast " + intent + " for user "
13424                                        + userId + " conflicts with existing global broadcast");
13425                            }
13426                        }
13427                    }
13428                }
13429            }
13430            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13431            if (stickies == null) {
13432                stickies = new ArrayMap<String, ArrayList<Intent>>();
13433                mStickyBroadcasts.put(userId, stickies);
13434            }
13435            ArrayList<Intent> list = stickies.get(intent.getAction());
13436            if (list == null) {
13437                list = new ArrayList<Intent>();
13438                stickies.put(intent.getAction(), list);
13439            }
13440            int N = list.size();
13441            int i;
13442            for (i=0; i<N; i++) {
13443                if (intent.filterEquals(list.get(i))) {
13444                    // This sticky already exists, replace it.
13445                    list.set(i, new Intent(intent));
13446                    break;
13447                }
13448            }
13449            if (i >= N) {
13450                list.add(new Intent(intent));
13451            }
13452        }
13453
13454        int[] users;
13455        if (userId == UserHandle.USER_ALL) {
13456            // Caller wants broadcast to go to all started users.
13457            users = mStartedUserArray;
13458        } else {
13459            // Caller wants broadcast to go to one specific user.
13460            users = new int[] {userId};
13461        }
13462
13463        // Figure out who all will receive this broadcast.
13464        List receivers = null;
13465        List<BroadcastFilter> registeredReceivers = null;
13466        // Need to resolve the intent to interested receivers...
13467        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13468                 == 0) {
13469            receivers = collectReceiverComponents(intent, resolvedType, users);
13470        }
13471        if (intent.getComponent() == null) {
13472            registeredReceivers = mReceiverResolver.queryIntent(intent,
13473                    resolvedType, false, userId);
13474        }
13475
13476        final boolean replacePending =
13477                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13478
13479        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13480                + " replacePending=" + replacePending);
13481
13482        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13483        if (!ordered && NR > 0) {
13484            // If we are not serializing this broadcast, then send the
13485            // registered receivers separately so they don't wait for the
13486            // components to be launched.
13487            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13488            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13489                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13490                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13491                    ordered, sticky, false, userId);
13492            if (DEBUG_BROADCAST) Slog.v(
13493                    TAG, "Enqueueing parallel broadcast " + r);
13494            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13495            if (!replaced) {
13496                queue.enqueueParallelBroadcastLocked(r);
13497                queue.scheduleBroadcastsLocked();
13498            }
13499            registeredReceivers = null;
13500            NR = 0;
13501        }
13502
13503        // Merge into one list.
13504        int ir = 0;
13505        if (receivers != null) {
13506            // A special case for PACKAGE_ADDED: do not allow the package
13507            // being added to see this broadcast.  This prevents them from
13508            // using this as a back door to get run as soon as they are
13509            // installed.  Maybe in the future we want to have a special install
13510            // broadcast or such for apps, but we'd like to deliberately make
13511            // this decision.
13512            String skipPackages[] = null;
13513            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13514                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13515                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13516                Uri data = intent.getData();
13517                if (data != null) {
13518                    String pkgName = data.getSchemeSpecificPart();
13519                    if (pkgName != null) {
13520                        skipPackages = new String[] { pkgName };
13521                    }
13522                }
13523            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13524                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13525            }
13526            if (skipPackages != null && (skipPackages.length > 0)) {
13527                for (String skipPackage : skipPackages) {
13528                    if (skipPackage != null) {
13529                        int NT = receivers.size();
13530                        for (int it=0; it<NT; it++) {
13531                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13532                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13533                                receivers.remove(it);
13534                                it--;
13535                                NT--;
13536                            }
13537                        }
13538                    }
13539                }
13540            }
13541
13542            int NT = receivers != null ? receivers.size() : 0;
13543            int it = 0;
13544            ResolveInfo curt = null;
13545            BroadcastFilter curr = null;
13546            while (it < NT && ir < NR) {
13547                if (curt == null) {
13548                    curt = (ResolveInfo)receivers.get(it);
13549                }
13550                if (curr == null) {
13551                    curr = registeredReceivers.get(ir);
13552                }
13553                if (curr.getPriority() >= curt.priority) {
13554                    // Insert this broadcast record into the final list.
13555                    receivers.add(it, curr);
13556                    ir++;
13557                    curr = null;
13558                    it++;
13559                    NT++;
13560                } else {
13561                    // Skip to the next ResolveInfo in the final list.
13562                    it++;
13563                    curt = null;
13564                }
13565            }
13566        }
13567        while (ir < NR) {
13568            if (receivers == null) {
13569                receivers = new ArrayList();
13570            }
13571            receivers.add(registeredReceivers.get(ir));
13572            ir++;
13573        }
13574
13575        if ((receivers != null && receivers.size() > 0)
13576                || resultTo != null) {
13577            BroadcastQueue queue = broadcastQueueForIntent(intent);
13578            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13579                    callerPackage, callingPid, callingUid, resolvedType,
13580                    requiredPermission, appOp, receivers, resultTo, resultCode,
13581                    resultData, map, ordered, sticky, false, userId);
13582            if (DEBUG_BROADCAST) Slog.v(
13583                    TAG, "Enqueueing ordered broadcast " + r
13584                    + ": prev had " + queue.mOrderedBroadcasts.size());
13585            if (DEBUG_BROADCAST) {
13586                int seq = r.intent.getIntExtra("seq", -1);
13587                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13588            }
13589            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13590            if (!replaced) {
13591                queue.enqueueOrderedBroadcastLocked(r);
13592                queue.scheduleBroadcastsLocked();
13593            }
13594        }
13595
13596        return ActivityManager.BROADCAST_SUCCESS;
13597    }
13598
13599    final Intent verifyBroadcastLocked(Intent intent) {
13600        // Refuse possible leaked file descriptors
13601        if (intent != null && intent.hasFileDescriptors() == true) {
13602            throw new IllegalArgumentException("File descriptors passed in Intent");
13603        }
13604
13605        int flags = intent.getFlags();
13606
13607        if (!mProcessesReady) {
13608            // if the caller really truly claims to know what they're doing, go
13609            // ahead and allow the broadcast without launching any receivers
13610            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13611                intent = new Intent(intent);
13612                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13613            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13614                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13615                        + " before boot completion");
13616                throw new IllegalStateException("Cannot broadcast before boot completed");
13617            }
13618        }
13619
13620        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13621            throw new IllegalArgumentException(
13622                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13623        }
13624
13625        return intent;
13626    }
13627
13628    public final int broadcastIntent(IApplicationThread caller,
13629            Intent intent, String resolvedType, IIntentReceiver resultTo,
13630            int resultCode, String resultData, Bundle map,
13631            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13632        enforceNotIsolatedCaller("broadcastIntent");
13633        synchronized(this) {
13634            intent = verifyBroadcastLocked(intent);
13635
13636            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13637            final int callingPid = Binder.getCallingPid();
13638            final int callingUid = Binder.getCallingUid();
13639            final long origId = Binder.clearCallingIdentity();
13640            int res = broadcastIntentLocked(callerApp,
13641                    callerApp != null ? callerApp.info.packageName : null,
13642                    intent, resolvedType, resultTo,
13643                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13644                    callingPid, callingUid, userId);
13645            Binder.restoreCallingIdentity(origId);
13646            return res;
13647        }
13648    }
13649
13650    int broadcastIntentInPackage(String packageName, int uid,
13651            Intent intent, String resolvedType, IIntentReceiver resultTo,
13652            int resultCode, String resultData, Bundle map,
13653            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13654        synchronized(this) {
13655            intent = verifyBroadcastLocked(intent);
13656
13657            final long origId = Binder.clearCallingIdentity();
13658            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13659                    resultTo, resultCode, resultData, map, requiredPermission,
13660                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13661            Binder.restoreCallingIdentity(origId);
13662            return res;
13663        }
13664    }
13665
13666    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13667        // Refuse possible leaked file descriptors
13668        if (intent != null && intent.hasFileDescriptors() == true) {
13669            throw new IllegalArgumentException("File descriptors passed in Intent");
13670        }
13671
13672        userId = handleIncomingUser(Binder.getCallingPid(),
13673                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13674
13675        synchronized(this) {
13676            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13677                    != PackageManager.PERMISSION_GRANTED) {
13678                String msg = "Permission Denial: unbroadcastIntent() from pid="
13679                        + Binder.getCallingPid()
13680                        + ", uid=" + Binder.getCallingUid()
13681                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13682                Slog.w(TAG, msg);
13683                throw new SecurityException(msg);
13684            }
13685            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13686            if (stickies != null) {
13687                ArrayList<Intent> list = stickies.get(intent.getAction());
13688                if (list != null) {
13689                    int N = list.size();
13690                    int i;
13691                    for (i=0; i<N; i++) {
13692                        if (intent.filterEquals(list.get(i))) {
13693                            list.remove(i);
13694                            break;
13695                        }
13696                    }
13697                    if (list.size() <= 0) {
13698                        stickies.remove(intent.getAction());
13699                    }
13700                }
13701                if (stickies.size() <= 0) {
13702                    mStickyBroadcasts.remove(userId);
13703                }
13704            }
13705        }
13706    }
13707
13708    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13709            String resultData, Bundle resultExtras, boolean resultAbort) {
13710        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13711        if (r == null) {
13712            Slog.w(TAG, "finishReceiver called but not found on queue");
13713            return false;
13714        }
13715
13716        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13717    }
13718
13719    void backgroundServicesFinishedLocked(int userId) {
13720        for (BroadcastQueue queue : mBroadcastQueues) {
13721            queue.backgroundServicesFinishedLocked(userId);
13722        }
13723    }
13724
13725    public void finishReceiver(IBinder who, int resultCode, String resultData,
13726            Bundle resultExtras, boolean resultAbort) {
13727        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13728
13729        // Refuse possible leaked file descriptors
13730        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13731            throw new IllegalArgumentException("File descriptors passed in Bundle");
13732        }
13733
13734        final long origId = Binder.clearCallingIdentity();
13735        try {
13736            boolean doNext = false;
13737            BroadcastRecord r;
13738
13739            synchronized(this) {
13740                r = broadcastRecordForReceiverLocked(who);
13741                if (r != null) {
13742                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13743                        resultData, resultExtras, resultAbort, true);
13744                }
13745            }
13746
13747            if (doNext) {
13748                r.queue.processNextBroadcast(false);
13749            }
13750            trimApplications();
13751        } finally {
13752            Binder.restoreCallingIdentity(origId);
13753        }
13754    }
13755
13756    // =========================================================
13757    // INSTRUMENTATION
13758    // =========================================================
13759
13760    public boolean startInstrumentation(ComponentName className,
13761            String profileFile, int flags, Bundle arguments,
13762            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13763            int userId, String abiOverride) {
13764        enforceNotIsolatedCaller("startInstrumentation");
13765        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13766                userId, false, true, "startInstrumentation", null);
13767        // Refuse possible leaked file descriptors
13768        if (arguments != null && arguments.hasFileDescriptors()) {
13769            throw new IllegalArgumentException("File descriptors passed in Bundle");
13770        }
13771
13772        synchronized(this) {
13773            InstrumentationInfo ii = null;
13774            ApplicationInfo ai = null;
13775            try {
13776                ii = mContext.getPackageManager().getInstrumentationInfo(
13777                    className, STOCK_PM_FLAGS);
13778                ai = AppGlobals.getPackageManager().getApplicationInfo(
13779                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13780            } catch (PackageManager.NameNotFoundException e) {
13781            } catch (RemoteException e) {
13782            }
13783            if (ii == null) {
13784                reportStartInstrumentationFailure(watcher, className,
13785                        "Unable to find instrumentation info for: " + className);
13786                return false;
13787            }
13788            if (ai == null) {
13789                reportStartInstrumentationFailure(watcher, className,
13790                        "Unable to find instrumentation target package: " + ii.targetPackage);
13791                return false;
13792            }
13793
13794            int match = mContext.getPackageManager().checkSignatures(
13795                    ii.targetPackage, ii.packageName);
13796            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13797                String msg = "Permission Denial: starting instrumentation "
13798                        + className + " from pid="
13799                        + Binder.getCallingPid()
13800                        + ", uid=" + Binder.getCallingPid()
13801                        + " not allowed because package " + ii.packageName
13802                        + " does not have a signature matching the target "
13803                        + ii.targetPackage;
13804                reportStartInstrumentationFailure(watcher, className, msg);
13805                throw new SecurityException(msg);
13806            }
13807
13808            final long origId = Binder.clearCallingIdentity();
13809            // Instrumentation can kill and relaunch even persistent processes
13810            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId,
13811                    "start instr");
13812            ProcessRecord app = addAppLocked(ai, false, abiOverride);
13813            app.instrumentationClass = className;
13814            app.instrumentationInfo = ai;
13815            app.instrumentationProfileFile = profileFile;
13816            app.instrumentationArguments = arguments;
13817            app.instrumentationWatcher = watcher;
13818            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13819            app.instrumentationResultClass = className;
13820            Binder.restoreCallingIdentity(origId);
13821        }
13822
13823        return true;
13824    }
13825
13826    /**
13827     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13828     * error to the logs, but if somebody is watching, send the report there too.  This enables
13829     * the "am" command to report errors with more information.
13830     *
13831     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13832     * @param cn The component name of the instrumentation.
13833     * @param report The error report.
13834     */
13835    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13836            ComponentName cn, String report) {
13837        Slog.w(TAG, report);
13838        try {
13839            if (watcher != null) {
13840                Bundle results = new Bundle();
13841                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13842                results.putString("Error", report);
13843                watcher.instrumentationStatus(cn, -1, results);
13844            }
13845        } catch (RemoteException e) {
13846            Slog.w(TAG, e);
13847        }
13848    }
13849
13850    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13851        if (app.instrumentationWatcher != null) {
13852            try {
13853                // NOTE:  IInstrumentationWatcher *must* be oneway here
13854                app.instrumentationWatcher.instrumentationFinished(
13855                    app.instrumentationClass,
13856                    resultCode,
13857                    results);
13858            } catch (RemoteException e) {
13859            }
13860        }
13861        if (app.instrumentationUiAutomationConnection != null) {
13862            try {
13863                app.instrumentationUiAutomationConnection.shutdown();
13864            } catch (RemoteException re) {
13865                /* ignore */
13866            }
13867            // Only a UiAutomation can set this flag and now that
13868            // it is finished we make sure it is reset to its default.
13869            mUserIsMonkey = false;
13870        }
13871        app.instrumentationWatcher = null;
13872        app.instrumentationUiAutomationConnection = null;
13873        app.instrumentationClass = null;
13874        app.instrumentationInfo = null;
13875        app.instrumentationProfileFile = null;
13876        app.instrumentationArguments = null;
13877
13878        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId,
13879                "finished inst");
13880    }
13881
13882    public void finishInstrumentation(IApplicationThread target,
13883            int resultCode, Bundle results) {
13884        int userId = UserHandle.getCallingUserId();
13885        // Refuse possible leaked file descriptors
13886        if (results != null && results.hasFileDescriptors()) {
13887            throw new IllegalArgumentException("File descriptors passed in Intent");
13888        }
13889
13890        synchronized(this) {
13891            ProcessRecord app = getRecordForAppLocked(target);
13892            if (app == null) {
13893                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13894                return;
13895            }
13896            final long origId = Binder.clearCallingIdentity();
13897            finishInstrumentationLocked(app, resultCode, results);
13898            Binder.restoreCallingIdentity(origId);
13899        }
13900    }
13901
13902    // =========================================================
13903    // CONFIGURATION
13904    // =========================================================
13905
13906    public ConfigurationInfo getDeviceConfigurationInfo() {
13907        ConfigurationInfo config = new ConfigurationInfo();
13908        synchronized (this) {
13909            config.reqTouchScreen = mConfiguration.touchscreen;
13910            config.reqKeyboardType = mConfiguration.keyboard;
13911            config.reqNavigation = mConfiguration.navigation;
13912            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13913                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13914                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13915            }
13916            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13917                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13918                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13919            }
13920            config.reqGlEsVersion = GL_ES_VERSION;
13921        }
13922        return config;
13923    }
13924
13925    ActivityStack getFocusedStack() {
13926        return mStackSupervisor.getFocusedStack();
13927    }
13928
13929    public Configuration getConfiguration() {
13930        Configuration ci;
13931        synchronized(this) {
13932            ci = new Configuration(mConfiguration);
13933        }
13934        return ci;
13935    }
13936
13937    public void updatePersistentConfiguration(Configuration values) {
13938        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13939                "updateConfiguration()");
13940        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13941                "updateConfiguration()");
13942        if (values == null) {
13943            throw new NullPointerException("Configuration must not be null");
13944        }
13945
13946        synchronized(this) {
13947            final long origId = Binder.clearCallingIdentity();
13948            updateConfigurationLocked(values, null, true, false);
13949            Binder.restoreCallingIdentity(origId);
13950        }
13951    }
13952
13953    public void updateConfiguration(Configuration values) {
13954        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13955                "updateConfiguration()");
13956
13957        synchronized(this) {
13958            if (values == null && mWindowManager != null) {
13959                // sentinel: fetch the current configuration from the window manager
13960                values = mWindowManager.computeNewConfiguration();
13961            }
13962
13963            if (mWindowManager != null) {
13964                mProcessList.applyDisplaySize(mWindowManager);
13965            }
13966
13967            final long origId = Binder.clearCallingIdentity();
13968            if (values != null) {
13969                Settings.System.clearConfiguration(values);
13970            }
13971            updateConfigurationLocked(values, null, false, false);
13972            Binder.restoreCallingIdentity(origId);
13973        }
13974    }
13975
13976    /**
13977     * Do either or both things: (1) change the current configuration, and (2)
13978     * make sure the given activity is running with the (now) current
13979     * configuration.  Returns true if the activity has been left running, or
13980     * false if <var>starting</var> is being destroyed to match the new
13981     * configuration.
13982     * @param persistent TODO
13983     */
13984    boolean updateConfigurationLocked(Configuration values,
13985            ActivityRecord starting, boolean persistent, boolean initLocale) {
13986        int changes = 0;
13987
13988        if (values != null) {
13989            Configuration newConfig = new Configuration(mConfiguration);
13990            changes = newConfig.updateFrom(values);
13991            if (changes != 0) {
13992                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13993                    Slog.i(TAG, "Updating configuration to: " + values);
13994                }
13995
13996                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13997
13998                if (values.locale != null && !initLocale) {
13999                    saveLocaleLocked(values.locale,
14000                                     !values.locale.equals(mConfiguration.locale),
14001                                     values.userSetLocale);
14002                }
14003
14004                mConfigurationSeq++;
14005                if (mConfigurationSeq <= 0) {
14006                    mConfigurationSeq = 1;
14007                }
14008                newConfig.seq = mConfigurationSeq;
14009                mConfiguration = newConfig;
14010                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14011
14012                final Configuration configCopy = new Configuration(mConfiguration);
14013
14014                // TODO: If our config changes, should we auto dismiss any currently
14015                // showing dialogs?
14016                mShowDialogs = shouldShowDialogs(newConfig);
14017
14018                AttributeCache ac = AttributeCache.instance();
14019                if (ac != null) {
14020                    ac.updateConfiguration(configCopy);
14021                }
14022
14023                // Make sure all resources in our process are updated
14024                // right now, so that anyone who is going to retrieve
14025                // resource values after we return will be sure to get
14026                // the new ones.  This is especially important during
14027                // boot, where the first config change needs to guarantee
14028                // all resources have that config before following boot
14029                // code is executed.
14030                mSystemThread.applyConfigurationToResources(configCopy);
14031
14032                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14033                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14034                    msg.obj = new Configuration(configCopy);
14035                    mHandler.sendMessage(msg);
14036                }
14037
14038                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14039                    ProcessRecord app = mLruProcesses.get(i);
14040                    try {
14041                        if (app.thread != null) {
14042                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14043                                    + app.processName + " new config " + mConfiguration);
14044                            app.thread.scheduleConfigurationChanged(configCopy);
14045                        }
14046                    } catch (Exception e) {
14047                    }
14048                }
14049                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14050                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14051                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14052                        | Intent.FLAG_RECEIVER_FOREGROUND);
14053                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14054                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14055                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14056                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14057                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14058                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14059                    broadcastIntentLocked(null, null, intent,
14060                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14061                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14062                }
14063            }
14064        }
14065
14066        boolean kept = true;
14067        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14068        // mainStack is null during startup.
14069        if (mainStack != null) {
14070            if (changes != 0 && starting == null) {
14071                // If the configuration changed, and the caller is not already
14072                // in the process of starting an activity, then find the top
14073                // activity to check if its configuration needs to change.
14074                starting = mainStack.topRunningActivityLocked(null);
14075            }
14076
14077            if (starting != null) {
14078                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14079                // And we need to make sure at this point that all other activities
14080                // are made visible with the correct configuration.
14081                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14082            }
14083        }
14084
14085        if (values != null && mWindowManager != null) {
14086            mWindowManager.setNewConfiguration(mConfiguration);
14087        }
14088
14089        return kept;
14090    }
14091
14092    /**
14093     * Decide based on the configuration whether we should shouw the ANR,
14094     * crash, etc dialogs.  The idea is that if there is no affordnace to
14095     * press the on-screen buttons, we shouldn't show the dialog.
14096     *
14097     * A thought: SystemUI might also want to get told about this, the Power
14098     * dialog / global actions also might want different behaviors.
14099     */
14100    private static final boolean shouldShowDialogs(Configuration config) {
14101        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14102                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14103    }
14104
14105    /**
14106     * Save the locale.  You must be inside a synchronized (this) block.
14107     */
14108    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14109        if(isDiff) {
14110            SystemProperties.set("user.language", l.getLanguage());
14111            SystemProperties.set("user.region", l.getCountry());
14112        }
14113
14114        if(isPersist) {
14115            SystemProperties.set("persist.sys.language", l.getLanguage());
14116            SystemProperties.set("persist.sys.country", l.getCountry());
14117            SystemProperties.set("persist.sys.localevar", l.getVariant());
14118        }
14119    }
14120
14121    @Override
14122    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14123        ActivityRecord srec = ActivityRecord.forToken(token);
14124        return srec != null && srec.task.affinity != null &&
14125                srec.task.affinity.equals(destAffinity);
14126    }
14127
14128    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14129            Intent resultData) {
14130
14131        synchronized (this) {
14132            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14133            if (stack != null) {
14134                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14135            }
14136            return false;
14137        }
14138    }
14139
14140    public int getLaunchedFromUid(IBinder activityToken) {
14141        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14142        if (srec == null) {
14143            return -1;
14144        }
14145        return srec.launchedFromUid;
14146    }
14147
14148    public String getLaunchedFromPackage(IBinder activityToken) {
14149        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14150        if (srec == null) {
14151            return null;
14152        }
14153        return srec.launchedFromPackage;
14154    }
14155
14156    // =========================================================
14157    // LIFETIME MANAGEMENT
14158    // =========================================================
14159
14160    // Returns which broadcast queue the app is the current [or imminent] receiver
14161    // on, or 'null' if the app is not an active broadcast recipient.
14162    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14163        BroadcastRecord r = app.curReceiver;
14164        if (r != null) {
14165            return r.queue;
14166        }
14167
14168        // It's not the current receiver, but it might be starting up to become one
14169        synchronized (this) {
14170            for (BroadcastQueue queue : mBroadcastQueues) {
14171                r = queue.mPendingBroadcast;
14172                if (r != null && r.curApp == app) {
14173                    // found it; report which queue it's in
14174                    return queue;
14175                }
14176            }
14177        }
14178
14179        return null;
14180    }
14181
14182    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14183            boolean doingAll, long now) {
14184        if (mAdjSeq == app.adjSeq) {
14185            // This adjustment has already been computed.
14186            return app.curRawAdj;
14187        }
14188
14189        if (app.thread == null) {
14190            app.adjSeq = mAdjSeq;
14191            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14192            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14193            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14194        }
14195
14196        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14197        app.adjSource = null;
14198        app.adjTarget = null;
14199        app.empty = false;
14200        app.cached = false;
14201
14202        final int activitiesSize = app.activities.size();
14203
14204        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14205            // The max adjustment doesn't allow this app to be anything
14206            // below foreground, so it is not worth doing work for it.
14207            app.adjType = "fixed";
14208            app.adjSeq = mAdjSeq;
14209            app.curRawAdj = app.maxAdj;
14210            app.foregroundActivities = false;
14211            app.keeping = true;
14212            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14213            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14214            // System process can do UI, and when they do we want to have
14215            // them trim their memory after the user leaves the UI.  To
14216            // facilitate this, here we need to determine whether or not it
14217            // is currently showing UI.
14218            app.systemNoUi = true;
14219            if (app == TOP_APP) {
14220                app.systemNoUi = false;
14221            } else if (activitiesSize > 0) {
14222                for (int j = 0; j < activitiesSize; j++) {
14223                    final ActivityRecord r = app.activities.get(j);
14224                    if (r.visible) {
14225                        app.systemNoUi = false;
14226                    }
14227                }
14228            }
14229            if (!app.systemNoUi) {
14230                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14231            }
14232            return (app.curAdj=app.maxAdj);
14233        }
14234
14235        app.keeping = false;
14236        app.systemNoUi = false;
14237
14238        // Determine the importance of the process, starting with most
14239        // important to least, and assign an appropriate OOM adjustment.
14240        int adj;
14241        int schedGroup;
14242        int procState;
14243        boolean foregroundActivities = false;
14244        boolean interesting = false;
14245        BroadcastQueue queue;
14246        if (app == TOP_APP) {
14247            // The last app on the list is the foreground app.
14248            adj = ProcessList.FOREGROUND_APP_ADJ;
14249            schedGroup = Process.THREAD_GROUP_DEFAULT;
14250            app.adjType = "top-activity";
14251            foregroundActivities = true;
14252            interesting = true;
14253            procState = ActivityManager.PROCESS_STATE_TOP;
14254        } else if (app.instrumentationClass != null) {
14255            // Don't want to kill running instrumentation.
14256            adj = ProcessList.FOREGROUND_APP_ADJ;
14257            schedGroup = Process.THREAD_GROUP_DEFAULT;
14258            app.adjType = "instrumentation";
14259            interesting = true;
14260            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14261        } else if ((queue = isReceivingBroadcast(app)) != null) {
14262            // An app that is currently receiving a broadcast also
14263            // counts as being in the foreground for OOM killer purposes.
14264            // It's placed in a sched group based on the nature of the
14265            // broadcast as reflected by which queue it's active in.
14266            adj = ProcessList.FOREGROUND_APP_ADJ;
14267            schedGroup = (queue == mFgBroadcastQueue)
14268                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14269            app.adjType = "broadcast";
14270            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14271        } else if (app.executingServices.size() > 0) {
14272            // An app that is currently executing a service callback also
14273            // counts as being in the foreground.
14274            adj = ProcessList.FOREGROUND_APP_ADJ;
14275            schedGroup = app.execServicesFg ?
14276                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14277            app.adjType = "exec-service";
14278            procState = ActivityManager.PROCESS_STATE_SERVICE;
14279            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14280        } else {
14281            // As far as we know the process is empty.  We may change our mind later.
14282            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14283            // At this point we don't actually know the adjustment.  Use the cached adj
14284            // value that the caller wants us to.
14285            adj = cachedAdj;
14286            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14287            app.cached = true;
14288            app.empty = true;
14289            app.adjType = "cch-empty";
14290        }
14291
14292        // Examine all activities if not already foreground.
14293        if (!foregroundActivities && activitiesSize > 0) {
14294            for (int j = 0; j < activitiesSize; j++) {
14295                final ActivityRecord r = app.activities.get(j);
14296                if (r.app != app) {
14297                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14298                            + app + "?!?");
14299                    continue;
14300                }
14301                if (r.visible) {
14302                    // App has a visible activity; only upgrade adjustment.
14303                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14304                        adj = ProcessList.VISIBLE_APP_ADJ;
14305                        app.adjType = "visible";
14306                    }
14307                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14308                        procState = ActivityManager.PROCESS_STATE_TOP;
14309                    }
14310                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14311                    app.cached = false;
14312                    app.empty = false;
14313                    foregroundActivities = true;
14314                    break;
14315                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14316                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14317                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14318                        app.adjType = "pausing";
14319                    }
14320                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14321                        procState = ActivityManager.PROCESS_STATE_TOP;
14322                    }
14323                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14324                    app.cached = false;
14325                    app.empty = false;
14326                    foregroundActivities = true;
14327                } else if (r.state == ActivityState.STOPPING) {
14328                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14329                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14330                        app.adjType = "stopping";
14331                    }
14332                    // For the process state, we will at this point consider the
14333                    // process to be cached.  It will be cached either as an activity
14334                    // or empty depending on whether the activity is finishing.  We do
14335                    // this so that we can treat the process as cached for purposes of
14336                    // memory trimming (determing current memory level, trim command to
14337                    // send to process) since there can be an arbitrary number of stopping
14338                    // processes and they should soon all go into the cached state.
14339                    if (!r.finishing) {
14340                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14341                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14342                        }
14343                    }
14344                    app.cached = false;
14345                    app.empty = false;
14346                    foregroundActivities = true;
14347                } else {
14348                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14349                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14350                        app.adjType = "cch-act";
14351                    }
14352                }
14353            }
14354        }
14355
14356        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14357            if (app.foregroundServices) {
14358                // The user is aware of this app, so make it visible.
14359                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14360                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14361                app.cached = false;
14362                app.adjType = "fg-service";
14363                schedGroup = Process.THREAD_GROUP_DEFAULT;
14364            } else if (app.forcingToForeground != null) {
14365                // The user is aware of this app, so make it visible.
14366                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14367                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14368                app.cached = false;
14369                app.adjType = "force-fg";
14370                app.adjSource = app.forcingToForeground;
14371                schedGroup = Process.THREAD_GROUP_DEFAULT;
14372            }
14373        }
14374
14375        if (app.foregroundServices) {
14376            interesting = true;
14377        }
14378
14379        if (app == mHeavyWeightProcess) {
14380            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14381                // We don't want to kill the current heavy-weight process.
14382                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14383                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14384                app.cached = false;
14385                app.adjType = "heavy";
14386            }
14387            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14388                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14389            }
14390        }
14391
14392        if (app == mHomeProcess) {
14393            if (adj > ProcessList.HOME_APP_ADJ) {
14394                // This process is hosting what we currently consider to be the
14395                // home app, so we don't want to let it go into the background.
14396                adj = ProcessList.HOME_APP_ADJ;
14397                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14398                app.cached = false;
14399                app.adjType = "home";
14400            }
14401            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14402                procState = ActivityManager.PROCESS_STATE_HOME;
14403            }
14404        }
14405
14406        if (app == mPreviousProcess && app.activities.size() > 0) {
14407            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14408                // This was the previous process that showed UI to the user.
14409                // We want to try to keep it around more aggressively, to give
14410                // a good experience around switching between two apps.
14411                adj = ProcessList.PREVIOUS_APP_ADJ;
14412                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14413                app.cached = false;
14414                app.adjType = "previous";
14415            }
14416            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14417                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14418            }
14419        }
14420
14421        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14422                + " reason=" + app.adjType);
14423
14424        // By default, we use the computed adjustment.  It may be changed if
14425        // there are applications dependent on our services or providers, but
14426        // this gives us a baseline and makes sure we don't get into an
14427        // infinite recursion.
14428        app.adjSeq = mAdjSeq;
14429        app.curRawAdj = adj;
14430        app.hasStartedServices = false;
14431
14432        if (mBackupTarget != null && app == mBackupTarget.app) {
14433            // If possible we want to avoid killing apps while they're being backed up
14434            if (adj > ProcessList.BACKUP_APP_ADJ) {
14435                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14436                adj = ProcessList.BACKUP_APP_ADJ;
14437                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14438                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14439                }
14440                app.adjType = "backup";
14441                app.cached = false;
14442            }
14443            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14444                procState = ActivityManager.PROCESS_STATE_BACKUP;
14445            }
14446        }
14447
14448        boolean mayBeTop = false;
14449
14450        for (int is = app.services.size()-1;
14451                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14452                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14453                        || procState > ActivityManager.PROCESS_STATE_TOP);
14454                is--) {
14455            ServiceRecord s = app.services.valueAt(is);
14456            if (s.startRequested) {
14457                app.hasStartedServices = true;
14458                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14459                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14460                }
14461                if (app.hasShownUi && app != mHomeProcess) {
14462                    // If this process has shown some UI, let it immediately
14463                    // go to the LRU list because it may be pretty heavy with
14464                    // UI stuff.  We'll tag it with a label just to help
14465                    // debug and understand what is going on.
14466                    if (adj > ProcessList.SERVICE_ADJ) {
14467                        app.adjType = "cch-started-ui-services";
14468                    }
14469                } else {
14470                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14471                        // This service has seen some activity within
14472                        // recent memory, so we will keep its process ahead
14473                        // of the background processes.
14474                        if (adj > ProcessList.SERVICE_ADJ) {
14475                            adj = ProcessList.SERVICE_ADJ;
14476                            app.adjType = "started-services";
14477                            app.cached = false;
14478                        }
14479                    }
14480                    // If we have let the service slide into the background
14481                    // state, still have some text describing what it is doing
14482                    // even though the service no longer has an impact.
14483                    if (adj > ProcessList.SERVICE_ADJ) {
14484                        app.adjType = "cch-started-services";
14485                    }
14486                }
14487                // Don't kill this process because it is doing work; it
14488                // has said it is doing work.
14489                app.keeping = true;
14490            }
14491            for (int conni = s.connections.size()-1;
14492                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14493                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14494                            || procState > ActivityManager.PROCESS_STATE_TOP);
14495                    conni--) {
14496                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14497                for (int i = 0;
14498                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14499                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14500                                || procState > ActivityManager.PROCESS_STATE_TOP);
14501                        i++) {
14502                    // XXX should compute this based on the max of
14503                    // all connected clients.
14504                    ConnectionRecord cr = clist.get(i);
14505                    if (cr.binding.client == app) {
14506                        // Binding to ourself is not interesting.
14507                        continue;
14508                    }
14509                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14510                        ProcessRecord client = cr.binding.client;
14511                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14512                                TOP_APP, doingAll, now);
14513                        int clientProcState = client.curProcState;
14514                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14515                            // If the other app is cached for any reason, for purposes here
14516                            // we are going to consider it empty.  The specific cached state
14517                            // doesn't propagate except under certain conditions.
14518                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14519                        }
14520                        String adjType = null;
14521                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14522                            // Not doing bind OOM management, so treat
14523                            // this guy more like a started service.
14524                            if (app.hasShownUi && app != mHomeProcess) {
14525                                // If this process has shown some UI, let it immediately
14526                                // go to the LRU list because it may be pretty heavy with
14527                                // UI stuff.  We'll tag it with a label just to help
14528                                // debug and understand what is going on.
14529                                if (adj > clientAdj) {
14530                                    adjType = "cch-bound-ui-services";
14531                                }
14532                                app.cached = false;
14533                                clientAdj = adj;
14534                                clientProcState = procState;
14535                            } else {
14536                                if (now >= (s.lastActivity
14537                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14538                                    // This service has not seen activity within
14539                                    // recent memory, so allow it to drop to the
14540                                    // LRU list if there is no other reason to keep
14541                                    // it around.  We'll also tag it with a label just
14542                                    // to help debug and undertand what is going on.
14543                                    if (adj > clientAdj) {
14544                                        adjType = "cch-bound-services";
14545                                    }
14546                                    clientAdj = adj;
14547                                }
14548                            }
14549                        }
14550                        if (adj > clientAdj) {
14551                            // If this process has recently shown UI, and
14552                            // the process that is binding to it is less
14553                            // important than being visible, then we don't
14554                            // care about the binding as much as we care
14555                            // about letting this process get into the LRU
14556                            // list to be killed and restarted if needed for
14557                            // memory.
14558                            if (app.hasShownUi && app != mHomeProcess
14559                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14560                                adjType = "cch-bound-ui-services";
14561                            } else {
14562                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14563                                        |Context.BIND_IMPORTANT)) != 0) {
14564                                    adj = clientAdj;
14565                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14566                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14567                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14568                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14569                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14570                                    adj = clientAdj;
14571                                } else {
14572                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14573                                        adj = ProcessList.VISIBLE_APP_ADJ;
14574                                    }
14575                                }
14576                                if (!client.cached) {
14577                                    app.cached = false;
14578                                }
14579                                if (client.keeping) {
14580                                    app.keeping = true;
14581                                }
14582                                adjType = "service";
14583                            }
14584                        }
14585                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14586                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14587                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14588                            }
14589                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14590                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14591                                    // Special handling of clients who are in the top state.
14592                                    // We *may* want to consider this process to be in the
14593                                    // top state as well, but only if there is not another
14594                                    // reason for it to be running.  Being on the top is a
14595                                    // special state, meaning you are specifically running
14596                                    // for the current top app.  If the process is already
14597                                    // running in the background for some other reason, it
14598                                    // is more important to continue considering it to be
14599                                    // in the background state.
14600                                    mayBeTop = true;
14601                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14602                                } else {
14603                                    // Special handling for above-top states (persistent
14604                                    // processes).  These should not bring the current process
14605                                    // into the top state, since they are not on top.  Instead
14606                                    // give them the best state after that.
14607                                    clientProcState =
14608                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14609                                }
14610                            }
14611                        } else {
14612                            if (clientProcState <
14613                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14614                                clientProcState =
14615                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14616                            }
14617                        }
14618                        if (procState > clientProcState) {
14619                            procState = clientProcState;
14620                        }
14621                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14622                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14623                            app.pendingUiClean = true;
14624                        }
14625                        if (adjType != null) {
14626                            app.adjType = adjType;
14627                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14628                                    .REASON_SERVICE_IN_USE;
14629                            app.adjSource = cr.binding.client;
14630                            app.adjSourceOom = clientAdj;
14631                            app.adjTarget = s.name;
14632                        }
14633                    }
14634                    final ActivityRecord a = cr.activity;
14635                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14636                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14637                                (a.visible || a.state == ActivityState.RESUMED
14638                                 || a.state == ActivityState.PAUSING)) {
14639                            adj = ProcessList.FOREGROUND_APP_ADJ;
14640                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14641                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14642                            }
14643                            app.cached = false;
14644                            app.adjType = "service";
14645                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14646                                    .REASON_SERVICE_IN_USE;
14647                            app.adjSource = a;
14648                            app.adjSourceOom = adj;
14649                            app.adjTarget = s.name;
14650                        }
14651                    }
14652                }
14653            }
14654        }
14655
14656        for (int provi = app.pubProviders.size()-1;
14657                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14658                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14659                        || procState > ActivityManager.PROCESS_STATE_TOP);
14660                provi--) {
14661            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14662            for (int i = cpr.connections.size()-1;
14663                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14664                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14665                            || procState > ActivityManager.PROCESS_STATE_TOP);
14666                    i--) {
14667                ContentProviderConnection conn = cpr.connections.get(i);
14668                ProcessRecord client = conn.client;
14669                if (client == app) {
14670                    // Being our own client is not interesting.
14671                    continue;
14672                }
14673                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14674                int clientProcState = client.curProcState;
14675                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14676                    // If the other app is cached for any reason, for purposes here
14677                    // we are going to consider it empty.
14678                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14679                }
14680                if (adj > clientAdj) {
14681                    if (app.hasShownUi && app != mHomeProcess
14682                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14683                        app.adjType = "cch-ui-provider";
14684                    } else {
14685                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14686                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14687                        app.adjType = "provider";
14688                    }
14689                    app.cached &= client.cached;
14690                    app.keeping |= client.keeping;
14691                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14692                            .REASON_PROVIDER_IN_USE;
14693                    app.adjSource = client;
14694                    app.adjSourceOom = clientAdj;
14695                    app.adjTarget = cpr.name;
14696                }
14697                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14698                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14699                        // Special handling of clients who are in the top state.
14700                        // We *may* want to consider this process to be in the
14701                        // top state as well, but only if there is not another
14702                        // reason for it to be running.  Being on the top is a
14703                        // special state, meaning you are specifically running
14704                        // for the current top app.  If the process is already
14705                        // running in the background for some other reason, it
14706                        // is more important to continue considering it to be
14707                        // in the background state.
14708                        mayBeTop = true;
14709                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14710                    } else {
14711                        // Special handling for above-top states (persistent
14712                        // processes).  These should not bring the current process
14713                        // into the top state, since they are not on top.  Instead
14714                        // give them the best state after that.
14715                        clientProcState =
14716                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14717                    }
14718                }
14719                if (procState > clientProcState) {
14720                    procState = clientProcState;
14721                }
14722                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14723                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14724                }
14725            }
14726            // If the provider has external (non-framework) process
14727            // dependencies, ensure that its adjustment is at least
14728            // FOREGROUND_APP_ADJ.
14729            if (cpr.hasExternalProcessHandles()) {
14730                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14731                    adj = ProcessList.FOREGROUND_APP_ADJ;
14732                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14733                    app.cached = false;
14734                    app.keeping = true;
14735                    app.adjType = "provider";
14736                    app.adjTarget = cpr.name;
14737                }
14738                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14739                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14740                }
14741            }
14742        }
14743
14744        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14745            // A client of one of our services or providers is in the top state.  We
14746            // *may* want to be in the top state, but not if we are already running in
14747            // the background for some other reason.  For the decision here, we are going
14748            // to pick out a few specific states that we want to remain in when a client
14749            // is top (states that tend to be longer-term) and otherwise allow it to go
14750            // to the top state.
14751            switch (procState) {
14752                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14753                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14754                case ActivityManager.PROCESS_STATE_SERVICE:
14755                    // These all are longer-term states, so pull them up to the top
14756                    // of the background states, but not all the way to the top state.
14757                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14758                    break;
14759                default:
14760                    // Otherwise, top is a better choice, so take it.
14761                    procState = ActivityManager.PROCESS_STATE_TOP;
14762                    break;
14763            }
14764        }
14765
14766        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14767            // This is a cached process, but with client activities.  Mark it so.
14768            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14769            app.adjType = "cch-client-act";
14770        }
14771
14772        if (adj == ProcessList.SERVICE_ADJ) {
14773            if (doingAll) {
14774                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14775                mNewNumServiceProcs++;
14776                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14777                if (!app.serviceb) {
14778                    // This service isn't far enough down on the LRU list to
14779                    // normally be a B service, but if we are low on RAM and it
14780                    // is large we want to force it down since we would prefer to
14781                    // keep launcher over it.
14782                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14783                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14784                        app.serviceHighRam = true;
14785                        app.serviceb = true;
14786                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14787                    } else {
14788                        mNewNumAServiceProcs++;
14789                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14790                    }
14791                } else {
14792                    app.serviceHighRam = false;
14793                }
14794            }
14795            if (app.serviceb) {
14796                adj = ProcessList.SERVICE_B_ADJ;
14797            }
14798        }
14799
14800        app.curRawAdj = adj;
14801
14802        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14803        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14804        if (adj > app.maxAdj) {
14805            adj = app.maxAdj;
14806            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14807                schedGroup = Process.THREAD_GROUP_DEFAULT;
14808            }
14809        }
14810        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14811            app.keeping = true;
14812        }
14813
14814        // Do final modification to adj.  Everything we do between here and applying
14815        // the final setAdj must be done in this function, because we will also use
14816        // it when computing the final cached adj later.  Note that we don't need to
14817        // worry about this for max adj above, since max adj will always be used to
14818        // keep it out of the cached vaues.
14819        adj = app.modifyRawOomAdj(adj);
14820
14821        app.curProcState = procState;
14822
14823        int importance = app.memImportance;
14824        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14825            app.curAdj = adj;
14826            app.curSchedGroup = schedGroup;
14827            if (!interesting) {
14828                // For this reporting, if there is not something explicitly
14829                // interesting in this process then we will push it to the
14830                // background importance.
14831                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14832            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14833                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14834            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14835                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14836            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14837                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14838            } else if (adj >= ProcessList.SERVICE_ADJ) {
14839                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14840            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14841                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14842            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14843                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14844            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14845                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14846            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14847                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14848            } else {
14849                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14850            }
14851        }
14852
14853        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14854        if (foregroundActivities != app.foregroundActivities) {
14855            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14856        }
14857        if (changes != 0) {
14858            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14859            app.memImportance = importance;
14860            app.foregroundActivities = foregroundActivities;
14861            int i = mPendingProcessChanges.size()-1;
14862            ProcessChangeItem item = null;
14863            while (i >= 0) {
14864                item = mPendingProcessChanges.get(i);
14865                if (item.pid == app.pid) {
14866                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14867                    break;
14868                }
14869                i--;
14870            }
14871            if (i < 0) {
14872                // No existing item in pending changes; need a new one.
14873                final int NA = mAvailProcessChanges.size();
14874                if (NA > 0) {
14875                    item = mAvailProcessChanges.remove(NA-1);
14876                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14877                } else {
14878                    item = new ProcessChangeItem();
14879                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14880                }
14881                item.changes = 0;
14882                item.pid = app.pid;
14883                item.uid = app.info.uid;
14884                if (mPendingProcessChanges.size() == 0) {
14885                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14886                            "*** Enqueueing dispatch processes changed!");
14887                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14888                }
14889                mPendingProcessChanges.add(item);
14890            }
14891            item.changes |= changes;
14892            item.importance = importance;
14893            item.foregroundActivities = foregroundActivities;
14894            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14895                    + Integer.toHexString(System.identityHashCode(item))
14896                    + " " + app.toShortString() + ": changes=" + item.changes
14897                    + " importance=" + item.importance
14898                    + " foreground=" + item.foregroundActivities
14899                    + " type=" + app.adjType + " source=" + app.adjSource
14900                    + " target=" + app.adjTarget);
14901        }
14902
14903        return app.curRawAdj;
14904    }
14905
14906    /**
14907     * Schedule PSS collection of a process.
14908     */
14909    void requestPssLocked(ProcessRecord proc, int procState) {
14910        if (mPendingPssProcesses.contains(proc)) {
14911            return;
14912        }
14913        if (mPendingPssProcesses.size() == 0) {
14914            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14915        }
14916        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
14917        proc.pssProcState = procState;
14918        mPendingPssProcesses.add(proc);
14919    }
14920
14921    /**
14922     * Schedule PSS collection of all processes.
14923     */
14924    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
14925        if (!always) {
14926            if (now < (mLastFullPssTime +
14927                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
14928                return;
14929            }
14930        }
14931        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
14932        mLastFullPssTime = now;
14933        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
14934        mPendingPssProcesses.clear();
14935        for (int i=mLruProcesses.size()-1; i>=0; i--) {
14936            ProcessRecord app = mLruProcesses.get(i);
14937            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
14938                app.pssProcState = app.setProcState;
14939                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
14940                        mSleeping, now);
14941                mPendingPssProcesses.add(app);
14942            }
14943        }
14944        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14945    }
14946
14947    /**
14948     * Ask a given process to GC right now.
14949     */
14950    final void performAppGcLocked(ProcessRecord app) {
14951        try {
14952            app.lastRequestedGc = SystemClock.uptimeMillis();
14953            if (app.thread != null) {
14954                if (app.reportLowMemory) {
14955                    app.reportLowMemory = false;
14956                    app.thread.scheduleLowMemory();
14957                } else {
14958                    app.thread.processInBackground();
14959                }
14960            }
14961        } catch (Exception e) {
14962            // whatever.
14963        }
14964    }
14965
14966    /**
14967     * Returns true if things are idle enough to perform GCs.
14968     */
14969    private final boolean canGcNowLocked() {
14970        boolean processingBroadcasts = false;
14971        for (BroadcastQueue q : mBroadcastQueues) {
14972            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14973                processingBroadcasts = true;
14974            }
14975        }
14976        return !processingBroadcasts
14977                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
14978    }
14979
14980    /**
14981     * Perform GCs on all processes that are waiting for it, but only
14982     * if things are idle.
14983     */
14984    final void performAppGcsLocked() {
14985        final int N = mProcessesToGc.size();
14986        if (N <= 0) {
14987            return;
14988        }
14989        if (canGcNowLocked()) {
14990            while (mProcessesToGc.size() > 0) {
14991                ProcessRecord proc = mProcessesToGc.remove(0);
14992                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
14993                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14994                            <= SystemClock.uptimeMillis()) {
14995                        // To avoid spamming the system, we will GC processes one
14996                        // at a time, waiting a few seconds between each.
14997                        performAppGcLocked(proc);
14998                        scheduleAppGcsLocked();
14999                        return;
15000                    } else {
15001                        // It hasn't been long enough since we last GCed this
15002                        // process...  put it in the list to wait for its time.
15003                        addProcessToGcListLocked(proc);
15004                        break;
15005                    }
15006                }
15007            }
15008
15009            scheduleAppGcsLocked();
15010        }
15011    }
15012
15013    /**
15014     * If all looks good, perform GCs on all processes waiting for them.
15015     */
15016    final void performAppGcsIfAppropriateLocked() {
15017        if (canGcNowLocked()) {
15018            performAppGcsLocked();
15019            return;
15020        }
15021        // Still not idle, wait some more.
15022        scheduleAppGcsLocked();
15023    }
15024
15025    /**
15026     * Schedule the execution of all pending app GCs.
15027     */
15028    final void scheduleAppGcsLocked() {
15029        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15030
15031        if (mProcessesToGc.size() > 0) {
15032            // Schedule a GC for the time to the next process.
15033            ProcessRecord proc = mProcessesToGc.get(0);
15034            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15035
15036            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15037            long now = SystemClock.uptimeMillis();
15038            if (when < (now+GC_TIMEOUT)) {
15039                when = now + GC_TIMEOUT;
15040            }
15041            mHandler.sendMessageAtTime(msg, when);
15042        }
15043    }
15044
15045    /**
15046     * Add a process to the array of processes waiting to be GCed.  Keeps the
15047     * list in sorted order by the last GC time.  The process can't already be
15048     * on the list.
15049     */
15050    final void addProcessToGcListLocked(ProcessRecord proc) {
15051        boolean added = false;
15052        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15053            if (mProcessesToGc.get(i).lastRequestedGc <
15054                    proc.lastRequestedGc) {
15055                added = true;
15056                mProcessesToGc.add(i+1, proc);
15057                break;
15058            }
15059        }
15060        if (!added) {
15061            mProcessesToGc.add(0, proc);
15062        }
15063    }
15064
15065    /**
15066     * Set up to ask a process to GC itself.  This will either do it
15067     * immediately, or put it on the list of processes to gc the next
15068     * time things are idle.
15069     */
15070    final void scheduleAppGcLocked(ProcessRecord app) {
15071        long now = SystemClock.uptimeMillis();
15072        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15073            return;
15074        }
15075        if (!mProcessesToGc.contains(app)) {
15076            addProcessToGcListLocked(app);
15077            scheduleAppGcsLocked();
15078        }
15079    }
15080
15081    final void checkExcessivePowerUsageLocked(boolean doKills) {
15082        updateCpuStatsNow();
15083
15084        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15085        boolean doWakeKills = doKills;
15086        boolean doCpuKills = doKills;
15087        if (mLastPowerCheckRealtime == 0) {
15088            doWakeKills = false;
15089        }
15090        if (mLastPowerCheckUptime == 0) {
15091            doCpuKills = false;
15092        }
15093        if (stats.isScreenOn()) {
15094            doWakeKills = false;
15095        }
15096        final long curRealtime = SystemClock.elapsedRealtime();
15097        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15098        final long curUptime = SystemClock.uptimeMillis();
15099        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15100        mLastPowerCheckRealtime = curRealtime;
15101        mLastPowerCheckUptime = curUptime;
15102        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15103            doWakeKills = false;
15104        }
15105        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15106            doCpuKills = false;
15107        }
15108        int i = mLruProcesses.size();
15109        while (i > 0) {
15110            i--;
15111            ProcessRecord app = mLruProcesses.get(i);
15112            if (!app.keeping) {
15113                long wtime;
15114                synchronized (stats) {
15115                    wtime = stats.getProcessWakeTime(app.info.uid,
15116                            app.pid, curRealtime);
15117                }
15118                long wtimeUsed = wtime - app.lastWakeTime;
15119                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15120                if (DEBUG_POWER) {
15121                    StringBuilder sb = new StringBuilder(128);
15122                    sb.append("Wake for ");
15123                    app.toShortString(sb);
15124                    sb.append(": over ");
15125                    TimeUtils.formatDuration(realtimeSince, sb);
15126                    sb.append(" used ");
15127                    TimeUtils.formatDuration(wtimeUsed, sb);
15128                    sb.append(" (");
15129                    sb.append((wtimeUsed*100)/realtimeSince);
15130                    sb.append("%)");
15131                    Slog.i(TAG, sb.toString());
15132                    sb.setLength(0);
15133                    sb.append("CPU for ");
15134                    app.toShortString(sb);
15135                    sb.append(": over ");
15136                    TimeUtils.formatDuration(uptimeSince, sb);
15137                    sb.append(" used ");
15138                    TimeUtils.formatDuration(cputimeUsed, sb);
15139                    sb.append(" (");
15140                    sb.append((cputimeUsed*100)/uptimeSince);
15141                    sb.append("%)");
15142                    Slog.i(TAG, sb.toString());
15143                }
15144                // If a process has held a wake lock for more
15145                // than 50% of the time during this period,
15146                // that sounds bad.  Kill!
15147                if (doWakeKills && realtimeSince > 0
15148                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15149                    synchronized (stats) {
15150                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15151                                realtimeSince, wtimeUsed);
15152                    }
15153                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15154                            + " during " + realtimeSince);
15155                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15156                } else if (doCpuKills && uptimeSince > 0
15157                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15158                    synchronized (stats) {
15159                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15160                                uptimeSince, cputimeUsed);
15161                    }
15162                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15163                            + " during " + uptimeSince);
15164                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15165                } else {
15166                    app.lastWakeTime = wtime;
15167                    app.lastCpuTime = app.curCpuTime;
15168                }
15169            }
15170        }
15171    }
15172
15173    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15174            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15175        boolean success = true;
15176
15177        if (app.curRawAdj != app.setRawAdj) {
15178            if (wasKeeping && !app.keeping) {
15179                // This app is no longer something we want to keep.  Note
15180                // its current wake lock time to later know to kill it if
15181                // it is not behaving well.
15182                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15183                synchronized (stats) {
15184                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15185                            app.pid, SystemClock.elapsedRealtime());
15186                }
15187                app.lastCpuTime = app.curCpuTime;
15188            }
15189
15190            app.setRawAdj = app.curRawAdj;
15191        }
15192
15193        if (app.curAdj != app.setAdj) {
15194            ProcessList.setOomAdj(app.pid, app.curAdj);
15195            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15196                TAG, "Set " + app.pid + " " + app.processName +
15197                " adj " + app.curAdj + ": " + app.adjType);
15198            app.setAdj = app.curAdj;
15199        }
15200
15201        if (app.setSchedGroup != app.curSchedGroup) {
15202            app.setSchedGroup = app.curSchedGroup;
15203            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15204                    "Setting process group of " + app.processName
15205                    + " to " + app.curSchedGroup);
15206            if (app.waitingToKill != null &&
15207                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15208                killUnneededProcessLocked(app, app.waitingToKill);
15209                success = false;
15210            } else {
15211                if (true) {
15212                    long oldId = Binder.clearCallingIdentity();
15213                    try {
15214                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15215                    } catch (Exception e) {
15216                        Slog.w(TAG, "Failed setting process group of " + app.pid
15217                                + " to " + app.curSchedGroup);
15218                        e.printStackTrace();
15219                    } finally {
15220                        Binder.restoreCallingIdentity(oldId);
15221                    }
15222                } else {
15223                    if (app.thread != null) {
15224                        try {
15225                            app.thread.setSchedulingGroup(app.curSchedGroup);
15226                        } catch (RemoteException e) {
15227                        }
15228                    }
15229                }
15230                Process.setSwappiness(app.pid,
15231                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15232            }
15233        }
15234        if (app.repProcState != app.curProcState) {
15235            app.repProcState = app.curProcState;
15236            if (!reportingProcessState && app.thread != null) {
15237                try {
15238                    if (false) {
15239                        //RuntimeException h = new RuntimeException("here");
15240                        Slog.i(TAG, "Sending new process state " + app.repProcState
15241                                + " to " + app /*, h*/);
15242                    }
15243                    app.thread.setProcessState(app.repProcState);
15244                } catch (RemoteException e) {
15245                }
15246            }
15247        }
15248        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15249                app.setProcState)) {
15250            app.lastStateTime = now;
15251            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15252                    mSleeping, now);
15253            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15254                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15255                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15256                    + (app.nextPssTime-now) + ": " + app);
15257        } else {
15258            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15259                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15260                requestPssLocked(app, app.setProcState);
15261                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15262                        mSleeping, now);
15263            } else if (false && DEBUG_PSS) {
15264                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15265            }
15266        }
15267        if (app.setProcState != app.curProcState) {
15268            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15269                    "Proc state change of " + app.processName
15270                    + " to " + app.curProcState);
15271            app.setProcState = app.curProcState;
15272            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15273                app.notCachedSinceIdle = false;
15274            }
15275            if (!doingAll) {
15276                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15277            } else {
15278                app.procStateChanged = true;
15279            }
15280        }
15281        return success;
15282    }
15283
15284    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15285        if (proc.thread != null && proc.baseProcessTracker != null) {
15286            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15287        }
15288    }
15289
15290    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15291            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15292        if (app.thread == null) {
15293            return false;
15294        }
15295
15296        final boolean wasKeeping = app.keeping;
15297
15298        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15299
15300        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15301                reportingProcessState, now);
15302    }
15303
15304    private final ActivityRecord resumedAppLocked() {
15305        return mStackSupervisor.resumedAppLocked();
15306    }
15307
15308    final boolean updateOomAdjLocked(ProcessRecord app) {
15309        return updateOomAdjLocked(app, false);
15310    }
15311
15312    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15313        final ActivityRecord TOP_ACT = resumedAppLocked();
15314        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15315        final boolean wasCached = app.cached;
15316
15317        mAdjSeq++;
15318
15319        // This is the desired cached adjusment we want to tell it to use.
15320        // If our app is currently cached, we know it, and that is it.  Otherwise,
15321        // we don't know it yet, and it needs to now be cached we will then
15322        // need to do a complete oom adj.
15323        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15324                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15325        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15326                SystemClock.uptimeMillis());
15327        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15328            // Changed to/from cached state, so apps after it in the LRU
15329            // list may also be changed.
15330            updateOomAdjLocked();
15331        }
15332        return success;
15333    }
15334
15335    final void updateOomAdjLocked() {
15336        final ActivityRecord TOP_ACT = resumedAppLocked();
15337        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15338        final long now = SystemClock.uptimeMillis();
15339        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15340        final int N = mLruProcesses.size();
15341
15342        if (false) {
15343            RuntimeException e = new RuntimeException();
15344            e.fillInStackTrace();
15345            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15346        }
15347
15348        mAdjSeq++;
15349        mNewNumServiceProcs = 0;
15350        mNewNumAServiceProcs = 0;
15351
15352        final int emptyProcessLimit;
15353        final int cachedProcessLimit;
15354        if (mProcessLimit <= 0) {
15355            emptyProcessLimit = cachedProcessLimit = 0;
15356        } else if (mProcessLimit == 1) {
15357            emptyProcessLimit = 1;
15358            cachedProcessLimit = 0;
15359        } else {
15360            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15361            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15362        }
15363
15364        // Let's determine how many processes we have running vs.
15365        // how many slots we have for background processes; we may want
15366        // to put multiple processes in a slot of there are enough of
15367        // them.
15368        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15369                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15370        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15371        if (numEmptyProcs > cachedProcessLimit) {
15372            // If there are more empty processes than our limit on cached
15373            // processes, then use the cached process limit for the factor.
15374            // This ensures that the really old empty processes get pushed
15375            // down to the bottom, so if we are running low on memory we will
15376            // have a better chance at keeping around more cached processes
15377            // instead of a gazillion empty processes.
15378            numEmptyProcs = cachedProcessLimit;
15379        }
15380        int emptyFactor = numEmptyProcs/numSlots;
15381        if (emptyFactor < 1) emptyFactor = 1;
15382        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15383        if (cachedFactor < 1) cachedFactor = 1;
15384        int stepCached = 0;
15385        int stepEmpty = 0;
15386        int numCached = 0;
15387        int numEmpty = 0;
15388        int numTrimming = 0;
15389
15390        mNumNonCachedProcs = 0;
15391        mNumCachedHiddenProcs = 0;
15392
15393        // First update the OOM adjustment for each of the
15394        // application processes based on their current state.
15395        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15396        int nextCachedAdj = curCachedAdj+1;
15397        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15398        int nextEmptyAdj = curEmptyAdj+2;
15399        for (int i=N-1; i>=0; i--) {
15400            ProcessRecord app = mLruProcesses.get(i);
15401            if (!app.killedByAm && app.thread != null) {
15402                app.procStateChanged = false;
15403                final boolean wasKeeping = app.keeping;
15404                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15405
15406                // If we haven't yet assigned the final cached adj
15407                // to the process, do that now.
15408                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15409                    switch (app.curProcState) {
15410                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15411                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15412                            // This process is a cached process holding activities...
15413                            // assign it the next cached value for that type, and then
15414                            // step that cached level.
15415                            app.curRawAdj = curCachedAdj;
15416                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15417                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15418                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15419                                    + ")");
15420                            if (curCachedAdj != nextCachedAdj) {
15421                                stepCached++;
15422                                if (stepCached >= cachedFactor) {
15423                                    stepCached = 0;
15424                                    curCachedAdj = nextCachedAdj;
15425                                    nextCachedAdj += 2;
15426                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15427                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15428                                    }
15429                                }
15430                            }
15431                            break;
15432                        default:
15433                            // For everything else, assign next empty cached process
15434                            // level and bump that up.  Note that this means that
15435                            // long-running services that have dropped down to the
15436                            // cached level will be treated as empty (since their process
15437                            // state is still as a service), which is what we want.
15438                            app.curRawAdj = curEmptyAdj;
15439                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15440                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15441                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15442                                    + ")");
15443                            if (curEmptyAdj != nextEmptyAdj) {
15444                                stepEmpty++;
15445                                if (stepEmpty >= emptyFactor) {
15446                                    stepEmpty = 0;
15447                                    curEmptyAdj = nextEmptyAdj;
15448                                    nextEmptyAdj += 2;
15449                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15450                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15451                                    }
15452                                }
15453                            }
15454                            break;
15455                    }
15456                }
15457
15458                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15459
15460                // Count the number of process types.
15461                switch (app.curProcState) {
15462                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15463                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15464                        mNumCachedHiddenProcs++;
15465                        numCached++;
15466                        if (numCached > cachedProcessLimit) {
15467                            killUnneededProcessLocked(app, "cached #" + numCached);
15468                        }
15469                        break;
15470                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15471                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15472                                && app.lastActivityTime < oldTime) {
15473                            killUnneededProcessLocked(app, "empty for "
15474                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15475                                    / 1000) + "s");
15476                        } else {
15477                            numEmpty++;
15478                            if (numEmpty > emptyProcessLimit) {
15479                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15480                            }
15481                        }
15482                        break;
15483                    default:
15484                        mNumNonCachedProcs++;
15485                        break;
15486                }
15487
15488                if (app.isolated && app.services.size() <= 0) {
15489                    // If this is an isolated process, and there are no
15490                    // services running in it, then the process is no longer
15491                    // needed.  We agressively kill these because we can by
15492                    // definition not re-use the same process again, and it is
15493                    // good to avoid having whatever code was running in them
15494                    // left sitting around after no longer needed.
15495                    killUnneededProcessLocked(app, "isolated not needed");
15496                }
15497
15498                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15499                        && !app.killedByAm) {
15500                    numTrimming++;
15501                }
15502            }
15503        }
15504
15505        mNumServiceProcs = mNewNumServiceProcs;
15506
15507        // Now determine the memory trimming level of background processes.
15508        // Unfortunately we need to start at the back of the list to do this
15509        // properly.  We only do this if the number of background apps we
15510        // are managing to keep around is less than half the maximum we desire;
15511        // if we are keeping a good number around, we'll let them use whatever
15512        // memory they want.
15513        final int numCachedAndEmpty = numCached + numEmpty;
15514        int memFactor;
15515        if (numCached <= ProcessList.TRIM_CACHED_APPS
15516                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15517            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15518                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15519            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15520                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15521            } else {
15522                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15523            }
15524        } else {
15525            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15526        }
15527        // We always allow the memory level to go up (better).  We only allow it to go
15528        // down if we are in a state where that is allowed, *and* the total number of processes
15529        // has gone down since last time.
15530        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15531                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15532                + " last=" + mLastNumProcesses);
15533        if (memFactor > mLastMemoryLevel) {
15534            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15535                memFactor = mLastMemoryLevel;
15536                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15537            }
15538        }
15539        mLastMemoryLevel = memFactor;
15540        mLastNumProcesses = mLruProcesses.size();
15541        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15542        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15543        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15544            if (mLowRamStartTime == 0) {
15545                mLowRamStartTime = now;
15546            }
15547            int step = 0;
15548            int fgTrimLevel;
15549            switch (memFactor) {
15550                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15551                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15552                    break;
15553                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15554                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15555                    break;
15556                default:
15557                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15558                    break;
15559            }
15560            int factor = numTrimming/3;
15561            int minFactor = 2;
15562            if (mHomeProcess != null) minFactor++;
15563            if (mPreviousProcess != null) minFactor++;
15564            if (factor < minFactor) factor = minFactor;
15565            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15566            for (int i=N-1; i>=0; i--) {
15567                ProcessRecord app = mLruProcesses.get(i);
15568                if (allChanged || app.procStateChanged) {
15569                    setProcessTrackerState(app, trackerMemFactor, now);
15570                    app.procStateChanged = false;
15571                }
15572                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15573                        && !app.killedByAm) {
15574                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15575                        try {
15576                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15577                                    "Trimming memory of " + app.processName
15578                                    + " to " + curLevel);
15579                            app.thread.scheduleTrimMemory(curLevel);
15580                        } catch (RemoteException e) {
15581                        }
15582                        if (false) {
15583                            // For now we won't do this; our memory trimming seems
15584                            // to be good enough at this point that destroying
15585                            // activities causes more harm than good.
15586                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15587                                    && app != mHomeProcess && app != mPreviousProcess) {
15588                                // Need to do this on its own message because the stack may not
15589                                // be in a consistent state at this point.
15590                                // For these apps we will also finish their activities
15591                                // to help them free memory.
15592                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15593                            }
15594                        }
15595                    }
15596                    app.trimMemoryLevel = curLevel;
15597                    step++;
15598                    if (step >= factor) {
15599                        step = 0;
15600                        switch (curLevel) {
15601                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15602                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15603                                break;
15604                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15605                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15606                                break;
15607                        }
15608                    }
15609                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15610                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15611                            && app.thread != null) {
15612                        try {
15613                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15614                                    "Trimming memory of heavy-weight " + app.processName
15615                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15616                            app.thread.scheduleTrimMemory(
15617                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15618                        } catch (RemoteException e) {
15619                        }
15620                    }
15621                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15622                } else {
15623                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15624                            || app.systemNoUi) && app.pendingUiClean) {
15625                        // If this application is now in the background and it
15626                        // had done UI, then give it the special trim level to
15627                        // have it free UI resources.
15628                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15629                        if (app.trimMemoryLevel < level && app.thread != null) {
15630                            try {
15631                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15632                                        "Trimming memory of bg-ui " + app.processName
15633                                        + " to " + level);
15634                                app.thread.scheduleTrimMemory(level);
15635                            } catch (RemoteException e) {
15636                            }
15637                        }
15638                        app.pendingUiClean = false;
15639                    }
15640                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15641                        try {
15642                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15643                                    "Trimming memory of fg " + app.processName
15644                                    + " to " + fgTrimLevel);
15645                            app.thread.scheduleTrimMemory(fgTrimLevel);
15646                        } catch (RemoteException e) {
15647                        }
15648                    }
15649                    app.trimMemoryLevel = fgTrimLevel;
15650                }
15651            }
15652        } else {
15653            if (mLowRamStartTime != 0) {
15654                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15655                mLowRamStartTime = 0;
15656            }
15657            for (int i=N-1; i>=0; i--) {
15658                ProcessRecord app = mLruProcesses.get(i);
15659                if (allChanged || app.procStateChanged) {
15660                    setProcessTrackerState(app, trackerMemFactor, now);
15661                    app.procStateChanged = false;
15662                }
15663                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15664                        || app.systemNoUi) && app.pendingUiClean) {
15665                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15666                            && app.thread != null) {
15667                        try {
15668                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15669                                    "Trimming memory of ui hidden " + app.processName
15670                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15671                            app.thread.scheduleTrimMemory(
15672                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15673                        } catch (RemoteException e) {
15674                        }
15675                    }
15676                    app.pendingUiClean = false;
15677                }
15678                app.trimMemoryLevel = 0;
15679            }
15680        }
15681
15682        if (mAlwaysFinishActivities) {
15683            // Need to do this on its own message because the stack may not
15684            // be in a consistent state at this point.
15685            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15686        }
15687
15688        if (allChanged) {
15689            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15690        }
15691
15692        if (mProcessStats.shouldWriteNowLocked(now)) {
15693            mHandler.post(new Runnable() {
15694                @Override public void run() {
15695                    synchronized (ActivityManagerService.this) {
15696                        mProcessStats.writeStateAsyncLocked();
15697                    }
15698                }
15699            });
15700        }
15701
15702        if (DEBUG_OOM_ADJ) {
15703            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15704        }
15705    }
15706
15707    final void trimApplications() {
15708        synchronized (this) {
15709            int i;
15710
15711            // First remove any unused application processes whose package
15712            // has been removed.
15713            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15714                final ProcessRecord app = mRemovedProcesses.get(i);
15715                if (app.activities.size() == 0
15716                        && app.curReceiver == null && app.services.size() == 0) {
15717                    Slog.i(
15718                        TAG, "Exiting empty application process "
15719                        + app.processName + " ("
15720                        + (app.thread != null ? app.thread.asBinder() : null)
15721                        + ")\n");
15722                    if (app.pid > 0 && app.pid != MY_PID) {
15723                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15724                                app.processName, app.setAdj, "empty");
15725                        app.killedByAm = true;
15726                        Process.killProcessQuiet(app.pid);
15727                    } else {
15728                        try {
15729                            app.thread.scheduleExit();
15730                        } catch (Exception e) {
15731                            // Ignore exceptions.
15732                        }
15733                    }
15734                    cleanUpApplicationRecordLocked(app, false, true, -1);
15735                    mRemovedProcesses.remove(i);
15736
15737                    if (app.persistent) {
15738                        if (app.persistent) {
15739                            addAppLocked(app.info, false, null /* ABI override */);
15740                        }
15741                    }
15742                }
15743            }
15744
15745            // Now update the oom adj for all processes.
15746            updateOomAdjLocked();
15747        }
15748    }
15749
15750    /** This method sends the specified signal to each of the persistent apps */
15751    public void signalPersistentProcesses(int sig) throws RemoteException {
15752        if (sig != Process.SIGNAL_USR1) {
15753            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15754        }
15755
15756        synchronized (this) {
15757            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15758                    != PackageManager.PERMISSION_GRANTED) {
15759                throw new SecurityException("Requires permission "
15760                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15761            }
15762
15763            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15764                ProcessRecord r = mLruProcesses.get(i);
15765                if (r.thread != null && r.persistent) {
15766                    Process.sendSignal(r.pid, sig);
15767                }
15768            }
15769        }
15770    }
15771
15772    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15773        if (proc == null || proc == mProfileProc) {
15774            proc = mProfileProc;
15775            path = mProfileFile;
15776            profileType = mProfileType;
15777            clearProfilerLocked();
15778        }
15779        if (proc == null) {
15780            return;
15781        }
15782        try {
15783            proc.thread.profilerControl(false, path, null, profileType);
15784        } catch (RemoteException e) {
15785            throw new IllegalStateException("Process disappeared");
15786        }
15787    }
15788
15789    private void clearProfilerLocked() {
15790        if (mProfileFd != null) {
15791            try {
15792                mProfileFd.close();
15793            } catch (IOException e) {
15794            }
15795        }
15796        mProfileApp = null;
15797        mProfileProc = null;
15798        mProfileFile = null;
15799        mProfileType = 0;
15800        mAutoStopProfiler = false;
15801    }
15802
15803    public boolean profileControl(String process, int userId, boolean start,
15804            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15805
15806        try {
15807            synchronized (this) {
15808                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15809                // its own permission.
15810                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15811                        != PackageManager.PERMISSION_GRANTED) {
15812                    throw new SecurityException("Requires permission "
15813                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15814                }
15815
15816                if (start && fd == null) {
15817                    throw new IllegalArgumentException("null fd");
15818                }
15819
15820                ProcessRecord proc = null;
15821                if (process != null) {
15822                    proc = findProcessLocked(process, userId, "profileControl");
15823                }
15824
15825                if (start && (proc == null || proc.thread == null)) {
15826                    throw new IllegalArgumentException("Unknown process: " + process);
15827                }
15828
15829                if (start) {
15830                    stopProfilerLocked(null, null, 0);
15831                    setProfileApp(proc.info, proc.processName, path, fd, false);
15832                    mProfileProc = proc;
15833                    mProfileType = profileType;
15834                    try {
15835                        fd = fd.dup();
15836                    } catch (IOException e) {
15837                        fd = null;
15838                    }
15839                    proc.thread.profilerControl(start, path, fd, profileType);
15840                    fd = null;
15841                    mProfileFd = null;
15842                } else {
15843                    stopProfilerLocked(proc, path, profileType);
15844                    if (fd != null) {
15845                        try {
15846                            fd.close();
15847                        } catch (IOException e) {
15848                        }
15849                    }
15850                }
15851
15852                return true;
15853            }
15854        } catch (RemoteException e) {
15855            throw new IllegalStateException("Process disappeared");
15856        } finally {
15857            if (fd != null) {
15858                try {
15859                    fd.close();
15860                } catch (IOException e) {
15861                }
15862            }
15863        }
15864    }
15865
15866    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15867        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15868                userId, true, true, callName, null);
15869        ProcessRecord proc = null;
15870        try {
15871            int pid = Integer.parseInt(process);
15872            synchronized (mPidsSelfLocked) {
15873                proc = mPidsSelfLocked.get(pid);
15874            }
15875        } catch (NumberFormatException e) {
15876        }
15877
15878        if (proc == null) {
15879            ArrayMap<String, SparseArray<ProcessRecord>> all
15880                    = mProcessNames.getMap();
15881            SparseArray<ProcessRecord> procs = all.get(process);
15882            if (procs != null && procs.size() > 0) {
15883                proc = procs.valueAt(0);
15884                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
15885                    for (int i=1; i<procs.size(); i++) {
15886                        ProcessRecord thisProc = procs.valueAt(i);
15887                        if (thisProc.userId == userId) {
15888                            proc = thisProc;
15889                            break;
15890                        }
15891                    }
15892                }
15893            }
15894        }
15895
15896        return proc;
15897    }
15898
15899    public boolean dumpHeap(String process, int userId, boolean managed,
15900            String path, ParcelFileDescriptor fd) throws RemoteException {
15901
15902        try {
15903            synchronized (this) {
15904                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15905                // its own permission (same as profileControl).
15906                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15907                        != PackageManager.PERMISSION_GRANTED) {
15908                    throw new SecurityException("Requires permission "
15909                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15910                }
15911
15912                if (fd == null) {
15913                    throw new IllegalArgumentException("null fd");
15914                }
15915
15916                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
15917                if (proc == null || proc.thread == null) {
15918                    throw new IllegalArgumentException("Unknown process: " + process);
15919                }
15920
15921                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15922                if (!isDebuggable) {
15923                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15924                        throw new SecurityException("Process not debuggable: " + proc);
15925                    }
15926                }
15927
15928                proc.thread.dumpHeap(managed, path, fd);
15929                fd = null;
15930                return true;
15931            }
15932        } catch (RemoteException e) {
15933            throw new IllegalStateException("Process disappeared");
15934        } finally {
15935            if (fd != null) {
15936                try {
15937                    fd.close();
15938                } catch (IOException e) {
15939                }
15940            }
15941        }
15942    }
15943
15944    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15945    public void monitor() {
15946        synchronized (this) { }
15947    }
15948
15949    void onCoreSettingsChange(Bundle settings) {
15950        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15951            ProcessRecord processRecord = mLruProcesses.get(i);
15952            try {
15953                if (processRecord.thread != null) {
15954                    processRecord.thread.setCoreSettings(settings);
15955                }
15956            } catch (RemoteException re) {
15957                /* ignore */
15958            }
15959        }
15960    }
15961
15962    // Multi-user methods
15963
15964    @Override
15965    public boolean switchUser(final int userId) {
15966        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
15967                != PackageManager.PERMISSION_GRANTED) {
15968            String msg = "Permission Denial: switchUser() from pid="
15969                    + Binder.getCallingPid()
15970                    + ", uid=" + Binder.getCallingUid()
15971                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
15972            Slog.w(TAG, msg);
15973            throw new SecurityException(msg);
15974        }
15975
15976        final long ident = Binder.clearCallingIdentity();
15977        try {
15978            synchronized (this) {
15979                final int oldUserId = mCurrentUserId;
15980                if (oldUserId == userId) {
15981                    return true;
15982                }
15983
15984                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
15985                if (userInfo == null) {
15986                    Slog.w(TAG, "No user info for user #" + userId);
15987                    return false;
15988                }
15989
15990                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
15991                        R.anim.screen_user_enter);
15992
15993                boolean needStart = false;
15994
15995                // If the user we are switching to is not currently started, then
15996                // we need to start it now.
15997                if (mStartedUsers.get(userId) == null) {
15998                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
15999                    updateStartedUserArrayLocked();
16000                    needStart = true;
16001                }
16002
16003                mCurrentUserId = userId;
16004                final Integer userIdInt = Integer.valueOf(userId);
16005                mUserLru.remove(userIdInt);
16006                mUserLru.add(userIdInt);
16007
16008                mWindowManager.setCurrentUser(userId);
16009
16010                // Once the internal notion of the active user has switched, we lock the device
16011                // with the option to show the user switcher on the keyguard.
16012                mWindowManager.lockNow(null);
16013
16014                final UserStartedState uss = mStartedUsers.get(userId);
16015
16016                // Make sure user is in the started state.  If it is currently
16017                // stopping, we need to knock that off.
16018                if (uss.mState == UserStartedState.STATE_STOPPING) {
16019                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16020                    // so we can just fairly silently bring the user back from
16021                    // the almost-dead.
16022                    uss.mState = UserStartedState.STATE_RUNNING;
16023                    updateStartedUserArrayLocked();
16024                    needStart = true;
16025                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16026                    // This means ACTION_SHUTDOWN has been sent, so we will
16027                    // need to treat this as a new boot of the user.
16028                    uss.mState = UserStartedState.STATE_BOOTING;
16029                    updateStartedUserArrayLocked();
16030                    needStart = true;
16031                }
16032
16033                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16034                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16035                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16036                        oldUserId, userId, uss));
16037                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16038                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16039                if (needStart) {
16040                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16041                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16042                            | Intent.FLAG_RECEIVER_FOREGROUND);
16043                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16044                    broadcastIntentLocked(null, null, intent,
16045                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16046                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16047                }
16048
16049                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16050                    if (userId != 0) {
16051                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16052                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16053                        broadcastIntentLocked(null, null, intent, null,
16054                                new IIntentReceiver.Stub() {
16055                                    public void performReceive(Intent intent, int resultCode,
16056                                            String data, Bundle extras, boolean ordered,
16057                                            boolean sticky, int sendingUser) {
16058                                        userInitialized(uss, userId);
16059                                    }
16060                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16061                                true, false, MY_PID, Process.SYSTEM_UID,
16062                                userId);
16063                        uss.initializing = true;
16064                    } else {
16065                        getUserManagerLocked().makeInitialized(userInfo.id);
16066                    }
16067                }
16068
16069                boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16070                if (homeInFront) {
16071                    startHomeActivityLocked(userId);
16072                } else {
16073                    mStackSupervisor.resumeTopActivitiesLocked();
16074                }
16075
16076                EventLogTags.writeAmSwitchUser(userId);
16077                getUserManagerLocked().userForeground(userId);
16078                sendUserSwitchBroadcastsLocked(oldUserId, userId);
16079                if (needStart) {
16080                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16081                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16082                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16083                    broadcastIntentLocked(null, null, intent,
16084                            null, new IIntentReceiver.Stub() {
16085                                @Override
16086                                public void performReceive(Intent intent, int resultCode, String data,
16087                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16088                                        throws RemoteException {
16089                                }
16090                            }, 0, null, null,
16091                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16092                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16093                }
16094            }
16095        } finally {
16096            Binder.restoreCallingIdentity(ident);
16097        }
16098
16099        return true;
16100    }
16101
16102    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16103        long ident = Binder.clearCallingIdentity();
16104        try {
16105            Intent intent;
16106            if (oldUserId >= 0) {
16107                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16108                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16109                        | Intent.FLAG_RECEIVER_FOREGROUND);
16110                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16111                broadcastIntentLocked(null, null, intent,
16112                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16113                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16114            }
16115            if (newUserId >= 0) {
16116                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16117                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16118                        | Intent.FLAG_RECEIVER_FOREGROUND);
16119                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16120                broadcastIntentLocked(null, null, intent,
16121                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16122                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16123                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16124                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16125                        | Intent.FLAG_RECEIVER_FOREGROUND);
16126                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16127                broadcastIntentLocked(null, null, intent,
16128                        null, null, 0, null, null,
16129                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16130                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16131            }
16132        } finally {
16133            Binder.restoreCallingIdentity(ident);
16134        }
16135    }
16136
16137    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16138            final int newUserId) {
16139        final int N = mUserSwitchObservers.beginBroadcast();
16140        if (N > 0) {
16141            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16142                int mCount = 0;
16143                @Override
16144                public void sendResult(Bundle data) throws RemoteException {
16145                    synchronized (ActivityManagerService.this) {
16146                        if (mCurUserSwitchCallback == this) {
16147                            mCount++;
16148                            if (mCount == N) {
16149                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16150                            }
16151                        }
16152                    }
16153                }
16154            };
16155            synchronized (this) {
16156                uss.switching = true;
16157                mCurUserSwitchCallback = callback;
16158            }
16159            for (int i=0; i<N; i++) {
16160                try {
16161                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16162                            newUserId, callback);
16163                } catch (RemoteException e) {
16164                }
16165            }
16166        } else {
16167            synchronized (this) {
16168                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16169            }
16170        }
16171        mUserSwitchObservers.finishBroadcast();
16172    }
16173
16174    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16175        synchronized (this) {
16176            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16177            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16178        }
16179    }
16180
16181    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16182        mCurUserSwitchCallback = null;
16183        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16184        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16185                oldUserId, newUserId, uss));
16186    }
16187
16188    void userInitialized(UserStartedState uss, int newUserId) {
16189        completeSwitchAndInitalize(uss, newUserId, true, false);
16190    }
16191
16192    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16193        completeSwitchAndInitalize(uss, newUserId, false, true);
16194    }
16195
16196    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16197            boolean clearInitializing, boolean clearSwitching) {
16198        boolean unfrozen = false;
16199        synchronized (this) {
16200            if (clearInitializing) {
16201                uss.initializing = false;
16202                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16203            }
16204            if (clearSwitching) {
16205                uss.switching = false;
16206            }
16207            if (!uss.switching && !uss.initializing) {
16208                mWindowManager.stopFreezingScreen();
16209                unfrozen = true;
16210            }
16211        }
16212        if (unfrozen) {
16213            final int N = mUserSwitchObservers.beginBroadcast();
16214            for (int i=0; i<N; i++) {
16215                try {
16216                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16217                } catch (RemoteException e) {
16218                }
16219            }
16220            mUserSwitchObservers.finishBroadcast();
16221        }
16222    }
16223
16224    void finishUserSwitch(UserStartedState uss) {
16225        synchronized (this) {
16226            if (uss.mState == UserStartedState.STATE_BOOTING
16227                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16228                uss.mState = UserStartedState.STATE_RUNNING;
16229                final int userId = uss.mHandle.getIdentifier();
16230                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16231                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16232                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16233                broadcastIntentLocked(null, null, intent,
16234                        null, null, 0, null, null,
16235                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16236                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16237            }
16238            int num = mUserLru.size();
16239            int i = 0;
16240            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16241                Integer oldUserId = mUserLru.get(i);
16242                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16243                if (oldUss == null) {
16244                    // Shouldn't happen, but be sane if it does.
16245                    mUserLru.remove(i);
16246                    num--;
16247                    continue;
16248                }
16249                if (oldUss.mState == UserStartedState.STATE_STOPPING
16250                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16251                    // This user is already stopping, doesn't count.
16252                    num--;
16253                    i++;
16254                    continue;
16255                }
16256                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16257                    // Owner and current can't be stopped, but count as running.
16258                    i++;
16259                    continue;
16260                }
16261                // This is a user to be stopped.
16262                stopUserLocked(oldUserId, null);
16263                num--;
16264                i++;
16265            }
16266        }
16267    }
16268
16269    @Override
16270    public int stopUser(final int userId, final IStopUserCallback callback) {
16271        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16272                != PackageManager.PERMISSION_GRANTED) {
16273            String msg = "Permission Denial: switchUser() from pid="
16274                    + Binder.getCallingPid()
16275                    + ", uid=" + Binder.getCallingUid()
16276                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16277            Slog.w(TAG, msg);
16278            throw new SecurityException(msg);
16279        }
16280        if (userId <= 0) {
16281            throw new IllegalArgumentException("Can't stop primary user " + userId);
16282        }
16283        synchronized (this) {
16284            return stopUserLocked(userId, callback);
16285        }
16286    }
16287
16288    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16289        if (mCurrentUserId == userId) {
16290            return ActivityManager.USER_OP_IS_CURRENT;
16291        }
16292
16293        final UserStartedState uss = mStartedUsers.get(userId);
16294        if (uss == null) {
16295            // User is not started, nothing to do...  but we do need to
16296            // callback if requested.
16297            if (callback != null) {
16298                mHandler.post(new Runnable() {
16299                    @Override
16300                    public void run() {
16301                        try {
16302                            callback.userStopped(userId);
16303                        } catch (RemoteException e) {
16304                        }
16305                    }
16306                });
16307            }
16308            return ActivityManager.USER_OP_SUCCESS;
16309        }
16310
16311        if (callback != null) {
16312            uss.mStopCallbacks.add(callback);
16313        }
16314
16315        if (uss.mState != UserStartedState.STATE_STOPPING
16316                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16317            uss.mState = UserStartedState.STATE_STOPPING;
16318            updateStartedUserArrayLocked();
16319
16320            long ident = Binder.clearCallingIdentity();
16321            try {
16322                // We are going to broadcast ACTION_USER_STOPPING and then
16323                // once that is done send a final ACTION_SHUTDOWN and then
16324                // stop the user.
16325                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16326                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16327                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16328                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16329                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16330                // This is the result receiver for the final shutdown broadcast.
16331                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16332                    @Override
16333                    public void performReceive(Intent intent, int resultCode, String data,
16334                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16335                        finishUserStop(uss);
16336                    }
16337                };
16338                // This is the result receiver for the initial stopping broadcast.
16339                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16340                    @Override
16341                    public void performReceive(Intent intent, int resultCode, String data,
16342                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16343                        // On to the next.
16344                        synchronized (ActivityManagerService.this) {
16345                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16346                                // Whoops, we are being started back up.  Abort, abort!
16347                                return;
16348                            }
16349                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16350                        }
16351                        broadcastIntentLocked(null, null, shutdownIntent,
16352                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16353                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16354                    }
16355                };
16356                // Kick things off.
16357                broadcastIntentLocked(null, null, stoppingIntent,
16358                        null, stoppingReceiver, 0, null, null,
16359                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16360                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16361            } finally {
16362                Binder.restoreCallingIdentity(ident);
16363            }
16364        }
16365
16366        return ActivityManager.USER_OP_SUCCESS;
16367    }
16368
16369    void finishUserStop(UserStartedState uss) {
16370        final int userId = uss.mHandle.getIdentifier();
16371        boolean stopped;
16372        ArrayList<IStopUserCallback> callbacks;
16373        synchronized (this) {
16374            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16375            if (mStartedUsers.get(userId) != uss) {
16376                stopped = false;
16377            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16378                stopped = false;
16379            } else {
16380                stopped = true;
16381                // User can no longer run.
16382                mStartedUsers.remove(userId);
16383                mUserLru.remove(Integer.valueOf(userId));
16384                updateStartedUserArrayLocked();
16385
16386                // Clean up all state and processes associated with the user.
16387                // Kill all the processes for the user.
16388                forceStopUserLocked(userId, "finish user");
16389            }
16390        }
16391
16392        for (int i=0; i<callbacks.size(); i++) {
16393            try {
16394                if (stopped) callbacks.get(i).userStopped(userId);
16395                else callbacks.get(i).userStopAborted(userId);
16396            } catch (RemoteException e) {
16397            }
16398        }
16399
16400        mStackSupervisor.removeUserLocked(userId);
16401    }
16402
16403    @Override
16404    public UserInfo getCurrentUser() {
16405        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16406                != PackageManager.PERMISSION_GRANTED) && (
16407                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16408                != PackageManager.PERMISSION_GRANTED)) {
16409            String msg = "Permission Denial: getCurrentUser() from pid="
16410                    + Binder.getCallingPid()
16411                    + ", uid=" + Binder.getCallingUid()
16412                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16413            Slog.w(TAG, msg);
16414            throw new SecurityException(msg);
16415        }
16416        synchronized (this) {
16417            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16418        }
16419    }
16420
16421    int getCurrentUserIdLocked() {
16422        return mCurrentUserId;
16423    }
16424
16425    @Override
16426    public boolean isUserRunning(int userId, boolean orStopped) {
16427        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16428                != PackageManager.PERMISSION_GRANTED) {
16429            String msg = "Permission Denial: isUserRunning() from pid="
16430                    + Binder.getCallingPid()
16431                    + ", uid=" + Binder.getCallingUid()
16432                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16433            Slog.w(TAG, msg);
16434            throw new SecurityException(msg);
16435        }
16436        synchronized (this) {
16437            return isUserRunningLocked(userId, orStopped);
16438        }
16439    }
16440
16441    boolean isUserRunningLocked(int userId, boolean orStopped) {
16442        UserStartedState state = mStartedUsers.get(userId);
16443        if (state == null) {
16444            return false;
16445        }
16446        if (orStopped) {
16447            return true;
16448        }
16449        return state.mState != UserStartedState.STATE_STOPPING
16450                && state.mState != UserStartedState.STATE_SHUTDOWN;
16451    }
16452
16453    @Override
16454    public int[] getRunningUserIds() {
16455        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16456                != PackageManager.PERMISSION_GRANTED) {
16457            String msg = "Permission Denial: isUserRunning() from pid="
16458                    + Binder.getCallingPid()
16459                    + ", uid=" + Binder.getCallingUid()
16460                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16461            Slog.w(TAG, msg);
16462            throw new SecurityException(msg);
16463        }
16464        synchronized (this) {
16465            return mStartedUserArray;
16466        }
16467    }
16468
16469    private void updateStartedUserArrayLocked() {
16470        int num = 0;
16471        for (int i=0; i<mStartedUsers.size();  i++) {
16472            UserStartedState uss = mStartedUsers.valueAt(i);
16473            // This list does not include stopping users.
16474            if (uss.mState != UserStartedState.STATE_STOPPING
16475                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16476                num++;
16477            }
16478        }
16479        mStartedUserArray = new int[num];
16480        num = 0;
16481        for (int i=0; i<mStartedUsers.size();  i++) {
16482            UserStartedState uss = mStartedUsers.valueAt(i);
16483            if (uss.mState != UserStartedState.STATE_STOPPING
16484                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16485                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16486                num++;
16487            }
16488        }
16489    }
16490
16491    @Override
16492    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16493        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16494                != PackageManager.PERMISSION_GRANTED) {
16495            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16496                    + Binder.getCallingPid()
16497                    + ", uid=" + Binder.getCallingUid()
16498                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16499            Slog.w(TAG, msg);
16500            throw new SecurityException(msg);
16501        }
16502
16503        mUserSwitchObservers.register(observer);
16504    }
16505
16506    @Override
16507    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16508        mUserSwitchObservers.unregister(observer);
16509    }
16510
16511    private boolean userExists(int userId) {
16512        if (userId == 0) {
16513            return true;
16514        }
16515        UserManagerService ums = getUserManagerLocked();
16516        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16517    }
16518
16519    int[] getUsersLocked() {
16520        UserManagerService ums = getUserManagerLocked();
16521        return ums != null ? ums.getUserIds() : new int[] { 0 };
16522    }
16523
16524    UserManagerService getUserManagerLocked() {
16525        if (mUserManager == null) {
16526            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16527            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16528        }
16529        return mUserManager;
16530    }
16531
16532    private int applyUserId(int uid, int userId) {
16533        return UserHandle.getUid(userId, uid);
16534    }
16535
16536    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16537        if (info == null) return null;
16538        ApplicationInfo newInfo = new ApplicationInfo(info);
16539        newInfo.uid = applyUserId(info.uid, userId);
16540        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16541                + info.packageName;
16542        return newInfo;
16543    }
16544
16545    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16546        if (aInfo == null
16547                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16548            return aInfo;
16549        }
16550
16551        ActivityInfo info = new ActivityInfo(aInfo);
16552        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16553        return info;
16554    }
16555
16556    private final class LocalService extends ActivityManagerInternal {
16557        @Override
16558        public void goingToSleep() {
16559            ActivityManagerService.this.goingToSleep();
16560        }
16561
16562        @Override
16563        public void wakingUp() {
16564            ActivityManagerService.this.wakingUp();
16565        }
16566    }
16567}
16568