ActivityManagerService.java revision e0a3884cb627efc650e19fbe76b1b3343468cf57
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readIntAttribute;
21import static com.android.internal.util.XmlUtils.readLongAttribute;
22import static com.android.internal.util.XmlUtils.writeIntAttribute;
23import static com.android.internal.util.XmlUtils.writeLongAttribute;
24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
26import static org.xmlpull.v1.XmlPullParser.START_TAG;
27
28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
29
30import android.app.AppOpsManager;
31import android.app.IActivityContainer;
32import android.app.IActivityContainerCallback;
33import android.appwidget.AppWidgetManager;
34import android.graphics.Rect;
35import android.util.ArrayMap;
36import com.android.internal.R;
37import com.android.internal.annotations.GuardedBy;
38import com.android.internal.app.IAppOpsService;
39import com.android.internal.app.ProcessMap;
40import com.android.internal.app.ProcessStats;
41import com.android.internal.os.BackgroundThread;
42import com.android.internal.os.BatteryStatsImpl;
43import com.android.internal.os.ProcessCpuTracker;
44import com.android.internal.os.TransferPipe;
45import com.android.internal.util.FastPrintWriter;
46import com.android.internal.util.FastXmlSerializer;
47import com.android.internal.util.MemInfoReader;
48import com.android.internal.util.Preconditions;
49import com.android.server.AppOpsService;
50import com.android.server.AttributeCache;
51import com.android.server.IntentResolver;
52import com.android.server.SystemServer;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.UserManagerService;
57import com.android.server.wm.AppTransition;
58import com.android.server.wm.WindowManagerService;
59import com.google.android.collect.Lists;
60import com.google.android.collect.Maps;
61
62import dalvik.system.Zygote;
63
64import libcore.io.IoUtils;
65
66import org.xmlpull.v1.XmlPullParser;
67import org.xmlpull.v1.XmlPullParserException;
68import org.xmlpull.v1.XmlSerializer;
69
70import android.app.Activity;
71import android.app.ActivityManager;
72import android.app.ActivityManager.RunningTaskInfo;
73import android.app.ActivityManager.StackInfo;
74import android.app.ActivityManagerNative;
75import android.app.ActivityOptions;
76import android.app.ActivityThread;
77import android.app.AlertDialog;
78import android.app.AppGlobals;
79import android.app.ApplicationErrorReport;
80import android.app.Dialog;
81import android.app.IActivityController;
82import android.app.IApplicationThread;
83import android.app.IInstrumentationWatcher;
84import android.app.INotificationManager;
85import android.app.IProcessObserver;
86import android.app.IServiceConnection;
87import android.app.IStopUserCallback;
88import android.app.IThumbnailReceiver;
89import android.app.IUiAutomationConnection;
90import android.app.IUserSwitchObserver;
91import android.app.Instrumentation;
92import android.app.Notification;
93import android.app.NotificationManager;
94import android.app.PendingIntent;
95import android.app.backup.IBackupManager;
96import android.content.ActivityNotFoundException;
97import android.content.BroadcastReceiver;
98import android.content.ClipData;
99import android.content.ComponentCallbacks2;
100import android.content.ComponentName;
101import android.content.ContentProvider;
102import android.content.ContentResolver;
103import android.content.Context;
104import android.content.DialogInterface;
105import android.content.IContentProvider;
106import android.content.IIntentReceiver;
107import android.content.IIntentSender;
108import android.content.Intent;
109import android.content.IntentFilter;
110import android.content.IntentSender;
111import android.content.pm.ActivityInfo;
112import android.content.pm.ApplicationInfo;
113import android.content.pm.ConfigurationInfo;
114import android.content.pm.IPackageDataObserver;
115import android.content.pm.IPackageManager;
116import android.content.pm.InstrumentationInfo;
117import android.content.pm.PackageInfo;
118import android.content.pm.PackageManager;
119import android.content.pm.ParceledListSlice;
120import android.content.pm.UserInfo;
121import android.content.pm.PackageManager.NameNotFoundException;
122import android.content.pm.PathPermission;
123import android.content.pm.ProviderInfo;
124import android.content.pm.ResolveInfo;
125import android.content.pm.ServiceInfo;
126import android.content.res.CompatibilityInfo;
127import android.content.res.Configuration;
128import android.graphics.Bitmap;
129import android.net.Proxy;
130import android.net.ProxyProperties;
131import android.net.Uri;
132import android.os.Binder;
133import android.os.Build;
134import android.os.Bundle;
135import android.os.Debug;
136import android.os.DropBoxManager;
137import android.os.Environment;
138import android.os.FileObserver;
139import android.os.FileUtils;
140import android.os.Handler;
141import android.os.IBinder;
142import android.os.IPermissionController;
143import android.os.IRemoteCallback;
144import android.os.IUserManager;
145import android.os.Looper;
146import android.os.Message;
147import android.os.Parcel;
148import android.os.ParcelFileDescriptor;
149import android.os.Process;
150import android.os.RemoteCallbackList;
151import android.os.RemoteException;
152import android.os.SELinux;
153import android.os.ServiceManager;
154import android.os.StrictMode;
155import android.os.SystemClock;
156import android.os.SystemProperties;
157import android.os.UpdateLock;
158import android.os.UserHandle;
159import android.provider.Settings;
160import android.text.format.DateUtils;
161import android.text.format.Time;
162import android.util.AtomicFile;
163import android.util.EventLog;
164import android.util.Log;
165import android.util.Pair;
166import android.util.PrintWriterPrinter;
167import android.util.Slog;
168import android.util.SparseArray;
169import android.util.TimeUtils;
170import android.util.Xml;
171import android.view.Gravity;
172import android.view.LayoutInflater;
173import android.view.View;
174import android.view.WindowManager;
175
176import java.io.BufferedInputStream;
177import java.io.BufferedOutputStream;
178import java.io.DataInputStream;
179import java.io.DataOutputStream;
180import java.io.File;
181import java.io.FileDescriptor;
182import java.io.FileInputStream;
183import java.io.FileNotFoundException;
184import java.io.FileOutputStream;
185import java.io.IOException;
186import java.io.InputStreamReader;
187import java.io.PrintWriter;
188import java.io.StringWriter;
189import java.lang.ref.WeakReference;
190import java.util.ArrayList;
191import java.util.Arrays;
192import java.util.Collections;
193import java.util.Comparator;
194import java.util.HashMap;
195import java.util.HashSet;
196import java.util.Iterator;
197import java.util.List;
198import java.util.Locale;
199import java.util.Map;
200import java.util.Set;
201import java.util.concurrent.atomic.AtomicBoolean;
202import java.util.concurrent.atomic.AtomicLong;
203
204public final class ActivityManagerService extends ActivityManagerNative
205        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
206    private static final String USER_DATA_DIR = "/data/user/";
207    static final String TAG = "ActivityManager";
208    static final String TAG_MU = "ActivityManagerServiceMU";
209    static final boolean DEBUG = false;
210    static final boolean localLOGV = DEBUG;
211    static final boolean DEBUG_BACKUP = localLOGV || false;
212    static final boolean DEBUG_BROADCAST = localLOGV || false;
213    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
214    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
215    static final boolean DEBUG_CLEANUP = localLOGV || false;
216    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
217    static final boolean DEBUG_FOCUS = false;
218    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
219    static final boolean DEBUG_MU = localLOGV || false;
220    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
221    static final boolean DEBUG_LRU = localLOGV || false;
222    static final boolean DEBUG_PAUSE = localLOGV || false;
223    static final boolean DEBUG_POWER = localLOGV || false;
224    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
225    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
226    static final boolean DEBUG_PROCESSES = localLOGV || false;
227    static final boolean DEBUG_PROVIDER = localLOGV || false;
228    static final boolean DEBUG_RESULTS = localLOGV || false;
229    static final boolean DEBUG_SERVICE = localLOGV || false;
230    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
231    static final boolean DEBUG_STACK = localLOGV || false;
232    static final boolean DEBUG_SWITCH = localLOGV || false;
233    static final boolean DEBUG_TASKS = localLOGV || false;
234    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
235    static final boolean DEBUG_TRANSITION = localLOGV || false;
236    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
237    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
238    static final boolean DEBUG_VISBILITY = localLOGV || false;
239    static final boolean DEBUG_PSS = localLOGV || false;
240    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
241    static final boolean VALIDATE_TOKENS = false;
242    static final boolean SHOW_ACTIVITY_START_TIME = true;
243
244    // Control over CPU and battery monitoring.
245    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
246    static final boolean MONITOR_CPU_USAGE = true;
247    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
248    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
249    static final boolean MONITOR_THREAD_CPU_USAGE = false;
250
251    // The flags that are set for all calls we make to the package manager.
252    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
253
254    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
255
256    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
257
258    // Maximum number of recent tasks that we can remember.
259    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
260
261    // Amount of time after a call to stopAppSwitches() during which we will
262    // prevent further untrusted switches from happening.
263    static final long APP_SWITCH_DELAY_TIME = 5*1000;
264
265    // How long we wait for a launched process to attach to the activity manager
266    // before we decide it's never going to come up for real.
267    static final int PROC_START_TIMEOUT = 10*1000;
268
269    // How long we wait for a launched process to attach to the activity manager
270    // before we decide it's never going to come up for real, when the process was
271    // started with a wrapper for instrumentation (such as Valgrind) because it
272    // could take much longer than usual.
273    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
274
275    // How long to wait after going idle before forcing apps to GC.
276    static final int GC_TIMEOUT = 5*1000;
277
278    // The minimum amount of time between successive GC requests for a process.
279    static final int GC_MIN_INTERVAL = 60*1000;
280
281    // The minimum amount of time between successive PSS requests for a process.
282    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
283
284    // The minimum amount of time between successive PSS requests for a process
285    // when the request is due to the memory state being lowered.
286    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
287
288    // The rate at which we check for apps using excessive power -- 15 mins.
289    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
290
291    // The minimum sample duration we will allow before deciding we have
292    // enough data on wake locks to start killing things.
293    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
294
295    // The minimum sample duration we will allow before deciding we have
296    // enough data on CPU usage to start killing things.
297    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
298
299    // How long we allow a receiver to run before giving up on it.
300    static final int BROADCAST_FG_TIMEOUT = 10*1000;
301    static final int BROADCAST_BG_TIMEOUT = 60*1000;
302
303    // How long we wait until we timeout on key dispatching.
304    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
305
306    // How long we wait until we timeout on key dispatching during instrumentation.
307    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
308
309    // Amount of time we wait for observers to handle a user switch before
310    // giving up on them and unfreezing the screen.
311    static final int USER_SWITCH_TIMEOUT = 2*1000;
312
313    // Maximum number of users we allow to be running at a time.
314    static final int MAX_RUNNING_USERS = 3;
315
316    // How long to wait in getAssistContextExtras for the activity and foreground services
317    // to respond with the result.
318    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
319
320    // Maximum number of persisted Uri grants a package is allowed
321    static final int MAX_PERSISTED_URI_GRANTS = 128;
322
323    static final int MY_PID = Process.myPid();
324
325    static final String[] EMPTY_STRING_ARRAY = new String[0];
326
327    // How many bytes to write into the dropbox log before truncating
328    static final int DROPBOX_MAX_SIZE = 256 * 1024;
329
330    /** Run all ActivityStacks through this */
331    ActivityStackSupervisor mStackSupervisor;
332
333    public IntentFirewall mIntentFirewall;
334
335    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
336    // default actuion automatically.  Important for devices without direct input
337    // devices.
338    private boolean mShowDialogs = true;
339
340    /**
341     * Description of a request to start a new activity, which has been held
342     * due to app switches being disabled.
343     */
344    static class PendingActivityLaunch {
345        final ActivityRecord r;
346        final ActivityRecord sourceRecord;
347        final int startFlags;
348        final ActivityStack stack;
349
350        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
351                int _startFlags, ActivityStack _stack) {
352            r = _r;
353            sourceRecord = _sourceRecord;
354            startFlags = _startFlags;
355            stack = _stack;
356        }
357    }
358
359    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
360            = new ArrayList<PendingActivityLaunch>();
361
362    BroadcastQueue mFgBroadcastQueue;
363    BroadcastQueue mBgBroadcastQueue;
364    // Convenient for easy iteration over the queues. Foreground is first
365    // so that dispatch of foreground broadcasts gets precedence.
366    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
367
368    BroadcastQueue broadcastQueueForIntent(Intent intent) {
369        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
370        if (DEBUG_BACKGROUND_BROADCAST) {
371            Slog.i(TAG, "Broadcast intent " + intent + " on "
372                    + (isFg ? "foreground" : "background")
373                    + " queue");
374        }
375        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
376    }
377
378    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
379        for (BroadcastQueue queue : mBroadcastQueues) {
380            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
381            if (r != null) {
382                return r;
383            }
384        }
385        return null;
386    }
387
388    /**
389     * Activity we have told the window manager to have key focus.
390     */
391    ActivityRecord mFocusedActivity = null;
392
393    /**
394     * List of intents that were used to start the most recent tasks.
395     */
396    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
397
398    public class PendingAssistExtras extends Binder implements Runnable {
399        public final ActivityRecord activity;
400        public boolean haveResult = false;
401        public Bundle result = null;
402        public PendingAssistExtras(ActivityRecord _activity) {
403            activity = _activity;
404        }
405        @Override
406        public void run() {
407            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
408            synchronized (this) {
409                haveResult = true;
410                notifyAll();
411            }
412        }
413    }
414
415    final ArrayList<PendingAssistExtras> mPendingAssistExtras
416            = new ArrayList<PendingAssistExtras>();
417
418    /**
419     * Process management.
420     */
421    final ProcessList mProcessList = new ProcessList();
422
423    /**
424     * All of the applications we currently have running organized by name.
425     * The keys are strings of the application package name (as
426     * returned by the package manager), and the keys are ApplicationRecord
427     * objects.
428     */
429    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
430
431    /**
432     * Tracking long-term execution of processes to look for abuse and other
433     * bad app behavior.
434     */
435    final ProcessStatsService mProcessStats;
436
437    /**
438     * The currently running isolated processes.
439     */
440    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
441
442    /**
443     * Counter for assigning isolated process uids, to avoid frequently reusing the
444     * same ones.
445     */
446    int mNextIsolatedProcessUid = 0;
447
448    /**
449     * The currently running heavy-weight process, if any.
450     */
451    ProcessRecord mHeavyWeightProcess = null;
452
453    /**
454     * The last time that various processes have crashed.
455     */
456    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
457
458    /**
459     * Information about a process that is currently marked as bad.
460     */
461    static final class BadProcessInfo {
462        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
463            this.time = time;
464            this.shortMsg = shortMsg;
465            this.longMsg = longMsg;
466            this.stack = stack;
467        }
468
469        final long time;
470        final String shortMsg;
471        final String longMsg;
472        final String stack;
473    }
474
475    /**
476     * Set of applications that we consider to be bad, and will reject
477     * incoming broadcasts from (which the user has no control over).
478     * Processes are added to this set when they have crashed twice within
479     * a minimum amount of time; they are removed from it when they are
480     * later restarted (hopefully due to some user action).  The value is the
481     * time it was added to the list.
482     */
483    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
484
485    /**
486     * All of the processes we currently have running organized by pid.
487     * The keys are the pid running the application.
488     *
489     * <p>NOTE: This object is protected by its own lock, NOT the global
490     * activity manager lock!
491     */
492    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
493
494    /**
495     * All of the processes that have been forced to be foreground.  The key
496     * is the pid of the caller who requested it (we hold a death
497     * link on it).
498     */
499    abstract class ForegroundToken implements IBinder.DeathRecipient {
500        int pid;
501        IBinder token;
502    }
503    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
504
505    /**
506     * List of records for processes that someone had tried to start before the
507     * system was ready.  We don't start them at that point, but ensure they
508     * are started by the time booting is complete.
509     */
510    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
511
512    /**
513     * List of persistent applications that are in the process
514     * of being started.
515     */
516    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
517
518    /**
519     * Processes that are being forcibly torn down.
520     */
521    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
522
523    /**
524     * List of running applications, sorted by recent usage.
525     * The first entry in the list is the least recently used.
526     */
527    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
528
529    /**
530     * Where in mLruProcesses that the processes hosting activities start.
531     */
532    int mLruProcessActivityStart = 0;
533
534    /**
535     * Where in mLruProcesses that the processes hosting services start.
536     * This is after (lower index) than mLruProcessesActivityStart.
537     */
538    int mLruProcessServiceStart = 0;
539
540    /**
541     * List of processes that should gc as soon as things are idle.
542     */
543    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
544
545    /**
546     * Processes we want to collect PSS data from.
547     */
548    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
549
550    /**
551     * Last time we requested PSS data of all processes.
552     */
553    long mLastFullPssTime = SystemClock.uptimeMillis();
554
555    /**
556     * This is the process holding what we currently consider to be
557     * the "home" activity.
558     */
559    ProcessRecord mHomeProcess;
560
561    /**
562     * This is the process holding the activity the user last visited that
563     * is in a different process from the one they are currently in.
564     */
565    ProcessRecord mPreviousProcess;
566
567    /**
568     * The time at which the previous process was last visible.
569     */
570    long mPreviousProcessVisibleTime;
571
572    /**
573     * Which uses have been started, so are allowed to run code.
574     */
575    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
576
577    /**
578     * LRU list of history of current users.  Most recently current is at the end.
579     */
580    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
581
582    /**
583     * Constant array of the users that are currently started.
584     */
585    int[] mStartedUserArray = new int[] { 0 };
586
587    /**
588     * Registered observers of the user switching mechanics.
589     */
590    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
591            = new RemoteCallbackList<IUserSwitchObserver>();
592
593    /**
594     * Currently active user switch.
595     */
596    Object mCurUserSwitchCallback;
597
598    /**
599     * Packages that the user has asked to have run in screen size
600     * compatibility mode instead of filling the screen.
601     */
602    final CompatModePackages mCompatModePackages;
603
604    /**
605     * Set of IntentSenderRecord objects that are currently active.
606     */
607    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
608            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
609
610    /**
611     * Fingerprints (hashCode()) of stack traces that we've
612     * already logged DropBox entries for.  Guarded by itself.  If
613     * something (rogue user app) forces this over
614     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
615     */
616    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
617    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
618
619    /**
620     * Strict Mode background batched logging state.
621     *
622     * The string buffer is guarded by itself, and its lock is also
623     * used to determine if another batched write is already
624     * in-flight.
625     */
626    private final StringBuilder mStrictModeBuffer = new StringBuilder();
627
628    /**
629     * Keeps track of all IIntentReceivers that have been registered for
630     * broadcasts.  Hash keys are the receiver IBinder, hash value is
631     * a ReceiverList.
632     */
633    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
634            new HashMap<IBinder, ReceiverList>();
635
636    /**
637     * Resolver for broadcast intents to registered receivers.
638     * Holds BroadcastFilter (subclass of IntentFilter).
639     */
640    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
641            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
642        @Override
643        protected boolean allowFilterResult(
644                BroadcastFilter filter, List<BroadcastFilter> dest) {
645            IBinder target = filter.receiverList.receiver.asBinder();
646            for (int i=dest.size()-1; i>=0; i--) {
647                if (dest.get(i).receiverList.receiver.asBinder() == target) {
648                    return false;
649                }
650            }
651            return true;
652        }
653
654        @Override
655        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
656            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
657                    || userId == filter.owningUserId) {
658                return super.newResult(filter, match, userId);
659            }
660            return null;
661        }
662
663        @Override
664        protected BroadcastFilter[] newArray(int size) {
665            return new BroadcastFilter[size];
666        }
667
668        @Override
669        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
670            return packageName.equals(filter.packageName);
671        }
672    };
673
674    /**
675     * State of all active sticky broadcasts per user.  Keys are the action of the
676     * sticky Intent, values are an ArrayList of all broadcasted intents with
677     * that action (which should usually be one).  The SparseArray is keyed
678     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
679     * for stickies that are sent to all users.
680     */
681    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
682            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
683
684    final ActiveServices mServices;
685
686    /**
687     * Backup/restore process management
688     */
689    String mBackupAppName = null;
690    BackupRecord mBackupTarget = null;
691
692    /**
693     * List of PendingThumbnailsRecord objects of clients who are still
694     * waiting to receive all of the thumbnails for a task.
695     */
696    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
697            new ArrayList<PendingThumbnailsRecord>();
698
699    final ProviderMap mProviderMap;
700
701    /**
702     * List of content providers who have clients waiting for them.  The
703     * application is currently being launched and the provider will be
704     * removed from this list once it is published.
705     */
706    final ArrayList<ContentProviderRecord> mLaunchingProviders
707            = new ArrayList<ContentProviderRecord>();
708
709    /**
710     * File storing persisted {@link #mGrantedUriPermissions}.
711     */
712    private final AtomicFile mGrantFile;
713
714    /** XML constants used in {@link #mGrantFile} */
715    private static final String TAG_URI_GRANTS = "uri-grants";
716    private static final String TAG_URI_GRANT = "uri-grant";
717    private static final String ATTR_USER_HANDLE = "userHandle";
718    private static final String ATTR_SOURCE_PKG = "sourcePkg";
719    private static final String ATTR_TARGET_PKG = "targetPkg";
720    private static final String ATTR_URI = "uri";
721    private static final String ATTR_MODE_FLAGS = "modeFlags";
722    private static final String ATTR_CREATED_TIME = "createdTime";
723
724    /**
725     * Global set of specific {@link Uri} permissions that have been granted.
726     * This optimized lookup structure maps from {@link UriPermission#targetUid}
727     * to {@link UriPermission#uri} to {@link UriPermission}.
728     */
729    @GuardedBy("this")
730    private final SparseArray<ArrayMap<Uri, UriPermission>>
731            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
732
733    CoreSettingsObserver mCoreSettingsObserver;
734
735    /**
736     * Thread-local storage used to carry caller permissions over through
737     * indirect content-provider access.
738     */
739    private class Identity {
740        public int pid;
741        public int uid;
742
743        Identity(int _pid, int _uid) {
744            pid = _pid;
745            uid = _uid;
746        }
747    }
748
749    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
750
751    /**
752     * All information we have collected about the runtime performance of
753     * any user id that can impact battery performance.
754     */
755    final BatteryStatsService mBatteryStatsService;
756
757    /**
758     * Information about component usage
759     */
760    final UsageStatsService mUsageStatsService;
761
762    /**
763     * Information about and control over application operations
764     */
765    final AppOpsService mAppOpsService;
766
767    /**
768     * Current configuration information.  HistoryRecord objects are given
769     * a reference to this object to indicate which configuration they are
770     * currently running in, so this object must be kept immutable.
771     */
772    Configuration mConfiguration = new Configuration();
773
774    /**
775     * Current sequencing integer of the configuration, for skipping old
776     * configurations.
777     */
778    int mConfigurationSeq = 0;
779
780    /**
781     * Hardware-reported OpenGLES version.
782     */
783    final int GL_ES_VERSION;
784
785    /**
786     * List of initialization arguments to pass to all processes when binding applications to them.
787     * For example, references to the commonly used services.
788     */
789    HashMap<String, IBinder> mAppBindArgs;
790
791    /**
792     * Temporary to avoid allocations.  Protected by main lock.
793     */
794    final StringBuilder mStringBuilder = new StringBuilder(256);
795
796    /**
797     * Used to control how we initialize the service.
798     */
799    boolean mStartRunning = false;
800    ComponentName mTopComponent;
801    String mTopAction;
802    String mTopData;
803    boolean mProcessesReady = false;
804    boolean mSystemReady = false;
805    boolean mBooting = false;
806    boolean mWaitingUpdate = false;
807    boolean mDidUpdate = false;
808    boolean mOnBattery = false;
809    boolean mLaunchWarningShown = false;
810
811    Context mContext;
812
813    int mFactoryTest;
814
815    boolean mCheckedForSetup;
816
817    /**
818     * The time at which we will allow normal application switches again,
819     * after a call to {@link #stopAppSwitches()}.
820     */
821    long mAppSwitchesAllowedTime;
822
823    /**
824     * This is set to true after the first switch after mAppSwitchesAllowedTime
825     * is set; any switches after that will clear the time.
826     */
827    boolean mDidAppSwitch;
828
829    /**
830     * Last time (in realtime) at which we checked for power usage.
831     */
832    long mLastPowerCheckRealtime;
833
834    /**
835     * Last time (in uptime) at which we checked for power usage.
836     */
837    long mLastPowerCheckUptime;
838
839    /**
840     * Set while we are wanting to sleep, to prevent any
841     * activities from being started/resumed.
842     */
843    boolean mSleeping = false;
844
845    /**
846     * State of external calls telling us if the device is asleep.
847     */
848    boolean mWentToSleep = false;
849
850    /**
851     * State of external call telling us if the lock screen is shown.
852     */
853    boolean mLockScreenShown = false;
854
855    /**
856     * Set if we are shutting down the system, similar to sleeping.
857     */
858    boolean mShuttingDown = false;
859
860    /**
861     * Current sequence id for oom_adj computation traversal.
862     */
863    int mAdjSeq = 0;
864
865    /**
866     * Current sequence id for process LRU updating.
867     */
868    int mLruSeq = 0;
869
870    /**
871     * Keep track of the non-cached/empty process we last found, to help
872     * determine how to distribute cached/empty processes next time.
873     */
874    int mNumNonCachedProcs = 0;
875
876    /**
877     * Keep track of the number of cached hidden procs, to balance oom adj
878     * distribution between those and empty procs.
879     */
880    int mNumCachedHiddenProcs = 0;
881
882    /**
883     * Keep track of the number of service processes we last found, to
884     * determine on the next iteration which should be B services.
885     */
886    int mNumServiceProcs = 0;
887    int mNewNumAServiceProcs = 0;
888    int mNewNumServiceProcs = 0;
889
890    /**
891     * Allow the current computed overall memory level of the system to go down?
892     * This is set to false when we are killing processes for reasons other than
893     * memory management, so that the now smaller process list will not be taken as
894     * an indication that memory is tighter.
895     */
896    boolean mAllowLowerMemLevel = false;
897
898    /**
899     * The last computed memory level, for holding when we are in a state that
900     * processes are going away for other reasons.
901     */
902    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
903
904    /**
905     * The last total number of process we have, to determine if changes actually look
906     * like a shrinking number of process due to lower RAM.
907     */
908    int mLastNumProcesses;
909
910    /**
911     * The uptime of the last time we performed idle maintenance.
912     */
913    long mLastIdleTime = SystemClock.uptimeMillis();
914
915    /**
916     * Total time spent with RAM that has been added in the past since the last idle time.
917     */
918    long mLowRamTimeSinceLastIdle = 0;
919
920    /**
921     * If RAM is currently low, when that horrible situatin started.
922     */
923    long mLowRamStartTime = 0;
924
925    /**
926     * This is set if we had to do a delayed dexopt of an app before launching
927     * it, to increasing the ANR timeouts in that case.
928     */
929    boolean mDidDexOpt;
930
931    String mDebugApp = null;
932    boolean mWaitForDebugger = false;
933    boolean mDebugTransient = false;
934    String mOrigDebugApp = null;
935    boolean mOrigWaitForDebugger = false;
936    boolean mAlwaysFinishActivities = false;
937    IActivityController mController = null;
938    String mProfileApp = null;
939    ProcessRecord mProfileProc = null;
940    String mProfileFile;
941    ParcelFileDescriptor mProfileFd;
942    int mProfileType = 0;
943    boolean mAutoStopProfiler = false;
944    String mOpenGlTraceApp = null;
945
946    static class ProcessChangeItem {
947        static final int CHANGE_ACTIVITIES = 1<<0;
948        static final int CHANGE_IMPORTANCE= 1<<1;
949        int changes;
950        int uid;
951        int pid;
952        int importance;
953        boolean foregroundActivities;
954    }
955
956    final RemoteCallbackList<IProcessObserver> mProcessObservers
957            = new RemoteCallbackList<IProcessObserver>();
958    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
959
960    final ArrayList<ProcessChangeItem> mPendingProcessChanges
961            = new ArrayList<ProcessChangeItem>();
962    final ArrayList<ProcessChangeItem> mAvailProcessChanges
963            = new ArrayList<ProcessChangeItem>();
964
965    /**
966     * Runtime CPU use collection thread.  This object's lock is used to
967     * protect all related state.
968     */
969    final Thread mProcessCpuThread;
970
971    /**
972     * Used to collect process stats when showing not responding dialog.
973     * Protected by mProcessCpuThread.
974     */
975    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
976            MONITOR_THREAD_CPU_USAGE);
977    final AtomicLong mLastCpuTime = new AtomicLong(0);
978    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
979
980    long mLastWriteTime = 0;
981
982    /**
983     * Used to retain an update lock when the foreground activity is in
984     * immersive mode.
985     */
986    final UpdateLock mUpdateLock = new UpdateLock("immersive");
987
988    /**
989     * Set to true after the system has finished booting.
990     */
991    boolean mBooted = false;
992
993    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
994    int mProcessLimitOverride = -1;
995
996    WindowManagerService mWindowManager;
997
998    static ActivityManagerService mSelf;
999    static ActivityThread mSystemThread;
1000
1001    int mCurrentUserId = 0;
1002    private UserManagerService mUserManager;
1003
1004    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1005        final ProcessRecord mApp;
1006        final int mPid;
1007        final IApplicationThread mAppThread;
1008
1009        AppDeathRecipient(ProcessRecord app, int pid,
1010                IApplicationThread thread) {
1011            if (localLOGV) Slog.v(
1012                TAG, "New death recipient " + this
1013                + " for thread " + thread.asBinder());
1014            mApp = app;
1015            mPid = pid;
1016            mAppThread = thread;
1017        }
1018
1019        @Override
1020        public void binderDied() {
1021            if (localLOGV) Slog.v(
1022                TAG, "Death received in " + this
1023                + " for thread " + mAppThread.asBinder());
1024            synchronized(ActivityManagerService.this) {
1025                appDiedLocked(mApp, mPid, mAppThread);
1026            }
1027        }
1028    }
1029
1030    static final int SHOW_ERROR_MSG = 1;
1031    static final int SHOW_NOT_RESPONDING_MSG = 2;
1032    static final int SHOW_FACTORY_ERROR_MSG = 3;
1033    static final int UPDATE_CONFIGURATION_MSG = 4;
1034    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1035    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1036    static final int SERVICE_TIMEOUT_MSG = 12;
1037    static final int UPDATE_TIME_ZONE = 13;
1038    static final int SHOW_UID_ERROR_MSG = 14;
1039    static final int IM_FEELING_LUCKY_MSG = 15;
1040    static final int PROC_START_TIMEOUT_MSG = 20;
1041    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1042    static final int KILL_APPLICATION_MSG = 22;
1043    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1044    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1045    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1046    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1047    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1048    static final int CLEAR_DNS_CACHE_MSG = 28;
1049    static final int UPDATE_HTTP_PROXY_MSG = 29;
1050    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1051    static final int DISPATCH_PROCESSES_CHANGED = 31;
1052    static final int DISPATCH_PROCESS_DIED = 32;
1053    static final int REPORT_MEM_USAGE_MSG = 33;
1054    static final int REPORT_USER_SWITCH_MSG = 34;
1055    static final int CONTINUE_USER_SWITCH_MSG = 35;
1056    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1057    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1058    static final int PERSIST_URI_GRANTS_MSG = 38;
1059    static final int REQUEST_ALL_PSS_MSG = 39;
1060
1061    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1062    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1063    static final int FIRST_COMPAT_MODE_MSG = 300;
1064    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1065
1066    AlertDialog mUidAlert;
1067    CompatModeDialog mCompatModeDialog;
1068    long mLastMemUsageReportTime = 0;
1069
1070    /**
1071     * Flag whether the current user is a "monkey", i.e. whether
1072     * the UI is driven by a UI automation tool.
1073     */
1074    private boolean mUserIsMonkey;
1075
1076    final Handler mHandler = new Handler() {
1077        //public Handler() {
1078        //    if (localLOGV) Slog.v(TAG, "Handler started!");
1079        //}
1080
1081        @Override
1082        public void handleMessage(Message msg) {
1083            switch (msg.what) {
1084            case SHOW_ERROR_MSG: {
1085                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1086                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1087                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1088                synchronized (ActivityManagerService.this) {
1089                    ProcessRecord proc = (ProcessRecord)data.get("app");
1090                    AppErrorResult res = (AppErrorResult) data.get("result");
1091                    if (proc != null && proc.crashDialog != null) {
1092                        Slog.e(TAG, "App already has crash dialog: " + proc);
1093                        if (res != null) {
1094                            res.set(0);
1095                        }
1096                        return;
1097                    }
1098                    if (!showBackground && UserHandle.getAppId(proc.uid)
1099                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1100                            && proc.pid != MY_PID) {
1101                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1102                        if (res != null) {
1103                            res.set(0);
1104                        }
1105                        return;
1106                    }
1107                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1108                        Dialog d = new AppErrorDialog(mContext,
1109                                ActivityManagerService.this, res, proc);
1110                        d.show();
1111                        proc.crashDialog = d;
1112                    } else {
1113                        // The device is asleep, so just pretend that the user
1114                        // saw a crash dialog and hit "force quit".
1115                        if (res != null) {
1116                            res.set(0);
1117                        }
1118                    }
1119                }
1120
1121                ensureBootCompleted();
1122            } break;
1123            case SHOW_NOT_RESPONDING_MSG: {
1124                synchronized (ActivityManagerService.this) {
1125                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1126                    ProcessRecord proc = (ProcessRecord)data.get("app");
1127                    if (proc != null && proc.anrDialog != null) {
1128                        Slog.e(TAG, "App already has anr dialog: " + proc);
1129                        return;
1130                    }
1131
1132                    Intent intent = new Intent("android.intent.action.ANR");
1133                    if (!mProcessesReady) {
1134                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1135                                | Intent.FLAG_RECEIVER_FOREGROUND);
1136                    }
1137                    broadcastIntentLocked(null, null, intent,
1138                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1139                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1140
1141                    if (mShowDialogs) {
1142                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1143                                mContext, proc, (ActivityRecord)data.get("activity"),
1144                                msg.arg1 != 0);
1145                        d.show();
1146                        proc.anrDialog = d;
1147                    } else {
1148                        // Just kill the app if there is no dialog to be shown.
1149                        killAppAtUsersRequest(proc, null);
1150                    }
1151                }
1152
1153                ensureBootCompleted();
1154            } break;
1155            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1156                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1157                synchronized (ActivityManagerService.this) {
1158                    ProcessRecord proc = (ProcessRecord) data.get("app");
1159                    if (proc == null) {
1160                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1161                        break;
1162                    }
1163                    if (proc.crashDialog != null) {
1164                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1165                        return;
1166                    }
1167                    AppErrorResult res = (AppErrorResult) data.get("result");
1168                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1169                        Dialog d = new StrictModeViolationDialog(mContext,
1170                                ActivityManagerService.this, res, proc);
1171                        d.show();
1172                        proc.crashDialog = d;
1173                    } else {
1174                        // The device is asleep, so just pretend that the user
1175                        // saw a crash dialog and hit "force quit".
1176                        res.set(0);
1177                    }
1178                }
1179                ensureBootCompleted();
1180            } break;
1181            case SHOW_FACTORY_ERROR_MSG: {
1182                Dialog d = new FactoryErrorDialog(
1183                    mContext, msg.getData().getCharSequence("msg"));
1184                d.show();
1185                ensureBootCompleted();
1186            } break;
1187            case UPDATE_CONFIGURATION_MSG: {
1188                final ContentResolver resolver = mContext.getContentResolver();
1189                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1190            } break;
1191            case GC_BACKGROUND_PROCESSES_MSG: {
1192                synchronized (ActivityManagerService.this) {
1193                    performAppGcsIfAppropriateLocked();
1194                }
1195            } break;
1196            case WAIT_FOR_DEBUGGER_MSG: {
1197                synchronized (ActivityManagerService.this) {
1198                    ProcessRecord app = (ProcessRecord)msg.obj;
1199                    if (msg.arg1 != 0) {
1200                        if (!app.waitedForDebugger) {
1201                            Dialog d = new AppWaitingForDebuggerDialog(
1202                                    ActivityManagerService.this,
1203                                    mContext, app);
1204                            app.waitDialog = d;
1205                            app.waitedForDebugger = true;
1206                            d.show();
1207                        }
1208                    } else {
1209                        if (app.waitDialog != null) {
1210                            app.waitDialog.dismiss();
1211                            app.waitDialog = null;
1212                        }
1213                    }
1214                }
1215            } break;
1216            case SERVICE_TIMEOUT_MSG: {
1217                if (mDidDexOpt) {
1218                    mDidDexOpt = false;
1219                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1220                    nmsg.obj = msg.obj;
1221                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1222                    return;
1223                }
1224                mServices.serviceTimeout((ProcessRecord)msg.obj);
1225            } break;
1226            case UPDATE_TIME_ZONE: {
1227                synchronized (ActivityManagerService.this) {
1228                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1229                        ProcessRecord r = mLruProcesses.get(i);
1230                        if (r.thread != null) {
1231                            try {
1232                                r.thread.updateTimeZone();
1233                            } catch (RemoteException ex) {
1234                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1235                            }
1236                        }
1237                    }
1238                }
1239            } break;
1240            case CLEAR_DNS_CACHE_MSG: {
1241                synchronized (ActivityManagerService.this) {
1242                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1243                        ProcessRecord r = mLruProcesses.get(i);
1244                        if (r.thread != null) {
1245                            try {
1246                                r.thread.clearDnsCache();
1247                            } catch (RemoteException ex) {
1248                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1249                            }
1250                        }
1251                    }
1252                }
1253            } break;
1254            case UPDATE_HTTP_PROXY_MSG: {
1255                ProxyProperties proxy = (ProxyProperties)msg.obj;
1256                String host = "";
1257                String port = "";
1258                String exclList = "";
1259                String pacFileUrl = null;
1260                if (proxy != null) {
1261                    host = proxy.getHost();
1262                    port = Integer.toString(proxy.getPort());
1263                    exclList = proxy.getExclusionList();
1264                    pacFileUrl = proxy.getPacFileUrl();
1265                }
1266                synchronized (ActivityManagerService.this) {
1267                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1268                        ProcessRecord r = mLruProcesses.get(i);
1269                        if (r.thread != null) {
1270                            try {
1271                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1272                            } catch (RemoteException ex) {
1273                                Slog.w(TAG, "Failed to update http proxy for: " +
1274                                        r.info.processName);
1275                            }
1276                        }
1277                    }
1278                }
1279            } break;
1280            case SHOW_UID_ERROR_MSG: {
1281                String title = "System UIDs Inconsistent";
1282                String text = "UIDs on the system are inconsistent, you need to wipe your"
1283                        + " data partition or your device will be unstable.";
1284                Log.e(TAG, title + ": " + text);
1285                if (mShowDialogs) {
1286                    // XXX This is a temporary dialog, no need to localize.
1287                    AlertDialog d = new BaseErrorDialog(mContext);
1288                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1289                    d.setCancelable(false);
1290                    d.setTitle(title);
1291                    d.setMessage(text);
1292                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1293                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1294                    mUidAlert = d;
1295                    d.show();
1296                }
1297            } break;
1298            case IM_FEELING_LUCKY_MSG: {
1299                if (mUidAlert != null) {
1300                    mUidAlert.dismiss();
1301                    mUidAlert = null;
1302                }
1303            } break;
1304            case PROC_START_TIMEOUT_MSG: {
1305                if (mDidDexOpt) {
1306                    mDidDexOpt = false;
1307                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1308                    nmsg.obj = msg.obj;
1309                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1310                    return;
1311                }
1312                ProcessRecord app = (ProcessRecord)msg.obj;
1313                synchronized (ActivityManagerService.this) {
1314                    processStartTimedOutLocked(app);
1315                }
1316            } break;
1317            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1318                synchronized (ActivityManagerService.this) {
1319                    doPendingActivityLaunchesLocked(true);
1320                }
1321            } break;
1322            case KILL_APPLICATION_MSG: {
1323                synchronized (ActivityManagerService.this) {
1324                    int appid = msg.arg1;
1325                    boolean restart = (msg.arg2 == 1);
1326                    Bundle bundle = (Bundle)msg.obj;
1327                    String pkg = bundle.getString("pkg");
1328                    String reason = bundle.getString("reason");
1329                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1330                            UserHandle.USER_ALL, reason);
1331                }
1332            } break;
1333            case FINALIZE_PENDING_INTENT_MSG: {
1334                ((PendingIntentRecord)msg.obj).completeFinalize();
1335            } break;
1336            case POST_HEAVY_NOTIFICATION_MSG: {
1337                INotificationManager inm = NotificationManager.getService();
1338                if (inm == null) {
1339                    return;
1340                }
1341
1342                ActivityRecord root = (ActivityRecord)msg.obj;
1343                ProcessRecord process = root.app;
1344                if (process == null) {
1345                    return;
1346                }
1347
1348                try {
1349                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1350                    String text = mContext.getString(R.string.heavy_weight_notification,
1351                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1352                    Notification notification = new Notification();
1353                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1354                    notification.when = 0;
1355                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1356                    notification.tickerText = text;
1357                    notification.defaults = 0; // please be quiet
1358                    notification.sound = null;
1359                    notification.vibrate = null;
1360                    notification.setLatestEventInfo(context, text,
1361                            mContext.getText(R.string.heavy_weight_notification_detail),
1362                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1363                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1364                                    new UserHandle(root.userId)));
1365
1366                    try {
1367                        int[] outId = new int[1];
1368                        inm.enqueueNotificationWithTag("android", "android", null,
1369                                R.string.heavy_weight_notification,
1370                                notification, outId, root.userId);
1371                    } catch (RuntimeException e) {
1372                        Slog.w(ActivityManagerService.TAG,
1373                                "Error showing notification for heavy-weight app", e);
1374                    } catch (RemoteException e) {
1375                    }
1376                } catch (NameNotFoundException e) {
1377                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1378                }
1379            } break;
1380            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1381                INotificationManager inm = NotificationManager.getService();
1382                if (inm == null) {
1383                    return;
1384                }
1385                try {
1386                    inm.cancelNotificationWithTag("android", null,
1387                            R.string.heavy_weight_notification,  msg.arg1);
1388                } catch (RuntimeException e) {
1389                    Slog.w(ActivityManagerService.TAG,
1390                            "Error canceling notification for service", e);
1391                } catch (RemoteException e) {
1392                }
1393            } break;
1394            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1395                synchronized (ActivityManagerService.this) {
1396                    checkExcessivePowerUsageLocked(true);
1397                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1398                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1399                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1400                }
1401            } break;
1402            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1403                synchronized (ActivityManagerService.this) {
1404                    ActivityRecord ar = (ActivityRecord)msg.obj;
1405                    if (mCompatModeDialog != null) {
1406                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1407                                ar.info.applicationInfo.packageName)) {
1408                            return;
1409                        }
1410                        mCompatModeDialog.dismiss();
1411                        mCompatModeDialog = null;
1412                    }
1413                    if (ar != null && false) {
1414                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1415                                ar.packageName)) {
1416                            int mode = mCompatModePackages.computeCompatModeLocked(
1417                                    ar.info.applicationInfo);
1418                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1419                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1420                                mCompatModeDialog = new CompatModeDialog(
1421                                        ActivityManagerService.this, mContext,
1422                                        ar.info.applicationInfo);
1423                                mCompatModeDialog.show();
1424                            }
1425                        }
1426                    }
1427                }
1428                break;
1429            }
1430            case DISPATCH_PROCESSES_CHANGED: {
1431                dispatchProcessesChanged();
1432                break;
1433            }
1434            case DISPATCH_PROCESS_DIED: {
1435                final int pid = msg.arg1;
1436                final int uid = msg.arg2;
1437                dispatchProcessDied(pid, uid);
1438                break;
1439            }
1440            case REPORT_MEM_USAGE_MSG: {
1441                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1442                Thread thread = new Thread() {
1443                    @Override public void run() {
1444                        final SparseArray<ProcessMemInfo> infoMap
1445                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1446                        for (int i=0, N=memInfos.size(); i<N; i++) {
1447                            ProcessMemInfo mi = memInfos.get(i);
1448                            infoMap.put(mi.pid, mi);
1449                        }
1450                        updateCpuStatsNow();
1451                        synchronized (mProcessCpuThread) {
1452                            final int N = mProcessCpuTracker.countStats();
1453                            for (int i=0; i<N; i++) {
1454                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1455                                if (st.vsize > 0) {
1456                                    long pss = Debug.getPss(st.pid, null);
1457                                    if (pss > 0) {
1458                                        if (infoMap.indexOfKey(st.pid) < 0) {
1459                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1460                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1461                                            mi.pss = pss;
1462                                            memInfos.add(mi);
1463                                        }
1464                                    }
1465                                }
1466                            }
1467                        }
1468
1469                        long totalPss = 0;
1470                        for (int i=0, N=memInfos.size(); i<N; i++) {
1471                            ProcessMemInfo mi = memInfos.get(i);
1472                            if (mi.pss == 0) {
1473                                mi.pss = Debug.getPss(mi.pid, null);
1474                            }
1475                            totalPss += mi.pss;
1476                        }
1477                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1478                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1479                                if (lhs.oomAdj != rhs.oomAdj) {
1480                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1481                                }
1482                                if (lhs.pss != rhs.pss) {
1483                                    return lhs.pss < rhs.pss ? 1 : -1;
1484                                }
1485                                return 0;
1486                            }
1487                        });
1488
1489                        StringBuilder tag = new StringBuilder(128);
1490                        StringBuilder stack = new StringBuilder(128);
1491                        tag.append("Low on memory -- ");
1492                        appendMemBucket(tag, totalPss, "total", false);
1493                        appendMemBucket(stack, totalPss, "total", true);
1494
1495                        StringBuilder logBuilder = new StringBuilder(1024);
1496                        logBuilder.append("Low on memory:\n");
1497
1498                        boolean firstLine = true;
1499                        int lastOomAdj = Integer.MIN_VALUE;
1500                        for (int i=0, N=memInfos.size(); i<N; i++) {
1501                            ProcessMemInfo mi = memInfos.get(i);
1502
1503                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1504                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1505                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1506                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1507                                if (lastOomAdj != mi.oomAdj) {
1508                                    lastOomAdj = mi.oomAdj;
1509                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1510                                        tag.append(" / ");
1511                                    }
1512                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1513                                        if (firstLine) {
1514                                            stack.append(":");
1515                                            firstLine = false;
1516                                        }
1517                                        stack.append("\n\t at ");
1518                                    } else {
1519                                        stack.append("$");
1520                                    }
1521                                } else {
1522                                    tag.append(" ");
1523                                    stack.append("$");
1524                                }
1525                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1526                                    appendMemBucket(tag, mi.pss, mi.name, false);
1527                                }
1528                                appendMemBucket(stack, mi.pss, mi.name, true);
1529                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1530                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1531                                    stack.append("(");
1532                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1533                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1534                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1535                                            stack.append(":");
1536                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1537                                        }
1538                                    }
1539                                    stack.append(")");
1540                                }
1541                            }
1542
1543                            logBuilder.append("  ");
1544                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1545                            logBuilder.append(' ');
1546                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1547                            logBuilder.append(' ');
1548                            ProcessList.appendRamKb(logBuilder, mi.pss);
1549                            logBuilder.append(" kB: ");
1550                            logBuilder.append(mi.name);
1551                            logBuilder.append(" (");
1552                            logBuilder.append(mi.pid);
1553                            logBuilder.append(") ");
1554                            logBuilder.append(mi.adjType);
1555                            logBuilder.append('\n');
1556                            if (mi.adjReason != null) {
1557                                logBuilder.append("                      ");
1558                                logBuilder.append(mi.adjReason);
1559                                logBuilder.append('\n');
1560                            }
1561                        }
1562
1563                        logBuilder.append("           ");
1564                        ProcessList.appendRamKb(logBuilder, totalPss);
1565                        logBuilder.append(" kB: TOTAL\n");
1566
1567                        long[] infos = new long[Debug.MEMINFO_COUNT];
1568                        Debug.getMemInfo(infos);
1569                        logBuilder.append("  MemInfo: ");
1570                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1571                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1572                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1573                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1574                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1575                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1576                            logBuilder.append("  ZRAM: ");
1577                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1578                            logBuilder.append(" kB RAM, ");
1579                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1580                            logBuilder.append(" kB swap total, ");
1581                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1582                            logBuilder.append(" kB swap free\n");
1583                        }
1584                        Slog.i(TAG, logBuilder.toString());
1585
1586                        StringBuilder dropBuilder = new StringBuilder(1024);
1587                        /*
1588                        StringWriter oomSw = new StringWriter();
1589                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1590                        StringWriter catSw = new StringWriter();
1591                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1592                        String[] emptyArgs = new String[] { };
1593                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1594                        oomPw.flush();
1595                        String oomString = oomSw.toString();
1596                        */
1597                        dropBuilder.append(stack);
1598                        dropBuilder.append('\n');
1599                        dropBuilder.append('\n');
1600                        dropBuilder.append(logBuilder);
1601                        dropBuilder.append('\n');
1602                        /*
1603                        dropBuilder.append(oomString);
1604                        dropBuilder.append('\n');
1605                        */
1606                        StringWriter catSw = new StringWriter();
1607                        synchronized (ActivityManagerService.this) {
1608                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1609                            String[] emptyArgs = new String[] { };
1610                            catPw.println();
1611                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1612                            catPw.println();
1613                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1614                                    false, false, null);
1615                            catPw.println();
1616                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1617                            catPw.flush();
1618                        }
1619                        dropBuilder.append(catSw.toString());
1620                        addErrorToDropBox("lowmem", null, "system_server", null,
1621                                null, tag.toString(), dropBuilder.toString(), null, null);
1622                        //Slog.i(TAG, "Sent to dropbox:");
1623                        //Slog.i(TAG, dropBuilder.toString());
1624                        synchronized (ActivityManagerService.this) {
1625                            long now = SystemClock.uptimeMillis();
1626                            if (mLastMemUsageReportTime < now) {
1627                                mLastMemUsageReportTime = now;
1628                            }
1629                        }
1630                    }
1631                };
1632                thread.start();
1633                break;
1634            }
1635            case REPORT_USER_SWITCH_MSG: {
1636                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1637                break;
1638            }
1639            case CONTINUE_USER_SWITCH_MSG: {
1640                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1641                break;
1642            }
1643            case USER_SWITCH_TIMEOUT_MSG: {
1644                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1645                break;
1646            }
1647            case IMMERSIVE_MODE_LOCK_MSG: {
1648                final boolean nextState = (msg.arg1 != 0);
1649                if (mUpdateLock.isHeld() != nextState) {
1650                    if (DEBUG_IMMERSIVE) {
1651                        final ActivityRecord r = (ActivityRecord) msg.obj;
1652                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1653                    }
1654                    if (nextState) {
1655                        mUpdateLock.acquire();
1656                    } else {
1657                        mUpdateLock.release();
1658                    }
1659                }
1660                break;
1661            }
1662            case PERSIST_URI_GRANTS_MSG: {
1663                writeGrantedUriPermissions();
1664                break;
1665            }
1666            case REQUEST_ALL_PSS_MSG: {
1667                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1668                break;
1669            }
1670            }
1671        }
1672    };
1673
1674    static final int COLLECT_PSS_BG_MSG = 1;
1675
1676    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1677        @Override
1678        public void handleMessage(Message msg) {
1679            switch (msg.what) {
1680            case COLLECT_PSS_BG_MSG: {
1681                int i=0, num=0;
1682                long start = SystemClock.uptimeMillis();
1683                long[] tmp = new long[1];
1684                do {
1685                    ProcessRecord proc;
1686                    int procState;
1687                    int pid;
1688                    synchronized (ActivityManagerService.this) {
1689                        if (i >= mPendingPssProcesses.size()) {
1690                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1691                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1692                            mPendingPssProcesses.clear();
1693                            return;
1694                        }
1695                        proc = mPendingPssProcesses.get(i);
1696                        procState = proc.pssProcState;
1697                        if (proc.thread != null && procState == proc.setProcState) {
1698                            pid = proc.pid;
1699                        } else {
1700                            proc = null;
1701                            pid = 0;
1702                        }
1703                        i++;
1704                    }
1705                    if (proc != null) {
1706                        long pss = Debug.getPss(pid, tmp);
1707                        synchronized (ActivityManagerService.this) {
1708                            if (proc.thread != null && proc.setProcState == procState
1709                                    && proc.pid == pid) {
1710                                num++;
1711                                proc.lastPssTime = SystemClock.uptimeMillis();
1712                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1713                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1714                                        + ": " + pss + " lastPss=" + proc.lastPss
1715                                        + " state=" + ProcessList.makeProcStateString(procState));
1716                                if (proc.initialIdlePss == 0) {
1717                                    proc.initialIdlePss = pss;
1718                                }
1719                                proc.lastPss = pss;
1720                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1721                                    proc.lastCachedPss = pss;
1722                                }
1723                            }
1724                        }
1725                    }
1726                } while (true);
1727            }
1728            }
1729        }
1730    };
1731
1732    public static void setSystemProcess() {
1733        try {
1734            ActivityManagerService m = mSelf;
1735
1736            ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true);
1737            ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats);
1738            ServiceManager.addService("meminfo", new MemBinder(m));
1739            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1740            ServiceManager.addService("dbinfo", new DbBinder(m));
1741            if (MONITOR_CPU_USAGE) {
1742                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1743            }
1744            ServiceManager.addService("permission", new PermissionController(m));
1745
1746            ApplicationInfo info =
1747                mSelf.mContext.getPackageManager().getApplicationInfo(
1748                            "android", STOCK_PM_FLAGS);
1749            mSystemThread.installSystemApplicationInfo(info);
1750
1751            synchronized (mSelf) {
1752                ProcessRecord app = mSelf.newProcessRecordLocked(info,
1753                        info.processName, false);
1754                app.persistent = true;
1755                app.pid = MY_PID;
1756                app.maxAdj = ProcessList.SYSTEM_ADJ;
1757                app.makeActive(mSystemThread.getApplicationThread(), mSelf.mProcessStats);
1758                mSelf.mProcessNames.put(app.processName, app.uid, app);
1759                synchronized (mSelf.mPidsSelfLocked) {
1760                    mSelf.mPidsSelfLocked.put(app.pid, app);
1761                }
1762                mSelf.updateLruProcessLocked(app, false, null);
1763                mSelf.updateOomAdjLocked();
1764            }
1765        } catch (PackageManager.NameNotFoundException e) {
1766            throw new RuntimeException(
1767                    "Unable to find android system package", e);
1768        }
1769    }
1770
1771    public void setWindowManager(WindowManagerService wm) {
1772        mWindowManager = wm;
1773        mStackSupervisor.setWindowManager(wm);
1774    }
1775
1776    public void startObservingNativeCrashes() {
1777        final NativeCrashListener ncl = new NativeCrashListener();
1778        ncl.start();
1779    }
1780
1781    public static final Context main(int factoryTest) {
1782        AThread thr = new AThread();
1783        thr.start();
1784
1785        synchronized (thr) {
1786            while (thr.mService == null) {
1787                try {
1788                    thr.wait();
1789                } catch (InterruptedException e) {
1790                }
1791            }
1792        }
1793
1794        ActivityManagerService m = thr.mService;
1795        mSelf = m;
1796        ActivityThread at = ActivityThread.systemMain();
1797        mSystemThread = at;
1798        Context context = at.getSystemContext();
1799        context.setTheme(android.R.style.Theme_Holo);
1800        m.mContext = context;
1801        m.mFactoryTest = factoryTest;
1802        m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface());
1803
1804        m.mStackSupervisor = new ActivityStackSupervisor(m);
1805
1806        m.mBatteryStatsService.publish(context);
1807        m.mUsageStatsService.publish(context);
1808        m.mAppOpsService.publish(context);
1809
1810        synchronized (thr) {
1811            thr.mReady = true;
1812            thr.notifyAll();
1813        }
1814
1815        m.startRunning(null, null, null, null);
1816
1817        return context;
1818    }
1819
1820    public static ActivityManagerService self() {
1821        return mSelf;
1822    }
1823
1824    public IAppOpsService getAppOpsService() {
1825        return mAppOpsService;
1826    }
1827
1828    static class AThread extends Thread {
1829        ActivityManagerService mService;
1830        Looper mLooper;
1831        boolean mReady = false;
1832
1833        public AThread() {
1834            super("ActivityManager");
1835        }
1836
1837        @Override
1838        public void run() {
1839            Looper.prepare();
1840
1841            android.os.Process.setThreadPriority(
1842                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1843            android.os.Process.setCanSelfBackground(false);
1844
1845            ActivityManagerService m = new ActivityManagerService();
1846
1847            synchronized (this) {
1848                mService = m;
1849                mLooper = Looper.myLooper();
1850                Watchdog.getInstance().addThread(new Handler(mLooper), getName());
1851                notifyAll();
1852            }
1853
1854            synchronized (this) {
1855                while (!mReady) {
1856                    try {
1857                        wait();
1858                    } catch (InterruptedException e) {
1859                    }
1860                }
1861            }
1862
1863            // For debug builds, log event loop stalls to dropbox for analysis.
1864            if (StrictMode.conditionallyEnableDebugLogging()) {
1865                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1866            }
1867
1868            Looper.loop();
1869        }
1870    }
1871
1872    static class MemBinder extends Binder {
1873        ActivityManagerService mActivityManagerService;
1874        MemBinder(ActivityManagerService activityManagerService) {
1875            mActivityManagerService = activityManagerService;
1876        }
1877
1878        @Override
1879        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1880            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1881                    != PackageManager.PERMISSION_GRANTED) {
1882                pw.println("Permission Denial: can't dump meminfo from from pid="
1883                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1884                        + " without permission " + android.Manifest.permission.DUMP);
1885                return;
1886            }
1887
1888            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1889        }
1890    }
1891
1892    static class GraphicsBinder extends Binder {
1893        ActivityManagerService mActivityManagerService;
1894        GraphicsBinder(ActivityManagerService activityManagerService) {
1895            mActivityManagerService = activityManagerService;
1896        }
1897
1898        @Override
1899        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1900            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1901                    != PackageManager.PERMISSION_GRANTED) {
1902                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1903                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1904                        + " without permission " + android.Manifest.permission.DUMP);
1905                return;
1906            }
1907
1908            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1909        }
1910    }
1911
1912    static class DbBinder extends Binder {
1913        ActivityManagerService mActivityManagerService;
1914        DbBinder(ActivityManagerService activityManagerService) {
1915            mActivityManagerService = activityManagerService;
1916        }
1917
1918        @Override
1919        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1920            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1921                    != PackageManager.PERMISSION_GRANTED) {
1922                pw.println("Permission Denial: can't dump dbinfo from from pid="
1923                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1924                        + " without permission " + android.Manifest.permission.DUMP);
1925                return;
1926            }
1927
1928            mActivityManagerService.dumpDbInfo(fd, pw, args);
1929        }
1930    }
1931
1932    static class CpuBinder extends Binder {
1933        ActivityManagerService mActivityManagerService;
1934        CpuBinder(ActivityManagerService activityManagerService) {
1935            mActivityManagerService = activityManagerService;
1936        }
1937
1938        @Override
1939        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1940            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1941                    != PackageManager.PERMISSION_GRANTED) {
1942                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1943                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1944                        + " without permission " + android.Manifest.permission.DUMP);
1945                return;
1946            }
1947
1948            synchronized (mActivityManagerService.mProcessCpuThread) {
1949                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1950                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1951                        SystemClock.uptimeMillis()));
1952            }
1953        }
1954    }
1955
1956    private ActivityManagerService() {
1957        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1958
1959        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT, false);
1960        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT, true);
1961        mBroadcastQueues[0] = mFgBroadcastQueue;
1962        mBroadcastQueues[1] = mBgBroadcastQueue;
1963
1964        mServices = new ActiveServices(this);
1965        mProviderMap = new ProviderMap(this);
1966
1967        File dataDir = Environment.getDataDirectory();
1968        File systemDir = new File(dataDir, "system");
1969        systemDir.mkdirs();
1970        mBatteryStatsService = new BatteryStatsService(new File(
1971                systemDir, "batterystats.bin").toString());
1972        mBatteryStatsService.getActiveStatistics().readLocked();
1973        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1974        mOnBattery = DEBUG_POWER ? true
1975                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1976        mBatteryStatsService.getActiveStatistics().setCallback(this);
1977
1978        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1979
1980        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1981        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"));
1982
1983        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1984
1985        // User 0 is the first and only user that runs at boot.
1986        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1987        mUserLru.add(Integer.valueOf(0));
1988        updateStartedUserArrayLocked();
1989
1990        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1991            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1992
1993        mConfiguration.setToDefaults();
1994        mConfiguration.setLocale(Locale.getDefault());
1995
1996        mConfigurationSeq = mConfiguration.seq = 1;
1997        mProcessCpuTracker.init();
1998
1999        mCompatModePackages = new CompatModePackages(this, systemDir);
2000
2001        // Add ourself to the Watchdog monitors.
2002        Watchdog.getInstance().addMonitor(this);
2003
2004        mProcessCpuThread = new Thread("CpuTracker") {
2005            @Override
2006            public void run() {
2007                while (true) {
2008                    try {
2009                        try {
2010                            synchronized(this) {
2011                                final long now = SystemClock.uptimeMillis();
2012                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2013                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2014                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2015                                //        + ", write delay=" + nextWriteDelay);
2016                                if (nextWriteDelay < nextCpuDelay) {
2017                                    nextCpuDelay = nextWriteDelay;
2018                                }
2019                                if (nextCpuDelay > 0) {
2020                                    mProcessCpuMutexFree.set(true);
2021                                    this.wait(nextCpuDelay);
2022                                }
2023                            }
2024                        } catch (InterruptedException e) {
2025                        }
2026                        updateCpuStatsNow();
2027                    } catch (Exception e) {
2028                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2029                    }
2030                }
2031            }
2032        };
2033        mProcessCpuThread.start();
2034    }
2035
2036    @Override
2037    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2038            throws RemoteException {
2039        if (code == SYSPROPS_TRANSACTION) {
2040            // We need to tell all apps about the system property change.
2041            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2042            synchronized(this) {
2043                final int NP = mProcessNames.getMap().size();
2044                for (int ip=0; ip<NP; ip++) {
2045                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2046                    final int NA = apps.size();
2047                    for (int ia=0; ia<NA; ia++) {
2048                        ProcessRecord app = apps.valueAt(ia);
2049                        if (app.thread != null) {
2050                            procs.add(app.thread.asBinder());
2051                        }
2052                    }
2053                }
2054            }
2055
2056            int N = procs.size();
2057            for (int i=0; i<N; i++) {
2058                Parcel data2 = Parcel.obtain();
2059                try {
2060                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2061                } catch (RemoteException e) {
2062                }
2063                data2.recycle();
2064            }
2065        }
2066        try {
2067            return super.onTransact(code, data, reply, flags);
2068        } catch (RuntimeException e) {
2069            // The activity manager only throws security exceptions, so let's
2070            // log all others.
2071            if (!(e instanceof SecurityException)) {
2072                Slog.wtf(TAG, "Activity Manager Crash", e);
2073            }
2074            throw e;
2075        }
2076    }
2077
2078    void updateCpuStats() {
2079        final long now = SystemClock.uptimeMillis();
2080        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2081            return;
2082        }
2083        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2084            synchronized (mProcessCpuThread) {
2085                mProcessCpuThread.notify();
2086            }
2087        }
2088    }
2089
2090    void updateCpuStatsNow() {
2091        synchronized (mProcessCpuThread) {
2092            mProcessCpuMutexFree.set(false);
2093            final long now = SystemClock.uptimeMillis();
2094            boolean haveNewCpuStats = false;
2095
2096            if (MONITOR_CPU_USAGE &&
2097                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2098                mLastCpuTime.set(now);
2099                haveNewCpuStats = true;
2100                mProcessCpuTracker.update();
2101                //Slog.i(TAG, mProcessCpu.printCurrentState());
2102                //Slog.i(TAG, "Total CPU usage: "
2103                //        + mProcessCpu.getTotalCpuPercent() + "%");
2104
2105                // Slog the cpu usage if the property is set.
2106                if ("true".equals(SystemProperties.get("events.cpu"))) {
2107                    int user = mProcessCpuTracker.getLastUserTime();
2108                    int system = mProcessCpuTracker.getLastSystemTime();
2109                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2110                    int irq = mProcessCpuTracker.getLastIrqTime();
2111                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2112                    int idle = mProcessCpuTracker.getLastIdleTime();
2113
2114                    int total = user + system + iowait + irq + softIrq + idle;
2115                    if (total == 0) total = 1;
2116
2117                    EventLog.writeEvent(EventLogTags.CPU,
2118                            ((user+system+iowait+irq+softIrq) * 100) / total,
2119                            (user * 100) / total,
2120                            (system * 100) / total,
2121                            (iowait * 100) / total,
2122                            (irq * 100) / total,
2123                            (softIrq * 100) / total);
2124                }
2125            }
2126
2127            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2128            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2129            synchronized(bstats) {
2130                synchronized(mPidsSelfLocked) {
2131                    if (haveNewCpuStats) {
2132                        if (mOnBattery) {
2133                            int perc = bstats.startAddingCpuLocked();
2134                            int totalUTime = 0;
2135                            int totalSTime = 0;
2136                            final int N = mProcessCpuTracker.countStats();
2137                            for (int i=0; i<N; i++) {
2138                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2139                                if (!st.working) {
2140                                    continue;
2141                                }
2142                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2143                                int otherUTime = (st.rel_utime*perc)/100;
2144                                int otherSTime = (st.rel_stime*perc)/100;
2145                                totalUTime += otherUTime;
2146                                totalSTime += otherSTime;
2147                                if (pr != null) {
2148                                    BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked(
2149                                            st.name, st.pid);
2150                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2151                                            st.rel_stime-otherSTime);
2152                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2153                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2154                                } else if (st.uid >= Process.FIRST_APPLICATION_UID) {
2155                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2156                                    if (ps == null) {
2157                                        st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid,
2158                                                "(Unknown)");
2159                                    }
2160                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2161                                            st.rel_stime-otherSTime);
2162                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2163                                } else {
2164                                    BatteryStatsImpl.Uid.Proc ps =
2165                                            bstats.getProcessStatsLocked(st.name, st.pid);
2166                                    if (ps != null) {
2167                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2168                                                st.rel_stime-otherSTime);
2169                                        ps.addSpeedStepTimes(cpuSpeedTimes);
2170                                    }
2171                                }
2172                            }
2173                            bstats.finishAddingCpuLocked(perc, totalUTime,
2174                                    totalSTime, cpuSpeedTimes);
2175                        }
2176                    }
2177                }
2178
2179                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2180                    mLastWriteTime = now;
2181                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2182                }
2183            }
2184        }
2185    }
2186
2187    @Override
2188    public void batteryNeedsCpuUpdate() {
2189        updateCpuStatsNow();
2190    }
2191
2192    @Override
2193    public void batteryPowerChanged(boolean onBattery) {
2194        // When plugging in, update the CPU stats first before changing
2195        // the plug state.
2196        updateCpuStatsNow();
2197        synchronized (this) {
2198            synchronized(mPidsSelfLocked) {
2199                mOnBattery = DEBUG_POWER ? true : onBattery;
2200            }
2201        }
2202    }
2203
2204    /**
2205     * Initialize the application bind args. These are passed to each
2206     * process when the bindApplication() IPC is sent to the process. They're
2207     * lazily setup to make sure the services are running when they're asked for.
2208     */
2209    private HashMap<String, IBinder> getCommonServicesLocked() {
2210        if (mAppBindArgs == null) {
2211            mAppBindArgs = new HashMap<String, IBinder>();
2212
2213            // Setup the application init args
2214            mAppBindArgs.put("package", ServiceManager.getService("package"));
2215            mAppBindArgs.put("window", ServiceManager.getService("window"));
2216            mAppBindArgs.put(Context.ALARM_SERVICE,
2217                    ServiceManager.getService(Context.ALARM_SERVICE));
2218        }
2219        return mAppBindArgs;
2220    }
2221
2222    final void setFocusedActivityLocked(ActivityRecord r) {
2223        if (mFocusedActivity != r) {
2224            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2225            mFocusedActivity = r;
2226            mStackSupervisor.setFocusedStack(r);
2227            if (r != null) {
2228                mWindowManager.setFocusedApp(r.appToken, true);
2229            }
2230            applyUpdateLockStateLocked(r);
2231        }
2232    }
2233
2234    @Override
2235    public void setFocusedStack(int stackId) {
2236        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2237        synchronized (ActivityManagerService.this) {
2238            ActivityStack stack = mStackSupervisor.getStack(stackId);
2239            if (stack != null) {
2240                ActivityRecord r = stack.topRunningActivityLocked(null);
2241                if (r != null) {
2242                    setFocusedActivityLocked(r);
2243                }
2244            }
2245        }
2246    }
2247
2248    @Override
2249    public void notifyActivityDrawn(IBinder token) {
2250        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2251        synchronized (this) {
2252            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2253            if (r != null) {
2254                r.task.stack.notifyActivityDrawnLocked(r);
2255            }
2256        }
2257    }
2258
2259    final void applyUpdateLockStateLocked(ActivityRecord r) {
2260        // Modifications to the UpdateLock state are done on our handler, outside
2261        // the activity manager's locks.  The new state is determined based on the
2262        // state *now* of the relevant activity record.  The object is passed to
2263        // the handler solely for logging detail, not to be consulted/modified.
2264        final boolean nextState = r != null && r.immersive;
2265        mHandler.sendMessage(
2266                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2267    }
2268
2269    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2270        Message msg = Message.obtain();
2271        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2272        msg.obj = r.task.askedCompatMode ? null : r;
2273        mHandler.sendMessage(msg);
2274    }
2275
2276    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2277            String what, Object obj, ProcessRecord srcApp) {
2278        app.lastActivityTime = now;
2279
2280        if (app.activities.size() > 0) {
2281            // Don't want to touch dependent processes that are hosting activities.
2282            return index;
2283        }
2284
2285        int lrui = mLruProcesses.lastIndexOf(app);
2286        if (lrui < 0) {
2287            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2288                    + what + " " + obj + " from " + srcApp);
2289            return index;
2290        }
2291
2292        if (lrui >= index) {
2293            // Don't want to cause this to move dependent processes *back* in the
2294            // list as if they were less frequently used.
2295            return index;
2296        }
2297
2298        if (lrui >= mLruProcessActivityStart) {
2299            // Don't want to touch dependent processes that are hosting activities.
2300            return index;
2301        }
2302
2303        mLruProcesses.remove(lrui);
2304        if (index > 0) {
2305            index--;
2306        }
2307        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2308                + " in LRU list: " + app);
2309        mLruProcesses.add(index, app);
2310        return index;
2311    }
2312
2313    final void removeLruProcessLocked(ProcessRecord app) {
2314        int lrui = mLruProcesses.lastIndexOf(app);
2315        if (lrui >= 0) {
2316            if (lrui <= mLruProcessActivityStart) {
2317                mLruProcessActivityStart--;
2318            }
2319            if (lrui <= mLruProcessServiceStart) {
2320                mLruProcessServiceStart--;
2321            }
2322            mLruProcesses.remove(lrui);
2323        }
2324    }
2325
2326    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2327            ProcessRecord client) {
2328        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2329        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2330        if (!activityChange && hasActivity) {
2331            // The process has activties, so we are only going to allow activity-based
2332            // adjustments move it.  It should be kept in the front of the list with other
2333            // processes that have activities, and we don't want those to change their
2334            // order except due to activity operations.
2335            return;
2336        }
2337
2338        mLruSeq++;
2339        final long now = SystemClock.uptimeMillis();
2340        app.lastActivityTime = now;
2341
2342        // First a quick reject: if the app is already at the position we will
2343        // put it, then there is nothing to do.
2344        if (hasActivity) {
2345            final int N = mLruProcesses.size();
2346            if (N > 0 && mLruProcesses.get(N-1) == app) {
2347                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2348                return;
2349            }
2350        } else {
2351            if (mLruProcessServiceStart > 0
2352                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2353                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2354                return;
2355            }
2356        }
2357
2358        int lrui = mLruProcesses.lastIndexOf(app);
2359
2360        if (app.persistent && lrui >= 0) {
2361            // We don't care about the position of persistent processes, as long as
2362            // they are in the list.
2363            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2364            return;
2365        }
2366
2367        /* In progress: compute new position first, so we can avoid doing work
2368           if the process is not actually going to move.  Not yet working.
2369        int addIndex;
2370        int nextIndex;
2371        boolean inActivity = false, inService = false;
2372        if (hasActivity) {
2373            // Process has activities, put it at the very tipsy-top.
2374            addIndex = mLruProcesses.size();
2375            nextIndex = mLruProcessServiceStart;
2376            inActivity = true;
2377        } else if (hasService) {
2378            // Process has services, put it at the top of the service list.
2379            addIndex = mLruProcessActivityStart;
2380            nextIndex = mLruProcessServiceStart;
2381            inActivity = true;
2382            inService = true;
2383        } else  {
2384            // Process not otherwise of interest, it goes to the top of the non-service area.
2385            addIndex = mLruProcessServiceStart;
2386            if (client != null) {
2387                int clientIndex = mLruProcesses.lastIndexOf(client);
2388                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2389                        + app);
2390                if (clientIndex >= 0 && addIndex > clientIndex) {
2391                    addIndex = clientIndex;
2392                }
2393            }
2394            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2395        }
2396
2397        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2398                + mLruProcessActivityStart + "): " + app);
2399        */
2400
2401        if (lrui >= 0) {
2402            if (lrui < mLruProcessActivityStart) {
2403                mLruProcessActivityStart--;
2404            }
2405            if (lrui < mLruProcessServiceStart) {
2406                mLruProcessServiceStart--;
2407            }
2408            /*
2409            if (addIndex > lrui) {
2410                addIndex--;
2411            }
2412            if (nextIndex > lrui) {
2413                nextIndex--;
2414            }
2415            */
2416            mLruProcesses.remove(lrui);
2417        }
2418
2419        /*
2420        mLruProcesses.add(addIndex, app);
2421        if (inActivity) {
2422            mLruProcessActivityStart++;
2423        }
2424        if (inService) {
2425            mLruProcessActivityStart++;
2426        }
2427        */
2428
2429        int nextIndex;
2430        if (hasActivity) {
2431            final int N = mLruProcesses.size();
2432            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2433                // Process doesn't have activities, but has clients with
2434                // activities...  move it up, but one below the top (the top
2435                // should always have a real activity).
2436                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2437                mLruProcesses.add(N-1, app);
2438                // To keep it from spamming the LRU list (by making a bunch of clients),
2439                // we will push down any other entries owned by the app.
2440                final int uid = app.info.uid;
2441                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2442                    ProcessRecord subProc = mLruProcesses.get(i);
2443                    if (subProc.info.uid == uid) {
2444                        // We want to push this one down the list.  If the process after
2445                        // it is for the same uid, however, don't do so, because we don't
2446                        // want them internally to be re-ordered.
2447                        if (mLruProcesses.get(i-1).info.uid != uid) {
2448                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2449                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2450                            ProcessRecord tmp = mLruProcesses.get(i);
2451                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2452                            mLruProcesses.set(i-1, tmp);
2453                            i--;
2454                        }
2455                    } else {
2456                        // A gap, we can stop here.
2457                        break;
2458                    }
2459                }
2460            } else {
2461                // Process has activities, put it at the very tipsy-top.
2462                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2463                mLruProcesses.add(app);
2464            }
2465            nextIndex = mLruProcessServiceStart;
2466        } else if (hasService) {
2467            // Process has services, put it at the top of the service list.
2468            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2469            mLruProcesses.add(mLruProcessActivityStart, app);
2470            nextIndex = mLruProcessServiceStart;
2471            mLruProcessActivityStart++;
2472        } else  {
2473            // Process not otherwise of interest, it goes to the top of the non-service area.
2474            int index = mLruProcessServiceStart;
2475            if (client != null) {
2476                // If there is a client, don't allow the process to be moved up higher
2477                // in the list than that client.
2478                int clientIndex = mLruProcesses.lastIndexOf(client);
2479                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2480                        + " when updating " + app);
2481                if (clientIndex <= lrui) {
2482                    // Don't allow the client index restriction to push it down farther in the
2483                    // list than it already is.
2484                    clientIndex = lrui;
2485                }
2486                if (clientIndex >= 0 && index > clientIndex) {
2487                    index = clientIndex;
2488                }
2489            }
2490            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2491            mLruProcesses.add(index, app);
2492            nextIndex = index-1;
2493            mLruProcessActivityStart++;
2494            mLruProcessServiceStart++;
2495        }
2496
2497        // If the app is currently using a content provider or service,
2498        // bump those processes as well.
2499        for (int j=app.connections.size()-1; j>=0; j--) {
2500            ConnectionRecord cr = app.connections.valueAt(j);
2501            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2502                    && cr.binding.service.app != null
2503                    && cr.binding.service.app.lruSeq != mLruSeq
2504                    && !cr.binding.service.app.persistent) {
2505                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2506                        "service connection", cr, app);
2507            }
2508        }
2509        for (int j=app.conProviders.size()-1; j>=0; j--) {
2510            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2511            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2512                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2513                        "provider reference", cpr, app);
2514            }
2515        }
2516    }
2517
2518    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2519        if (uid == Process.SYSTEM_UID) {
2520            // The system gets to run in any process.  If there are multiple
2521            // processes with the same uid, just pick the first (this
2522            // should never happen).
2523            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2524            if (procs == null) return null;
2525            final int N = procs.size();
2526            for (int i = 0; i < N; i++) {
2527                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2528            }
2529        }
2530        ProcessRecord proc = mProcessNames.get(processName, uid);
2531        if (false && proc != null && !keepIfLarge
2532                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2533                && proc.lastCachedPss >= 4000) {
2534            // Turn this condition on to cause killing to happen regularly, for testing.
2535            if (proc.baseProcessTracker != null) {
2536                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2537            }
2538            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2539                    + "k from cached");
2540        } else if (proc != null && !keepIfLarge
2541                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2542                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2543            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2544            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2545                if (proc.baseProcessTracker != null) {
2546                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2547                }
2548                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2549                        + "k from cached");
2550            }
2551        }
2552        return proc;
2553    }
2554
2555    void ensurePackageDexOpt(String packageName) {
2556        IPackageManager pm = AppGlobals.getPackageManager();
2557        try {
2558            if (pm.performDexOpt(packageName)) {
2559                mDidDexOpt = true;
2560            }
2561        } catch (RemoteException e) {
2562        }
2563    }
2564
2565    boolean isNextTransitionForward() {
2566        int transit = mWindowManager.getPendingAppTransition();
2567        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2568                || transit == AppTransition.TRANSIT_TASK_OPEN
2569                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2570    }
2571
2572    final ProcessRecord startProcessLocked(String processName,
2573            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2574            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2575            boolean isolated, boolean keepIfLarge) {
2576        ProcessRecord app;
2577        if (!isolated) {
2578            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2579        } else {
2580            // If this is an isolated process, it can't re-use an existing process.
2581            app = null;
2582        }
2583        // We don't have to do anything more if:
2584        // (1) There is an existing application record; and
2585        // (2) The caller doesn't think it is dead, OR there is no thread
2586        //     object attached to it so we know it couldn't have crashed; and
2587        // (3) There is a pid assigned to it, so it is either starting or
2588        //     already running.
2589        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2590                + " app=" + app + " knownToBeDead=" + knownToBeDead
2591                + " thread=" + (app != null ? app.thread : null)
2592                + " pid=" + (app != null ? app.pid : -1));
2593        if (app != null && app.pid > 0) {
2594            if (!knownToBeDead || app.thread == null) {
2595                // We already have the app running, or are waiting for it to
2596                // come up (we have a pid but not yet its thread), so keep it.
2597                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2598                // If this is a new package in the process, add the package to the list
2599                app.addPackage(info.packageName, mProcessStats);
2600                return app;
2601            }
2602
2603            // An application record is attached to a previous process,
2604            // clean it up now.
2605            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2606            handleAppDiedLocked(app, true, true);
2607        }
2608
2609        String hostingNameStr = hostingName != null
2610                ? hostingName.flattenToShortString() : null;
2611
2612        if (!isolated) {
2613            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2614                // If we are in the background, then check to see if this process
2615                // is bad.  If so, we will just silently fail.
2616                if (mBadProcesses.get(info.processName, info.uid) != null) {
2617                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2618                            + "/" + info.processName);
2619                    return null;
2620                }
2621            } else {
2622                // When the user is explicitly starting a process, then clear its
2623                // crash count so that we won't make it bad until they see at
2624                // least one crash dialog again, and make the process good again
2625                // if it had been bad.
2626                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2627                        + "/" + info.processName);
2628                mProcessCrashTimes.remove(info.processName, info.uid);
2629                if (mBadProcesses.get(info.processName, info.uid) != null) {
2630                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2631                            UserHandle.getUserId(info.uid), info.uid,
2632                            info.processName);
2633                    mBadProcesses.remove(info.processName, info.uid);
2634                    if (app != null) {
2635                        app.bad = false;
2636                    }
2637                }
2638            }
2639        }
2640
2641        if (app == null) {
2642            app = newProcessRecordLocked(info, processName, isolated);
2643            if (app == null) {
2644                Slog.w(TAG, "Failed making new process record for "
2645                        + processName + "/" + info.uid + " isolated=" + isolated);
2646                return null;
2647            }
2648            mProcessNames.put(processName, app.uid, app);
2649            if (isolated) {
2650                mIsolatedProcesses.put(app.uid, app);
2651            }
2652        } else {
2653            // If this is a new package in the process, add the package to the list
2654            app.addPackage(info.packageName, mProcessStats);
2655        }
2656
2657        // If the system is not ready yet, then hold off on starting this
2658        // process until it is.
2659        if (!mProcessesReady
2660                && !isAllowedWhileBooting(info)
2661                && !allowWhileBooting) {
2662            if (!mProcessesOnHold.contains(app)) {
2663                mProcessesOnHold.add(app);
2664            }
2665            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2666            return app;
2667        }
2668
2669        startProcessLocked(app, hostingType, hostingNameStr);
2670        return (app.pid != 0) ? app : null;
2671    }
2672
2673    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2674        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2675    }
2676
2677    private final void startProcessLocked(ProcessRecord app,
2678            String hostingType, String hostingNameStr) {
2679        if (app.pid > 0 && app.pid != MY_PID) {
2680            synchronized (mPidsSelfLocked) {
2681                mPidsSelfLocked.remove(app.pid);
2682                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2683            }
2684            app.setPid(0);
2685        }
2686
2687        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2688                "startProcessLocked removing on hold: " + app);
2689        mProcessesOnHold.remove(app);
2690
2691        updateCpuStats();
2692
2693        try {
2694            int uid = app.uid;
2695
2696            int[] gids = null;
2697            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2698            if (!app.isolated) {
2699                int[] permGids = null;
2700                try {
2701                    final PackageManager pm = mContext.getPackageManager();
2702                    permGids = pm.getPackageGids(app.info.packageName);
2703
2704                    if (Environment.isExternalStorageEmulated()) {
2705                        if (pm.checkPermission(
2706                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2707                                app.info.packageName) == PERMISSION_GRANTED) {
2708                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2709                        } else {
2710                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2711                        }
2712                    }
2713                } catch (PackageManager.NameNotFoundException e) {
2714                    Slog.w(TAG, "Unable to retrieve gids", e);
2715                }
2716
2717                /*
2718                 * Add shared application GID so applications can share some
2719                 * resources like shared libraries
2720                 */
2721                if (permGids == null) {
2722                    gids = new int[1];
2723                } else {
2724                    gids = new int[permGids.length + 1];
2725                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2726                }
2727                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2728            }
2729            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2730                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2731                        && mTopComponent != null
2732                        && app.processName.equals(mTopComponent.getPackageName())) {
2733                    uid = 0;
2734                }
2735                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2736                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2737                    uid = 0;
2738                }
2739            }
2740            int debugFlags = 0;
2741            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2742                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2743                // Also turn on CheckJNI for debuggable apps. It's quite
2744                // awkward to turn on otherwise.
2745                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2746            }
2747            // Run the app in safe mode if its manifest requests so or the
2748            // system is booted in safe mode.
2749            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2750                Zygote.systemInSafeMode == true) {
2751                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2752            }
2753            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2754                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2755            }
2756            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2757                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2758            }
2759            if ("1".equals(SystemProperties.get("debug.assert"))) {
2760                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2761            }
2762
2763            // Start the process.  It will either succeed and return a result containing
2764            // the PID of the new process, or else throw a RuntimeException.
2765            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2766                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2767                    app.info.targetSdkVersion, app.info.seinfo, null);
2768
2769            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2770            synchronized (bs) {
2771                if (bs.isOnBattery()) {
2772                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2773                }
2774            }
2775
2776            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2777                    UserHandle.getUserId(uid), startResult.pid, uid,
2778                    app.processName, hostingType,
2779                    hostingNameStr != null ? hostingNameStr : "");
2780
2781            if (app.persistent) {
2782                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2783            }
2784
2785            StringBuilder buf = mStringBuilder;
2786            buf.setLength(0);
2787            buf.append("Start proc ");
2788            buf.append(app.processName);
2789            buf.append(" for ");
2790            buf.append(hostingType);
2791            if (hostingNameStr != null) {
2792                buf.append(" ");
2793                buf.append(hostingNameStr);
2794            }
2795            buf.append(": pid=");
2796            buf.append(startResult.pid);
2797            buf.append(" uid=");
2798            buf.append(uid);
2799            buf.append(" gids={");
2800            if (gids != null) {
2801                for (int gi=0; gi<gids.length; gi++) {
2802                    if (gi != 0) buf.append(", ");
2803                    buf.append(gids[gi]);
2804
2805                }
2806            }
2807            buf.append("}");
2808            Slog.i(TAG, buf.toString());
2809            app.setPid(startResult.pid);
2810            app.usingWrapper = startResult.usingWrapper;
2811            app.removed = false;
2812            synchronized (mPidsSelfLocked) {
2813                this.mPidsSelfLocked.put(startResult.pid, app);
2814                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2815                msg.obj = app;
2816                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2817                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2818            }
2819        } catch (RuntimeException e) {
2820            // XXX do better error recovery.
2821            app.setPid(0);
2822            Slog.e(TAG, "Failure starting process " + app.processName, e);
2823        }
2824    }
2825
2826    void updateUsageStats(ActivityRecord component, boolean resumed) {
2827        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2828        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2829        if (resumed) {
2830            mUsageStatsService.noteResumeComponent(component.realActivity);
2831            synchronized (stats) {
2832                stats.noteActivityResumedLocked(component.app.uid);
2833            }
2834        } else {
2835            mUsageStatsService.notePauseComponent(component.realActivity);
2836            synchronized (stats) {
2837                stats.noteActivityPausedLocked(component.app.uid);
2838            }
2839        }
2840    }
2841
2842    Intent getHomeIntent() {
2843        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2844        intent.setComponent(mTopComponent);
2845        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2846            intent.addCategory(Intent.CATEGORY_HOME);
2847        }
2848        return intent;
2849    }
2850
2851    boolean startHomeActivityLocked(int userId) {
2852        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2853                && mTopAction == null) {
2854            // We are running in factory test mode, but unable to find
2855            // the factory test app, so just sit around displaying the
2856            // error message and don't try to start anything.
2857            return false;
2858        }
2859        Intent intent = getHomeIntent();
2860        ActivityInfo aInfo =
2861            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2862        if (aInfo != null) {
2863            intent.setComponent(new ComponentName(
2864                    aInfo.applicationInfo.packageName, aInfo.name));
2865            // Don't do this if the home app is currently being
2866            // instrumented.
2867            aInfo = new ActivityInfo(aInfo);
2868            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2869            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2870                    aInfo.applicationInfo.uid, true);
2871            if (app == null || app.instrumentationClass == null) {
2872                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2873                mStackSupervisor.startHomeActivity(intent, aInfo);
2874            }
2875        }
2876
2877        return true;
2878    }
2879
2880    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2881        ActivityInfo ai = null;
2882        ComponentName comp = intent.getComponent();
2883        try {
2884            if (comp != null) {
2885                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2886            } else {
2887                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2888                        intent,
2889                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2890                            flags, userId);
2891
2892                if (info != null) {
2893                    ai = info.activityInfo;
2894                }
2895            }
2896        } catch (RemoteException e) {
2897            // ignore
2898        }
2899
2900        return ai;
2901    }
2902
2903    /**
2904     * Starts the "new version setup screen" if appropriate.
2905     */
2906    void startSetupActivityLocked() {
2907        // Only do this once per boot.
2908        if (mCheckedForSetup) {
2909            return;
2910        }
2911
2912        // We will show this screen if the current one is a different
2913        // version than the last one shown, and we are not running in
2914        // low-level factory test mode.
2915        final ContentResolver resolver = mContext.getContentResolver();
2916        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2917                Settings.Global.getInt(resolver,
2918                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2919            mCheckedForSetup = true;
2920
2921            // See if we should be showing the platform update setup UI.
2922            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2923            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2924                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2925
2926            // We don't allow third party apps to replace this.
2927            ResolveInfo ri = null;
2928            for (int i=0; ris != null && i<ris.size(); i++) {
2929                if ((ris.get(i).activityInfo.applicationInfo.flags
2930                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2931                    ri = ris.get(i);
2932                    break;
2933                }
2934            }
2935
2936            if (ri != null) {
2937                String vers = ri.activityInfo.metaData != null
2938                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2939                        : null;
2940                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2941                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2942                            Intent.METADATA_SETUP_VERSION);
2943                }
2944                String lastVers = Settings.Secure.getString(
2945                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2946                if (vers != null && !vers.equals(lastVers)) {
2947                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2948                    intent.setComponent(new ComponentName(
2949                            ri.activityInfo.packageName, ri.activityInfo.name));
2950                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2951                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2952                }
2953            }
2954        }
2955    }
2956
2957    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2958        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2959    }
2960
2961    void enforceNotIsolatedCaller(String caller) {
2962        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2963            throw new SecurityException("Isolated process not allowed to call " + caller);
2964        }
2965    }
2966
2967    @Override
2968    public int getFrontActivityScreenCompatMode() {
2969        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2970        synchronized (this) {
2971            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2972        }
2973    }
2974
2975    @Override
2976    public void setFrontActivityScreenCompatMode(int mode) {
2977        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2978                "setFrontActivityScreenCompatMode");
2979        synchronized (this) {
2980            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2981        }
2982    }
2983
2984    @Override
2985    public int getPackageScreenCompatMode(String packageName) {
2986        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2987        synchronized (this) {
2988            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2989        }
2990    }
2991
2992    @Override
2993    public void setPackageScreenCompatMode(String packageName, int mode) {
2994        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2995                "setPackageScreenCompatMode");
2996        synchronized (this) {
2997            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2998        }
2999    }
3000
3001    @Override
3002    public boolean getPackageAskScreenCompat(String packageName) {
3003        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3004        synchronized (this) {
3005            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3006        }
3007    }
3008
3009    @Override
3010    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3011        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3012                "setPackageAskScreenCompat");
3013        synchronized (this) {
3014            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3015        }
3016    }
3017
3018    private void dispatchProcessesChanged() {
3019        int N;
3020        synchronized (this) {
3021            N = mPendingProcessChanges.size();
3022            if (mActiveProcessChanges.length < N) {
3023                mActiveProcessChanges = new ProcessChangeItem[N];
3024            }
3025            mPendingProcessChanges.toArray(mActiveProcessChanges);
3026            mAvailProcessChanges.addAll(mPendingProcessChanges);
3027            mPendingProcessChanges.clear();
3028            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3029        }
3030
3031        int i = mProcessObservers.beginBroadcast();
3032        while (i > 0) {
3033            i--;
3034            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3035            if (observer != null) {
3036                try {
3037                    for (int j=0; j<N; j++) {
3038                        ProcessChangeItem item = mActiveProcessChanges[j];
3039                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3040                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3041                                    + item.pid + " uid=" + item.uid + ": "
3042                                    + item.foregroundActivities);
3043                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3044                                    item.foregroundActivities);
3045                        }
3046                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3047                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3048                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3049                            observer.onImportanceChanged(item.pid, item.uid,
3050                                    item.importance);
3051                        }
3052                    }
3053                } catch (RemoteException e) {
3054                }
3055            }
3056        }
3057        mProcessObservers.finishBroadcast();
3058    }
3059
3060    private void dispatchProcessDied(int pid, int uid) {
3061        int i = mProcessObservers.beginBroadcast();
3062        while (i > 0) {
3063            i--;
3064            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3065            if (observer != null) {
3066                try {
3067                    observer.onProcessDied(pid, uid);
3068                } catch (RemoteException e) {
3069                }
3070            }
3071        }
3072        mProcessObservers.finishBroadcast();
3073    }
3074
3075    final void doPendingActivityLaunchesLocked(boolean doResume) {
3076        final int N = mPendingActivityLaunches.size();
3077        if (N <= 0) {
3078            return;
3079        }
3080        for (int i=0; i<N; i++) {
3081            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3082            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3083                    doResume && i == (N-1), null);
3084        }
3085        mPendingActivityLaunches.clear();
3086    }
3087
3088    @Override
3089    public final int startActivity(IApplicationThread caller, String callingPackage,
3090            Intent intent, String resolvedType, IBinder resultTo,
3091            String resultWho, int requestCode, int startFlags,
3092            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3093        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3094                resultWho, requestCode,
3095                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3096    }
3097
3098    @Override
3099    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3100            Intent intent, String resolvedType, IBinder resultTo,
3101            String resultWho, int requestCode, int startFlags,
3102            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3103        enforceNotIsolatedCaller("startActivity");
3104        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3105                false, true, "startActivity", null);
3106        // TODO: Switch to user app stacks here.
3107        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3108                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3109                null, null, options, userId, null);
3110    }
3111
3112    @Override
3113    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3114            Intent intent, String resolvedType, IBinder resultTo,
3115            String resultWho, int requestCode, int startFlags, String profileFile,
3116            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3117        enforceNotIsolatedCaller("startActivityAndWait");
3118        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3119                false, true, "startActivityAndWait", null);
3120        WaitResult res = new WaitResult();
3121        // TODO: Switch to user app stacks here.
3122        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3123                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3124                res, null, options, UserHandle.getCallingUserId(), null);
3125        return res;
3126    }
3127
3128    @Override
3129    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3130            Intent intent, String resolvedType, IBinder resultTo,
3131            String resultWho, int requestCode, int startFlags, Configuration config,
3132            Bundle options, int userId) {
3133        enforceNotIsolatedCaller("startActivityWithConfig");
3134        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3135                false, true, "startActivityWithConfig", null);
3136        // TODO: Switch to user app stacks here.
3137        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3138                resolvedType, resultTo, resultWho, requestCode, startFlags,
3139                null, null, null, config, options, userId, null);
3140        return ret;
3141    }
3142
3143    @Override
3144    public int startActivityIntentSender(IApplicationThread caller,
3145            IntentSender intent, Intent fillInIntent, String resolvedType,
3146            IBinder resultTo, String resultWho, int requestCode,
3147            int flagsMask, int flagsValues, Bundle options) {
3148        enforceNotIsolatedCaller("startActivityIntentSender");
3149        // Refuse possible leaked file descriptors
3150        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3151            throw new IllegalArgumentException("File descriptors passed in Intent");
3152        }
3153
3154        IIntentSender sender = intent.getTarget();
3155        if (!(sender instanceof PendingIntentRecord)) {
3156            throw new IllegalArgumentException("Bad PendingIntent object");
3157        }
3158
3159        PendingIntentRecord pir = (PendingIntentRecord)sender;
3160
3161        synchronized (this) {
3162            // If this is coming from the currently resumed activity, it is
3163            // effectively saying that app switches are allowed at this point.
3164            final ActivityStack stack = getFocusedStack();
3165            if (stack.mResumedActivity != null &&
3166                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3167                mAppSwitchesAllowedTime = 0;
3168            }
3169        }
3170        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3171                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
3172        return ret;
3173    }
3174
3175    @Override
3176    public boolean startNextMatchingActivity(IBinder callingActivity,
3177            Intent intent, Bundle options) {
3178        // Refuse possible leaked file descriptors
3179        if (intent != null && intent.hasFileDescriptors() == true) {
3180            throw new IllegalArgumentException("File descriptors passed in Intent");
3181        }
3182
3183        synchronized (this) {
3184            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3185            if (r == null) {
3186                ActivityOptions.abort(options);
3187                return false;
3188            }
3189            if (r.app == null || r.app.thread == null) {
3190                // The caller is not running...  d'oh!
3191                ActivityOptions.abort(options);
3192                return false;
3193            }
3194            intent = new Intent(intent);
3195            // The caller is not allowed to change the data.
3196            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3197            // And we are resetting to find the next component...
3198            intent.setComponent(null);
3199
3200            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3201
3202            ActivityInfo aInfo = null;
3203            try {
3204                List<ResolveInfo> resolves =
3205                    AppGlobals.getPackageManager().queryIntentActivities(
3206                            intent, r.resolvedType,
3207                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3208                            UserHandle.getCallingUserId());
3209
3210                // Look for the original activity in the list...
3211                final int N = resolves != null ? resolves.size() : 0;
3212                for (int i=0; i<N; i++) {
3213                    ResolveInfo rInfo = resolves.get(i);
3214                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3215                            && rInfo.activityInfo.name.equals(r.info.name)) {
3216                        // We found the current one...  the next matching is
3217                        // after it.
3218                        i++;
3219                        if (i<N) {
3220                            aInfo = resolves.get(i).activityInfo;
3221                        }
3222                        if (debug) {
3223                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3224                                    + "/" + r.info.name);
3225                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3226                                    + "/" + aInfo.name);
3227                        }
3228                        break;
3229                    }
3230                }
3231            } catch (RemoteException e) {
3232            }
3233
3234            if (aInfo == null) {
3235                // Nobody who is next!
3236                ActivityOptions.abort(options);
3237                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3238                return false;
3239            }
3240
3241            intent.setComponent(new ComponentName(
3242                    aInfo.applicationInfo.packageName, aInfo.name));
3243            intent.setFlags(intent.getFlags()&~(
3244                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3245                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3246                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3247                    Intent.FLAG_ACTIVITY_NEW_TASK));
3248
3249            // Okay now we need to start the new activity, replacing the
3250            // currently running activity.  This is a little tricky because
3251            // we want to start the new one as if the current one is finished,
3252            // but not finish the current one first so that there is no flicker.
3253            // And thus...
3254            final boolean wasFinishing = r.finishing;
3255            r.finishing = true;
3256
3257            // Propagate reply information over to the new activity.
3258            final ActivityRecord resultTo = r.resultTo;
3259            final String resultWho = r.resultWho;
3260            final int requestCode = r.requestCode;
3261            r.resultTo = null;
3262            if (resultTo != null) {
3263                resultTo.removeResultsLocked(r, resultWho, requestCode);
3264            }
3265
3266            final long origId = Binder.clearCallingIdentity();
3267            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3268                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3269                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3270                    options, false, null, null);
3271            Binder.restoreCallingIdentity(origId);
3272
3273            r.finishing = wasFinishing;
3274            if (res != ActivityManager.START_SUCCESS) {
3275                return false;
3276            }
3277            return true;
3278        }
3279    }
3280
3281    final int startActivityInPackage(int uid, String callingPackage,
3282            Intent intent, String resolvedType, IBinder resultTo,
3283            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
3284
3285        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3286                false, true, "startActivityInPackage", null);
3287
3288        // TODO: Switch to user app stacks here.
3289        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3290                resultTo, resultWho, requestCode, startFlags,
3291                null, null, null, null, options, userId, null);
3292        return ret;
3293    }
3294
3295    @Override
3296    public final int startActivities(IApplicationThread caller, String callingPackage,
3297            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3298            int userId) {
3299        enforceNotIsolatedCaller("startActivities");
3300        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3301                false, true, "startActivity", null);
3302        // TODO: Switch to user app stacks here.
3303        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3304                resolvedTypes, resultTo, options, userId);
3305        return ret;
3306    }
3307
3308    final int startActivitiesInPackage(int uid, String callingPackage,
3309            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3310            Bundle options, int userId) {
3311
3312        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3313                false, true, "startActivityInPackage", null);
3314        // TODO: Switch to user app stacks here.
3315        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3316                resultTo, options, userId);
3317        return ret;
3318    }
3319
3320    final void addRecentTaskLocked(TaskRecord task) {
3321        int N = mRecentTasks.size();
3322        // Quick case: check if the top-most recent task is the same.
3323        if (N > 0 && mRecentTasks.get(0) == task) {
3324            return;
3325        }
3326        // Remove any existing entries that are the same kind of task.
3327        for (int i=0; i<N; i++) {
3328            TaskRecord tr = mRecentTasks.get(i);
3329            if (task.userId == tr.userId
3330                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3331                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3332                tr.disposeThumbnail();
3333                mRecentTasks.remove(i);
3334                i--;
3335                N--;
3336                if (task.intent == null) {
3337                    // If the new recent task we are adding is not fully
3338                    // specified, then replace it with the existing recent task.
3339                    task = tr;
3340                }
3341            }
3342        }
3343        if (N >= MAX_RECENT_TASKS) {
3344            mRecentTasks.remove(N-1).disposeThumbnail();
3345        }
3346        mRecentTasks.add(0, task);
3347    }
3348
3349    @Override
3350    public void reportActivityFullyDrawn(IBinder token) {
3351        synchronized (this) {
3352            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3353            if (r == null) {
3354                return;
3355            }
3356            r.reportFullyDrawnLocked();
3357        }
3358    }
3359
3360    @Override
3361    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3362        synchronized (this) {
3363            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3364            if (r == null) {
3365                return;
3366            }
3367            final long origId = Binder.clearCallingIdentity();
3368            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3369            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3370                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3371            if (config != null) {
3372                r.frozenBeforeDestroy = true;
3373                if (!updateConfigurationLocked(config, r, false, false)) {
3374                    mStackSupervisor.resumeTopActivitiesLocked();
3375                }
3376            }
3377            Binder.restoreCallingIdentity(origId);
3378        }
3379    }
3380
3381    @Override
3382    public int getRequestedOrientation(IBinder token) {
3383        synchronized (this) {
3384            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3385            if (r == null) {
3386                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3387            }
3388            return mWindowManager.getAppOrientation(r.appToken);
3389        }
3390    }
3391
3392    /**
3393     * This is the internal entry point for handling Activity.finish().
3394     *
3395     * @param token The Binder token referencing the Activity we want to finish.
3396     * @param resultCode Result code, if any, from this Activity.
3397     * @param resultData Result data (Intent), if any, from this Activity.
3398     *
3399     * @return Returns true if the activity successfully finished, or false if it is still running.
3400     */
3401    @Override
3402    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3403        // Refuse possible leaked file descriptors
3404        if (resultData != null && resultData.hasFileDescriptors() == true) {
3405            throw new IllegalArgumentException("File descriptors passed in Intent");
3406        }
3407
3408        synchronized(this) {
3409            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3410            if (r == null) {
3411                return true;
3412            }
3413            if (mController != null) {
3414                // Find the first activity that is not finishing.
3415                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3416                if (next != null) {
3417                    // ask watcher if this is allowed
3418                    boolean resumeOK = true;
3419                    try {
3420                        resumeOK = mController.activityResuming(next.packageName);
3421                    } catch (RemoteException e) {
3422                        mController = null;
3423                        Watchdog.getInstance().setActivityController(null);
3424                    }
3425
3426                    if (!resumeOK) {
3427                        return false;
3428                    }
3429                }
3430            }
3431            final long origId = Binder.clearCallingIdentity();
3432            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3433                    resultData, "app-request", true);
3434            Binder.restoreCallingIdentity(origId);
3435            return res;
3436        }
3437    }
3438
3439    @Override
3440    public final void finishHeavyWeightApp() {
3441        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3442                != PackageManager.PERMISSION_GRANTED) {
3443            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3444                    + Binder.getCallingPid()
3445                    + ", uid=" + Binder.getCallingUid()
3446                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3447            Slog.w(TAG, msg);
3448            throw new SecurityException(msg);
3449        }
3450
3451        synchronized(this) {
3452            if (mHeavyWeightProcess == null) {
3453                return;
3454            }
3455
3456            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3457                    mHeavyWeightProcess.activities);
3458            for (int i=0; i<activities.size(); i++) {
3459                ActivityRecord r = activities.get(i);
3460                if (!r.finishing) {
3461                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3462                            null, "finish-heavy", true);
3463                }
3464            }
3465
3466            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3467                    mHeavyWeightProcess.userId, 0));
3468            mHeavyWeightProcess = null;
3469        }
3470    }
3471
3472    @Override
3473    public void crashApplication(int uid, int initialPid, String packageName,
3474            String message) {
3475        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3476                != PackageManager.PERMISSION_GRANTED) {
3477            String msg = "Permission Denial: crashApplication() from pid="
3478                    + Binder.getCallingPid()
3479                    + ", uid=" + Binder.getCallingUid()
3480                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3481            Slog.w(TAG, msg);
3482            throw new SecurityException(msg);
3483        }
3484
3485        synchronized(this) {
3486            ProcessRecord proc = null;
3487
3488            // Figure out which process to kill.  We don't trust that initialPid
3489            // still has any relation to current pids, so must scan through the
3490            // list.
3491            synchronized (mPidsSelfLocked) {
3492                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3493                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3494                    if (p.uid != uid) {
3495                        continue;
3496                    }
3497                    if (p.pid == initialPid) {
3498                        proc = p;
3499                        break;
3500                    }
3501                    if (p.pkgList.containsKey(packageName)) {
3502                        proc = p;
3503                    }
3504                }
3505            }
3506
3507            if (proc == null) {
3508                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3509                        + " initialPid=" + initialPid
3510                        + " packageName=" + packageName);
3511                return;
3512            }
3513
3514            if (proc.thread != null) {
3515                if (proc.pid == Process.myPid()) {
3516                    Log.w(TAG, "crashApplication: trying to crash self!");
3517                    return;
3518                }
3519                long ident = Binder.clearCallingIdentity();
3520                try {
3521                    proc.thread.scheduleCrash(message);
3522                } catch (RemoteException e) {
3523                }
3524                Binder.restoreCallingIdentity(ident);
3525            }
3526        }
3527    }
3528
3529    @Override
3530    public final void finishSubActivity(IBinder token, String resultWho,
3531            int requestCode) {
3532        synchronized(this) {
3533            final long origId = Binder.clearCallingIdentity();
3534            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3535            if (r != null) {
3536                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3537            }
3538            Binder.restoreCallingIdentity(origId);
3539        }
3540    }
3541
3542    @Override
3543    public boolean finishActivityAffinity(IBinder token) {
3544        synchronized(this) {
3545            final long origId = Binder.clearCallingIdentity();
3546            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3547            boolean res = false;
3548            if (r != null) {
3549                res = r.task.stack.finishActivityAffinityLocked(r);
3550            }
3551            Binder.restoreCallingIdentity(origId);
3552            return res;
3553        }
3554    }
3555
3556    @Override
3557    public boolean willActivityBeVisible(IBinder token) {
3558        synchronized(this) {
3559            ActivityStack stack = ActivityRecord.getStackLocked(token);
3560            if (stack != null) {
3561                return stack.willActivityBeVisibleLocked(token);
3562            }
3563            return false;
3564        }
3565    }
3566
3567    @Override
3568    public void overridePendingTransition(IBinder token, String packageName,
3569            int enterAnim, int exitAnim) {
3570        synchronized(this) {
3571            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3572            if (self == null) {
3573                return;
3574            }
3575
3576            final long origId = Binder.clearCallingIdentity();
3577
3578            if (self.state == ActivityState.RESUMED
3579                    || self.state == ActivityState.PAUSING) {
3580                mWindowManager.overridePendingAppTransition(packageName,
3581                        enterAnim, exitAnim, null);
3582            }
3583
3584            Binder.restoreCallingIdentity(origId);
3585        }
3586    }
3587
3588    /**
3589     * Main function for removing an existing process from the activity manager
3590     * as a result of that process going away.  Clears out all connections
3591     * to the process.
3592     */
3593    private final void handleAppDiedLocked(ProcessRecord app,
3594            boolean restarting, boolean allowRestart) {
3595        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3596        if (!restarting) {
3597            removeLruProcessLocked(app);
3598        }
3599
3600        if (mProfileProc == app) {
3601            clearProfilerLocked();
3602        }
3603
3604        // Remove this application's activities from active lists.
3605        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3606
3607        app.activities.clear();
3608
3609        if (app.instrumentationClass != null) {
3610            Slog.w(TAG, "Crash of app " + app.processName
3611                  + " running instrumentation " + app.instrumentationClass);
3612            Bundle info = new Bundle();
3613            info.putString("shortMsg", "Process crashed.");
3614            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3615        }
3616
3617        if (!restarting) {
3618            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3619                // If there was nothing to resume, and we are not already
3620                // restarting this process, but there is a visible activity that
3621                // is hosted by the process...  then make sure all visible
3622                // activities are running, taking care of restarting this
3623                // process.
3624                if (hasVisibleActivities) {
3625                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3626                }
3627            }
3628        }
3629    }
3630
3631    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3632        IBinder threadBinder = thread.asBinder();
3633        // Find the application record.
3634        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3635            ProcessRecord rec = mLruProcesses.get(i);
3636            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3637                return i;
3638            }
3639        }
3640        return -1;
3641    }
3642
3643    final ProcessRecord getRecordForAppLocked(
3644            IApplicationThread thread) {
3645        if (thread == null) {
3646            return null;
3647        }
3648
3649        int appIndex = getLRURecordIndexForAppLocked(thread);
3650        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3651    }
3652
3653    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3654        // If there are no longer any background processes running,
3655        // and the app that died was not running instrumentation,
3656        // then tell everyone we are now low on memory.
3657        boolean haveBg = false;
3658        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3659            ProcessRecord rec = mLruProcesses.get(i);
3660            if (rec.thread != null
3661                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3662                haveBg = true;
3663                break;
3664            }
3665        }
3666
3667        if (!haveBg) {
3668            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3669            if (doReport) {
3670                long now = SystemClock.uptimeMillis();
3671                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3672                    doReport = false;
3673                } else {
3674                    mLastMemUsageReportTime = now;
3675                }
3676            }
3677            final ArrayList<ProcessMemInfo> memInfos
3678                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3679            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3680            long now = SystemClock.uptimeMillis();
3681            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3682                ProcessRecord rec = mLruProcesses.get(i);
3683                if (rec == dyingProc || rec.thread == null) {
3684                    continue;
3685                }
3686                if (doReport) {
3687                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3688                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3689                }
3690                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3691                    // The low memory report is overriding any current
3692                    // state for a GC request.  Make sure to do
3693                    // heavy/important/visible/foreground processes first.
3694                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3695                        rec.lastRequestedGc = 0;
3696                    } else {
3697                        rec.lastRequestedGc = rec.lastLowMemory;
3698                    }
3699                    rec.reportLowMemory = true;
3700                    rec.lastLowMemory = now;
3701                    mProcessesToGc.remove(rec);
3702                    addProcessToGcListLocked(rec);
3703                }
3704            }
3705            if (doReport) {
3706                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3707                mHandler.sendMessage(msg);
3708            }
3709            scheduleAppGcsLocked();
3710        }
3711    }
3712
3713    final void appDiedLocked(ProcessRecord app, int pid,
3714            IApplicationThread thread) {
3715
3716        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3717        synchronized (stats) {
3718            stats.noteProcessDiedLocked(app.info.uid, pid);
3719        }
3720
3721        // Clean up already done if the process has been re-started.
3722        if (app.pid == pid && app.thread != null &&
3723                app.thread.asBinder() == thread.asBinder()) {
3724            boolean doLowMem = app.instrumentationClass == null;
3725            boolean doOomAdj = doLowMem;
3726            if (!app.killedByAm) {
3727                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3728                        + ") has died.");
3729                mAllowLowerMemLevel = true;
3730            } else {
3731                // Note that we always want to do oom adj to update our state with the
3732                // new number of procs.
3733                mAllowLowerMemLevel = false;
3734                doLowMem = false;
3735            }
3736            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3737            if (DEBUG_CLEANUP) Slog.v(
3738                TAG, "Dying app: " + app + ", pid: " + pid
3739                + ", thread: " + thread.asBinder());
3740            handleAppDiedLocked(app, false, true);
3741
3742            if (doOomAdj) {
3743                updateOomAdjLocked();
3744            }
3745            if (doLowMem) {
3746                doLowMemReportIfNeededLocked(app);
3747            }
3748        } else if (app.pid != pid) {
3749            // A new process has already been started.
3750            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3751                    + ") has died and restarted (pid " + app.pid + ").");
3752            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3753        } else if (DEBUG_PROCESSES) {
3754            Slog.d(TAG, "Received spurious death notification for thread "
3755                    + thread.asBinder());
3756        }
3757    }
3758
3759    /**
3760     * If a stack trace dump file is configured, dump process stack traces.
3761     * @param clearTraces causes the dump file to be erased prior to the new
3762     *    traces being written, if true; when false, the new traces will be
3763     *    appended to any existing file content.
3764     * @param firstPids of dalvik VM processes to dump stack traces for first
3765     * @param lastPids of dalvik VM processes to dump stack traces for last
3766     * @param nativeProcs optional list of native process names to dump stack crawls
3767     * @return file containing stack traces, or null if no dump file is configured
3768     */
3769    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3770            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3771        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3772        if (tracesPath == null || tracesPath.length() == 0) {
3773            return null;
3774        }
3775
3776        File tracesFile = new File(tracesPath);
3777        try {
3778            File tracesDir = tracesFile.getParentFile();
3779            if (!tracesDir.exists()) {
3780                tracesFile.mkdirs();
3781                if (!SELinux.restorecon(tracesDir)) {
3782                    return null;
3783                }
3784            }
3785            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3786
3787            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3788            tracesFile.createNewFile();
3789            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3790        } catch (IOException e) {
3791            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3792            return null;
3793        }
3794
3795        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3796        return tracesFile;
3797    }
3798
3799    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3800            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3801        // Use a FileObserver to detect when traces finish writing.
3802        // The order of traces is considered important to maintain for legibility.
3803        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3804            @Override
3805            public synchronized void onEvent(int event, String path) { notify(); }
3806        };
3807
3808        try {
3809            observer.startWatching();
3810
3811            // First collect all of the stacks of the most important pids.
3812            if (firstPids != null) {
3813                try {
3814                    int num = firstPids.size();
3815                    for (int i = 0; i < num; i++) {
3816                        synchronized (observer) {
3817                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3818                            observer.wait(200);  // Wait for write-close, give up after 200msec
3819                        }
3820                    }
3821                } catch (InterruptedException e) {
3822                    Log.wtf(TAG, e);
3823                }
3824            }
3825
3826            // Next collect the stacks of the native pids
3827            if (nativeProcs != null) {
3828                int[] pids = Process.getPidsForCommands(nativeProcs);
3829                if (pids != null) {
3830                    for (int pid : pids) {
3831                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3832                    }
3833                }
3834            }
3835
3836            // Lastly, measure CPU usage.
3837            if (processCpuTracker != null) {
3838                processCpuTracker.init();
3839                System.gc();
3840                processCpuTracker.update();
3841                try {
3842                    synchronized (processCpuTracker) {
3843                        processCpuTracker.wait(500); // measure over 1/2 second.
3844                    }
3845                } catch (InterruptedException e) {
3846                }
3847                processCpuTracker.update();
3848
3849                // We'll take the stack crawls of just the top apps using CPU.
3850                final int N = processCpuTracker.countWorkingStats();
3851                int numProcs = 0;
3852                for (int i=0; i<N && numProcs<5; i++) {
3853                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3854                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3855                        numProcs++;
3856                        try {
3857                            synchronized (observer) {
3858                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3859                                observer.wait(200);  // Wait for write-close, give up after 200msec
3860                            }
3861                        } catch (InterruptedException e) {
3862                            Log.wtf(TAG, e);
3863                        }
3864
3865                    }
3866                }
3867            }
3868        } finally {
3869            observer.stopWatching();
3870        }
3871    }
3872
3873    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3874        if (true || IS_USER_BUILD) {
3875            return;
3876        }
3877        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3878        if (tracesPath == null || tracesPath.length() == 0) {
3879            return;
3880        }
3881
3882        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3883        StrictMode.allowThreadDiskWrites();
3884        try {
3885            final File tracesFile = new File(tracesPath);
3886            final File tracesDir = tracesFile.getParentFile();
3887            final File tracesTmp = new File(tracesDir, "__tmp__");
3888            try {
3889                if (!tracesDir.exists()) {
3890                    tracesFile.mkdirs();
3891                    if (!SELinux.restorecon(tracesDir.getPath())) {
3892                        return;
3893                    }
3894                }
3895                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3896
3897                if (tracesFile.exists()) {
3898                    tracesTmp.delete();
3899                    tracesFile.renameTo(tracesTmp);
3900                }
3901                StringBuilder sb = new StringBuilder();
3902                Time tobj = new Time();
3903                tobj.set(System.currentTimeMillis());
3904                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3905                sb.append(": ");
3906                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3907                sb.append(" since ");
3908                sb.append(msg);
3909                FileOutputStream fos = new FileOutputStream(tracesFile);
3910                fos.write(sb.toString().getBytes());
3911                if (app == null) {
3912                    fos.write("\n*** No application process!".getBytes());
3913                }
3914                fos.close();
3915                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3916            } catch (IOException e) {
3917                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3918                return;
3919            }
3920
3921            if (app != null) {
3922                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3923                firstPids.add(app.pid);
3924                dumpStackTraces(tracesPath, firstPids, null, null, null);
3925            }
3926
3927            File lastTracesFile = null;
3928            File curTracesFile = null;
3929            for (int i=9; i>=0; i--) {
3930                String name = String.format(Locale.US, "slow%02d.txt", i);
3931                curTracesFile = new File(tracesDir, name);
3932                if (curTracesFile.exists()) {
3933                    if (lastTracesFile != null) {
3934                        curTracesFile.renameTo(lastTracesFile);
3935                    } else {
3936                        curTracesFile.delete();
3937                    }
3938                }
3939                lastTracesFile = curTracesFile;
3940            }
3941            tracesFile.renameTo(curTracesFile);
3942            if (tracesTmp.exists()) {
3943                tracesTmp.renameTo(tracesFile);
3944            }
3945        } finally {
3946            StrictMode.setThreadPolicy(oldPolicy);
3947        }
3948    }
3949
3950    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3951            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3952        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3953        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3954
3955        if (mController != null) {
3956            try {
3957                // 0 == continue, -1 = kill process immediately
3958                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3959                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3960            } catch (RemoteException e) {
3961                mController = null;
3962                Watchdog.getInstance().setActivityController(null);
3963            }
3964        }
3965
3966        long anrTime = SystemClock.uptimeMillis();
3967        if (MONITOR_CPU_USAGE) {
3968            updateCpuStatsNow();
3969        }
3970
3971        synchronized (this) {
3972            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3973            if (mShuttingDown) {
3974                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3975                return;
3976            } else if (app.notResponding) {
3977                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3978                return;
3979            } else if (app.crashing) {
3980                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3981                return;
3982            }
3983
3984            // In case we come through here for the same app before completing
3985            // this one, mark as anring now so we will bail out.
3986            app.notResponding = true;
3987
3988            // Log the ANR to the event log.
3989            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3990                    app.processName, app.info.flags, annotation);
3991
3992            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3993            firstPids.add(app.pid);
3994
3995            int parentPid = app.pid;
3996            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3997            if (parentPid != app.pid) firstPids.add(parentPid);
3998
3999            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4000
4001            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4002                ProcessRecord r = mLruProcesses.get(i);
4003                if (r != null && r.thread != null) {
4004                    int pid = r.pid;
4005                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4006                        if (r.persistent) {
4007                            firstPids.add(pid);
4008                        } else {
4009                            lastPids.put(pid, Boolean.TRUE);
4010                        }
4011                    }
4012                }
4013            }
4014        }
4015
4016        // Log the ANR to the main log.
4017        StringBuilder info = new StringBuilder();
4018        info.setLength(0);
4019        info.append("ANR in ").append(app.processName);
4020        if (activity != null && activity.shortComponentName != null) {
4021            info.append(" (").append(activity.shortComponentName).append(")");
4022        }
4023        info.append("\n");
4024        info.append("PID: ").append(app.pid).append("\n");
4025        if (annotation != null) {
4026            info.append("Reason: ").append(annotation).append("\n");
4027        }
4028        if (parent != null && parent != activity) {
4029            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4030        }
4031
4032        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4033
4034        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4035                NATIVE_STACKS_OF_INTEREST);
4036
4037        String cpuInfo = null;
4038        if (MONITOR_CPU_USAGE) {
4039            updateCpuStatsNow();
4040            synchronized (mProcessCpuThread) {
4041                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4042            }
4043            info.append(processCpuTracker.printCurrentLoad());
4044            info.append(cpuInfo);
4045        }
4046
4047        info.append(processCpuTracker.printCurrentState(anrTime));
4048
4049        Slog.e(TAG, info.toString());
4050        if (tracesFile == null) {
4051            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4052            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4053        }
4054
4055        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4056                cpuInfo, tracesFile, null);
4057
4058        if (mController != null) {
4059            try {
4060                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4061                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4062                if (res != 0) {
4063                    if (res < 0 && app.pid != MY_PID) {
4064                        Process.killProcess(app.pid);
4065                    } else {
4066                        synchronized (this) {
4067                            mServices.scheduleServiceTimeoutLocked(app);
4068                        }
4069                    }
4070                    return;
4071                }
4072            } catch (RemoteException e) {
4073                mController = null;
4074                Watchdog.getInstance().setActivityController(null);
4075            }
4076        }
4077
4078        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4079        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4080                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4081
4082        synchronized (this) {
4083            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4084                killUnneededProcessLocked(app, "background ANR");
4085                return;
4086            }
4087
4088            // Set the app's notResponding state, and look up the errorReportReceiver
4089            makeAppNotRespondingLocked(app,
4090                    activity != null ? activity.shortComponentName : null,
4091                    annotation != null ? "ANR " + annotation : "ANR",
4092                    info.toString());
4093
4094            // Bring up the infamous App Not Responding dialog
4095            Message msg = Message.obtain();
4096            HashMap<String, Object> map = new HashMap<String, Object>();
4097            msg.what = SHOW_NOT_RESPONDING_MSG;
4098            msg.obj = map;
4099            msg.arg1 = aboveSystem ? 1 : 0;
4100            map.put("app", app);
4101            if (activity != null) {
4102                map.put("activity", activity);
4103            }
4104
4105            mHandler.sendMessage(msg);
4106        }
4107    }
4108
4109    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4110        if (!mLaunchWarningShown) {
4111            mLaunchWarningShown = true;
4112            mHandler.post(new Runnable() {
4113                @Override
4114                public void run() {
4115                    synchronized (ActivityManagerService.this) {
4116                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4117                        d.show();
4118                        mHandler.postDelayed(new Runnable() {
4119                            @Override
4120                            public void run() {
4121                                synchronized (ActivityManagerService.this) {
4122                                    d.dismiss();
4123                                    mLaunchWarningShown = false;
4124                                }
4125                            }
4126                        }, 4000);
4127                    }
4128                }
4129            });
4130        }
4131    }
4132
4133    @Override
4134    public boolean clearApplicationUserData(final String packageName,
4135            final IPackageDataObserver observer, int userId) {
4136        enforceNotIsolatedCaller("clearApplicationUserData");
4137        int uid = Binder.getCallingUid();
4138        int pid = Binder.getCallingPid();
4139        userId = handleIncomingUser(pid, uid,
4140                userId, false, true, "clearApplicationUserData", null);
4141        long callingId = Binder.clearCallingIdentity();
4142        try {
4143            IPackageManager pm = AppGlobals.getPackageManager();
4144            int pkgUid = -1;
4145            synchronized(this) {
4146                try {
4147                    pkgUid = pm.getPackageUid(packageName, userId);
4148                } catch (RemoteException e) {
4149                }
4150                if (pkgUid == -1) {
4151                    Slog.w(TAG, "Invalid packageName: " + packageName);
4152                    if (observer != null) {
4153                        try {
4154                            observer.onRemoveCompleted(packageName, false);
4155                        } catch (RemoteException e) {
4156                            Slog.i(TAG, "Observer no longer exists.");
4157                        }
4158                    }
4159                    return false;
4160                }
4161                if (uid == pkgUid || checkComponentPermission(
4162                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4163                        pid, uid, -1, true)
4164                        == PackageManager.PERMISSION_GRANTED) {
4165                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4166                } else {
4167                    throw new SecurityException("PID " + pid + " does not have permission "
4168                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4169                                    + " of package " + packageName);
4170                }
4171            }
4172
4173            try {
4174                // Clear application user data
4175                pm.clearApplicationUserData(packageName, observer, userId);
4176
4177                // Remove all permissions granted from/to this package
4178                removeUriPermissionsForPackageLocked(packageName, userId, true);
4179
4180                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4181                        Uri.fromParts("package", packageName, null));
4182                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4183                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4184                        null, null, 0, null, null, null, false, false, userId);
4185            } catch (RemoteException e) {
4186            }
4187        } finally {
4188            Binder.restoreCallingIdentity(callingId);
4189        }
4190        return true;
4191    }
4192
4193    @Override
4194    public void killBackgroundProcesses(final String packageName, int userId) {
4195        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4196                != PackageManager.PERMISSION_GRANTED &&
4197                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4198                        != PackageManager.PERMISSION_GRANTED) {
4199            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4200                    + Binder.getCallingPid()
4201                    + ", uid=" + Binder.getCallingUid()
4202                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4203            Slog.w(TAG, msg);
4204            throw new SecurityException(msg);
4205        }
4206
4207        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4208                userId, true, true, "killBackgroundProcesses", null);
4209        long callingId = Binder.clearCallingIdentity();
4210        try {
4211            IPackageManager pm = AppGlobals.getPackageManager();
4212            synchronized(this) {
4213                int appId = -1;
4214                try {
4215                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4216                } catch (RemoteException e) {
4217                }
4218                if (appId == -1) {
4219                    Slog.w(TAG, "Invalid packageName: " + packageName);
4220                    return;
4221                }
4222                killPackageProcessesLocked(packageName, appId, userId,
4223                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4224            }
4225        } finally {
4226            Binder.restoreCallingIdentity(callingId);
4227        }
4228    }
4229
4230    @Override
4231    public void killAllBackgroundProcesses() {
4232        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4233                != PackageManager.PERMISSION_GRANTED) {
4234            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4235                    + Binder.getCallingPid()
4236                    + ", uid=" + Binder.getCallingUid()
4237                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4238            Slog.w(TAG, msg);
4239            throw new SecurityException(msg);
4240        }
4241
4242        long callingId = Binder.clearCallingIdentity();
4243        try {
4244            synchronized(this) {
4245                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4246                final int NP = mProcessNames.getMap().size();
4247                for (int ip=0; ip<NP; ip++) {
4248                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4249                    final int NA = apps.size();
4250                    for (int ia=0; ia<NA; ia++) {
4251                        ProcessRecord app = apps.valueAt(ia);
4252                        if (app.persistent) {
4253                            // we don't kill persistent processes
4254                            continue;
4255                        }
4256                        if (app.removed) {
4257                            procs.add(app);
4258                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4259                            app.removed = true;
4260                            procs.add(app);
4261                        }
4262                    }
4263                }
4264
4265                int N = procs.size();
4266                for (int i=0; i<N; i++) {
4267                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4268                }
4269                mAllowLowerMemLevel = true;
4270                updateOomAdjLocked();
4271                doLowMemReportIfNeededLocked(null);
4272            }
4273        } finally {
4274            Binder.restoreCallingIdentity(callingId);
4275        }
4276    }
4277
4278    @Override
4279    public void forceStopPackage(final String packageName, int userId) {
4280        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4281                != PackageManager.PERMISSION_GRANTED) {
4282            String msg = "Permission Denial: forceStopPackage() from pid="
4283                    + Binder.getCallingPid()
4284                    + ", uid=" + Binder.getCallingUid()
4285                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4286            Slog.w(TAG, msg);
4287            throw new SecurityException(msg);
4288        }
4289        final int callingPid = Binder.getCallingPid();
4290        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4291                userId, true, true, "forceStopPackage", null);
4292        long callingId = Binder.clearCallingIdentity();
4293        try {
4294            IPackageManager pm = AppGlobals.getPackageManager();
4295            synchronized(this) {
4296                int[] users = userId == UserHandle.USER_ALL
4297                        ? getUsersLocked() : new int[] { userId };
4298                for (int user : users) {
4299                    int pkgUid = -1;
4300                    try {
4301                        pkgUid = pm.getPackageUid(packageName, user);
4302                    } catch (RemoteException e) {
4303                    }
4304                    if (pkgUid == -1) {
4305                        Slog.w(TAG, "Invalid packageName: " + packageName);
4306                        continue;
4307                    }
4308                    try {
4309                        pm.setPackageStoppedState(packageName, true, user);
4310                    } catch (RemoteException e) {
4311                    } catch (IllegalArgumentException e) {
4312                        Slog.w(TAG, "Failed trying to unstop package "
4313                                + packageName + ": " + e);
4314                    }
4315                    if (isUserRunningLocked(user, false)) {
4316                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4317                    }
4318                }
4319            }
4320        } finally {
4321            Binder.restoreCallingIdentity(callingId);
4322        }
4323    }
4324
4325    /*
4326     * The pkg name and app id have to be specified.
4327     */
4328    @Override
4329    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4330        if (pkg == null) {
4331            return;
4332        }
4333        // Make sure the uid is valid.
4334        if (appid < 0) {
4335            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4336            return;
4337        }
4338        int callerUid = Binder.getCallingUid();
4339        // Only the system server can kill an application
4340        if (callerUid == Process.SYSTEM_UID) {
4341            // Post an aysnc message to kill the application
4342            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4343            msg.arg1 = appid;
4344            msg.arg2 = 0;
4345            Bundle bundle = new Bundle();
4346            bundle.putString("pkg", pkg);
4347            bundle.putString("reason", reason);
4348            msg.obj = bundle;
4349            mHandler.sendMessage(msg);
4350        } else {
4351            throw new SecurityException(callerUid + " cannot kill pkg: " +
4352                    pkg);
4353        }
4354    }
4355
4356    @Override
4357    public void closeSystemDialogs(String reason) {
4358        enforceNotIsolatedCaller("closeSystemDialogs");
4359
4360        final int pid = Binder.getCallingPid();
4361        final int uid = Binder.getCallingUid();
4362        final long origId = Binder.clearCallingIdentity();
4363        try {
4364            synchronized (this) {
4365                // Only allow this from foreground processes, so that background
4366                // applications can't abuse it to prevent system UI from being shown.
4367                if (uid >= Process.FIRST_APPLICATION_UID) {
4368                    ProcessRecord proc;
4369                    synchronized (mPidsSelfLocked) {
4370                        proc = mPidsSelfLocked.get(pid);
4371                    }
4372                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4373                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4374                                + " from background process " + proc);
4375                        return;
4376                    }
4377                }
4378                closeSystemDialogsLocked(reason);
4379            }
4380        } finally {
4381            Binder.restoreCallingIdentity(origId);
4382        }
4383    }
4384
4385    void closeSystemDialogsLocked(String reason) {
4386        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4387        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4388                | Intent.FLAG_RECEIVER_FOREGROUND);
4389        if (reason != null) {
4390            intent.putExtra("reason", reason);
4391        }
4392        mWindowManager.closeSystemDialogs(reason);
4393
4394        mStackSupervisor.closeSystemDialogsLocked();
4395
4396        broadcastIntentLocked(null, null, intent, null,
4397                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4398                Process.SYSTEM_UID, UserHandle.USER_ALL);
4399    }
4400
4401    @Override
4402    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4403        enforceNotIsolatedCaller("getProcessMemoryInfo");
4404        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4405        for (int i=pids.length-1; i>=0; i--) {
4406            ProcessRecord proc;
4407            int oomAdj;
4408            synchronized (this) {
4409                synchronized (mPidsSelfLocked) {
4410                    proc = mPidsSelfLocked.get(pids[i]);
4411                    oomAdj = proc != null ? proc.setAdj : 0;
4412                }
4413            }
4414            infos[i] = new Debug.MemoryInfo();
4415            Debug.getMemoryInfo(pids[i], infos[i]);
4416            if (proc != null) {
4417                synchronized (this) {
4418                    if (proc.thread != null && proc.setAdj == oomAdj) {
4419                        // Record this for posterity if the process has been stable.
4420                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4421                                infos[i].getTotalUss(), false, proc.pkgList);
4422                    }
4423                }
4424            }
4425        }
4426        return infos;
4427    }
4428
4429    @Override
4430    public long[] getProcessPss(int[] pids) {
4431        enforceNotIsolatedCaller("getProcessPss");
4432        long[] pss = new long[pids.length];
4433        for (int i=pids.length-1; i>=0; i--) {
4434            ProcessRecord proc;
4435            int oomAdj;
4436            synchronized (this) {
4437                synchronized (mPidsSelfLocked) {
4438                    proc = mPidsSelfLocked.get(pids[i]);
4439                    oomAdj = proc != null ? proc.setAdj : 0;
4440                }
4441            }
4442            long[] tmpUss = new long[1];
4443            pss[i] = Debug.getPss(pids[i], tmpUss);
4444            if (proc != null) {
4445                synchronized (this) {
4446                    if (proc.thread != null && proc.setAdj == oomAdj) {
4447                        // Record this for posterity if the process has been stable.
4448                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4449                    }
4450                }
4451            }
4452        }
4453        return pss;
4454    }
4455
4456    @Override
4457    public void killApplicationProcess(String processName, int uid) {
4458        if (processName == null) {
4459            return;
4460        }
4461
4462        int callerUid = Binder.getCallingUid();
4463        // Only the system server can kill an application
4464        if (callerUid == Process.SYSTEM_UID) {
4465            synchronized (this) {
4466                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4467                if (app != null && app.thread != null) {
4468                    try {
4469                        app.thread.scheduleSuicide();
4470                    } catch (RemoteException e) {
4471                        // If the other end already died, then our work here is done.
4472                    }
4473                } else {
4474                    Slog.w(TAG, "Process/uid not found attempting kill of "
4475                            + processName + " / " + uid);
4476                }
4477            }
4478        } else {
4479            throw new SecurityException(callerUid + " cannot kill app process: " +
4480                    processName);
4481        }
4482    }
4483
4484    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4485        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4486                false, true, false, UserHandle.getUserId(uid), reason);
4487        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4488                Uri.fromParts("package", packageName, null));
4489        if (!mProcessesReady) {
4490            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4491                    | Intent.FLAG_RECEIVER_FOREGROUND);
4492        }
4493        intent.putExtra(Intent.EXTRA_UID, uid);
4494        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4495        broadcastIntentLocked(null, null, intent,
4496                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4497                false, false,
4498                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4499    }
4500
4501    private void forceStopUserLocked(int userId, String reason) {
4502        forceStopPackageLocked(null, -1, false, false, true, false, userId, reason);
4503        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4504        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4505                | Intent.FLAG_RECEIVER_FOREGROUND);
4506        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4507        broadcastIntentLocked(null, null, intent,
4508                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4509                false, false,
4510                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4511    }
4512
4513    private final boolean killPackageProcessesLocked(String packageName, int appId,
4514            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4515            boolean doit, boolean evenPersistent, String reason) {
4516        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4517
4518        // Remove all processes this package may have touched: all with the
4519        // same UID (except for the system or root user), and all whose name
4520        // matches the package name.
4521        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4522        final int NP = mProcessNames.getMap().size();
4523        for (int ip=0; ip<NP; ip++) {
4524            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4525            final int NA = apps.size();
4526            for (int ia=0; ia<NA; ia++) {
4527                ProcessRecord app = apps.valueAt(ia);
4528                if (app.persistent && !evenPersistent) {
4529                    // we don't kill persistent processes
4530                    continue;
4531                }
4532                if (app.removed) {
4533                    if (doit) {
4534                        procs.add(app);
4535                    }
4536                    continue;
4537                }
4538
4539                // Skip process if it doesn't meet our oom adj requirement.
4540                if (app.setAdj < minOomAdj) {
4541                    continue;
4542                }
4543
4544                // If no package is specified, we call all processes under the
4545                // give user id.
4546                if (packageName == null) {
4547                    if (app.userId != userId) {
4548                        continue;
4549                    }
4550                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4551                        continue;
4552                    }
4553                // Package has been specified, we want to hit all processes
4554                // that match it.  We need to qualify this by the processes
4555                // that are running under the specified app and user ID.
4556                } else {
4557                    if (UserHandle.getAppId(app.uid) != appId) {
4558                        continue;
4559                    }
4560                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4561                        continue;
4562                    }
4563                    if (!app.pkgList.containsKey(packageName)) {
4564                        continue;
4565                    }
4566                }
4567
4568                // Process has passed all conditions, kill it!
4569                if (!doit) {
4570                    return true;
4571                }
4572                app.removed = true;
4573                procs.add(app);
4574            }
4575        }
4576
4577        int N = procs.size();
4578        for (int i=0; i<N; i++) {
4579            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4580        }
4581        updateOomAdjLocked();
4582        return N > 0;
4583    }
4584
4585    private final boolean forceStopPackageLocked(String name, int appId,
4586            boolean callerWillRestart, boolean purgeCache, boolean doit,
4587            boolean evenPersistent, int userId, String reason) {
4588        int i;
4589        int N;
4590
4591        if (userId == UserHandle.USER_ALL && name == null) {
4592            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4593        }
4594
4595        if (appId < 0 && name != null) {
4596            try {
4597                appId = UserHandle.getAppId(
4598                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4599            } catch (RemoteException e) {
4600            }
4601        }
4602
4603        if (doit) {
4604            if (name != null) {
4605                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4606                        + " user=" + userId + ": " + reason);
4607            } else {
4608                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4609            }
4610
4611            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4612            for (int ip=pmap.size()-1; ip>=0; ip--) {
4613                SparseArray<Long> ba = pmap.valueAt(ip);
4614                for (i=ba.size()-1; i>=0; i--) {
4615                    boolean remove = false;
4616                    final int entUid = ba.keyAt(i);
4617                    if (name != null) {
4618                        if (userId == UserHandle.USER_ALL) {
4619                            if (UserHandle.getAppId(entUid) == appId) {
4620                                remove = true;
4621                            }
4622                        } else {
4623                            if (entUid == UserHandle.getUid(userId, appId)) {
4624                                remove = true;
4625                            }
4626                        }
4627                    } else if (UserHandle.getUserId(entUid) == userId) {
4628                        remove = true;
4629                    }
4630                    if (remove) {
4631                        ba.removeAt(i);
4632                    }
4633                }
4634                if (ba.size() == 0) {
4635                    pmap.removeAt(ip);
4636                }
4637            }
4638        }
4639
4640        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4641                -100, callerWillRestart, true, doit, evenPersistent,
4642                name == null ? ("stop user " + userId) : ("stop " + name));
4643
4644        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4645            if (!doit) {
4646                return true;
4647            }
4648            didSomething = true;
4649        }
4650
4651        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4652            if (!doit) {
4653                return true;
4654            }
4655            didSomething = true;
4656        }
4657
4658        if (name == null) {
4659            // Remove all sticky broadcasts from this user.
4660            mStickyBroadcasts.remove(userId);
4661        }
4662
4663        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4664        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4665                userId, providers)) {
4666            if (!doit) {
4667                return true;
4668            }
4669            didSomething = true;
4670        }
4671        N = providers.size();
4672        for (i=0; i<N; i++) {
4673            removeDyingProviderLocked(null, providers.get(i), true);
4674        }
4675
4676        // Remove transient permissions granted from/to this package/user
4677        removeUriPermissionsForPackageLocked(name, userId, false);
4678
4679        if (name == null) {
4680            // Remove pending intents.  For now we only do this when force
4681            // stopping users, because we have some problems when doing this
4682            // for packages -- app widgets are not currently cleaned up for
4683            // such packages, so they can be left with bad pending intents.
4684            if (mIntentSenderRecords.size() > 0) {
4685                Iterator<WeakReference<PendingIntentRecord>> it
4686                        = mIntentSenderRecords.values().iterator();
4687                while (it.hasNext()) {
4688                    WeakReference<PendingIntentRecord> wpir = it.next();
4689                    if (wpir == null) {
4690                        it.remove();
4691                        continue;
4692                    }
4693                    PendingIntentRecord pir = wpir.get();
4694                    if (pir == null) {
4695                        it.remove();
4696                        continue;
4697                    }
4698                    if (name == null) {
4699                        // Stopping user, remove all objects for the user.
4700                        if (pir.key.userId != userId) {
4701                            // Not the same user, skip it.
4702                            continue;
4703                        }
4704                    } else {
4705                        if (UserHandle.getAppId(pir.uid) != appId) {
4706                            // Different app id, skip it.
4707                            continue;
4708                        }
4709                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4710                            // Different user, skip it.
4711                            continue;
4712                        }
4713                        if (!pir.key.packageName.equals(name)) {
4714                            // Different package, skip it.
4715                            continue;
4716                        }
4717                    }
4718                    if (!doit) {
4719                        return true;
4720                    }
4721                    didSomething = true;
4722                    it.remove();
4723                    pir.canceled = true;
4724                    if (pir.key.activity != null) {
4725                        pir.key.activity.pendingResults.remove(pir.ref);
4726                    }
4727                }
4728            }
4729        }
4730
4731        if (doit) {
4732            if (purgeCache && name != null) {
4733                AttributeCache ac = AttributeCache.instance();
4734                if (ac != null) {
4735                    ac.removePackage(name);
4736                }
4737            }
4738            if (mBooted) {
4739                mStackSupervisor.resumeTopActivitiesLocked();
4740                mStackSupervisor.scheduleIdleLocked();
4741            }
4742        }
4743
4744        return didSomething;
4745    }
4746
4747    private final boolean removeProcessLocked(ProcessRecord app,
4748            boolean callerWillRestart, boolean allowRestart, String reason) {
4749        final String name = app.processName;
4750        final int uid = app.uid;
4751        if (DEBUG_PROCESSES) Slog.d(
4752            TAG, "Force removing proc " + app.toShortString() + " (" + name
4753            + "/" + uid + ")");
4754
4755        mProcessNames.remove(name, uid);
4756        mIsolatedProcesses.remove(app.uid);
4757        if (mHeavyWeightProcess == app) {
4758            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4759                    mHeavyWeightProcess.userId, 0));
4760            mHeavyWeightProcess = null;
4761        }
4762        boolean needRestart = false;
4763        if (app.pid > 0 && app.pid != MY_PID) {
4764            int pid = app.pid;
4765            synchronized (mPidsSelfLocked) {
4766                mPidsSelfLocked.remove(pid);
4767                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4768            }
4769            killUnneededProcessLocked(app, reason);
4770            handleAppDiedLocked(app, true, allowRestart);
4771            removeLruProcessLocked(app);
4772
4773            if (app.persistent && !app.isolated) {
4774                if (!callerWillRestart) {
4775                    addAppLocked(app.info, false);
4776                } else {
4777                    needRestart = true;
4778                }
4779            }
4780        } else {
4781            mRemovedProcesses.add(app);
4782        }
4783
4784        return needRestart;
4785    }
4786
4787    private final void processStartTimedOutLocked(ProcessRecord app) {
4788        final int pid = app.pid;
4789        boolean gone = false;
4790        synchronized (mPidsSelfLocked) {
4791            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4792            if (knownApp != null && knownApp.thread == null) {
4793                mPidsSelfLocked.remove(pid);
4794                gone = true;
4795            }
4796        }
4797
4798        if (gone) {
4799            Slog.w(TAG, "Process " + app + " failed to attach");
4800            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4801                    pid, app.uid, app.processName);
4802            mProcessNames.remove(app.processName, app.uid);
4803            mIsolatedProcesses.remove(app.uid);
4804            if (mHeavyWeightProcess == app) {
4805                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4806                        mHeavyWeightProcess.userId, 0));
4807                mHeavyWeightProcess = null;
4808            }
4809            // Take care of any launching providers waiting for this process.
4810            checkAppInLaunchingProvidersLocked(app, true);
4811            // Take care of any services that are waiting for the process.
4812            mServices.processStartTimedOutLocked(app);
4813            killUnneededProcessLocked(app, "start timeout");
4814            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4815                Slog.w(TAG, "Unattached app died before backup, skipping");
4816                try {
4817                    IBackupManager bm = IBackupManager.Stub.asInterface(
4818                            ServiceManager.getService(Context.BACKUP_SERVICE));
4819                    bm.agentDisconnected(app.info.packageName);
4820                } catch (RemoteException e) {
4821                    // Can't happen; the backup manager is local
4822                }
4823            }
4824            if (isPendingBroadcastProcessLocked(pid)) {
4825                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4826                skipPendingBroadcastLocked(pid);
4827            }
4828        } else {
4829            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4830        }
4831    }
4832
4833    private final boolean attachApplicationLocked(IApplicationThread thread,
4834            int pid) {
4835
4836        // Find the application record that is being attached...  either via
4837        // the pid if we are running in multiple processes, or just pull the
4838        // next app record if we are emulating process with anonymous threads.
4839        ProcessRecord app;
4840        if (pid != MY_PID && pid >= 0) {
4841            synchronized (mPidsSelfLocked) {
4842                app = mPidsSelfLocked.get(pid);
4843            }
4844        } else {
4845            app = null;
4846        }
4847
4848        if (app == null) {
4849            Slog.w(TAG, "No pending application record for pid " + pid
4850                    + " (IApplicationThread " + thread + "); dropping process");
4851            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4852            if (pid > 0 && pid != MY_PID) {
4853                Process.killProcessQuiet(pid);
4854            } else {
4855                try {
4856                    thread.scheduleExit();
4857                } catch (Exception e) {
4858                    // Ignore exceptions.
4859                }
4860            }
4861            return false;
4862        }
4863
4864        // If this application record is still attached to a previous
4865        // process, clean it up now.
4866        if (app.thread != null) {
4867            handleAppDiedLocked(app, true, true);
4868        }
4869
4870        // Tell the process all about itself.
4871
4872        if (localLOGV) Slog.v(
4873                TAG, "Binding process pid " + pid + " to record " + app);
4874
4875        final String processName = app.processName;
4876        try {
4877            AppDeathRecipient adr = new AppDeathRecipient(
4878                    app, pid, thread);
4879            thread.asBinder().linkToDeath(adr, 0);
4880            app.deathRecipient = adr;
4881        } catch (RemoteException e) {
4882            app.resetPackageList(mProcessStats);
4883            startProcessLocked(app, "link fail", processName);
4884            return false;
4885        }
4886
4887        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4888
4889        app.makeActive(thread, mProcessStats);
4890        app.curAdj = app.setAdj = -100;
4891        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4892        app.forcingToForeground = null;
4893        app.foregroundServices = false;
4894        app.hasShownUi = false;
4895        app.debugging = false;
4896        app.cached = false;
4897
4898        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4899
4900        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4901        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4902
4903        if (!normalMode) {
4904            Slog.i(TAG, "Launching preboot mode app: " + app);
4905        }
4906
4907        if (localLOGV) Slog.v(
4908            TAG, "New app record " + app
4909            + " thread=" + thread.asBinder() + " pid=" + pid);
4910        try {
4911            int testMode = IApplicationThread.DEBUG_OFF;
4912            if (mDebugApp != null && mDebugApp.equals(processName)) {
4913                testMode = mWaitForDebugger
4914                    ? IApplicationThread.DEBUG_WAIT
4915                    : IApplicationThread.DEBUG_ON;
4916                app.debugging = true;
4917                if (mDebugTransient) {
4918                    mDebugApp = mOrigDebugApp;
4919                    mWaitForDebugger = mOrigWaitForDebugger;
4920                }
4921            }
4922            String profileFile = app.instrumentationProfileFile;
4923            ParcelFileDescriptor profileFd = null;
4924            boolean profileAutoStop = false;
4925            if (mProfileApp != null && mProfileApp.equals(processName)) {
4926                mProfileProc = app;
4927                profileFile = mProfileFile;
4928                profileFd = mProfileFd;
4929                profileAutoStop = mAutoStopProfiler;
4930            }
4931            boolean enableOpenGlTrace = false;
4932            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4933                enableOpenGlTrace = true;
4934                mOpenGlTraceApp = null;
4935            }
4936
4937            // If the app is being launched for restore or full backup, set it up specially
4938            boolean isRestrictedBackupMode = false;
4939            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4940                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4941                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4942                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4943            }
4944
4945            ensurePackageDexOpt(app.instrumentationInfo != null
4946                    ? app.instrumentationInfo.packageName
4947                    : app.info.packageName);
4948            if (app.instrumentationClass != null) {
4949                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4950            }
4951            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4952                    + processName + " with config " + mConfiguration);
4953            ApplicationInfo appInfo = app.instrumentationInfo != null
4954                    ? app.instrumentationInfo : app.info;
4955            app.compat = compatibilityInfoForPackageLocked(appInfo);
4956            if (profileFd != null) {
4957                profileFd = profileFd.dup();
4958            }
4959            thread.bindApplication(processName, appInfo, providers,
4960                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4961                    app.instrumentationArguments, app.instrumentationWatcher,
4962                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4963                    isRestrictedBackupMode || !normalMode, app.persistent,
4964                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4965                    mCoreSettingsObserver.getCoreSettingsLocked());
4966            updateLruProcessLocked(app, false, null);
4967            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4968        } catch (Exception e) {
4969            // todo: Yikes!  What should we do?  For now we will try to
4970            // start another process, but that could easily get us in
4971            // an infinite loop of restarting processes...
4972            Slog.w(TAG, "Exception thrown during bind!", e);
4973
4974            app.resetPackageList(mProcessStats);
4975            app.unlinkDeathRecipient();
4976            startProcessLocked(app, "bind fail", processName);
4977            return false;
4978        }
4979
4980        // Remove this record from the list of starting applications.
4981        mPersistentStartingProcesses.remove(app);
4982        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4983                "Attach application locked removing on hold: " + app);
4984        mProcessesOnHold.remove(app);
4985
4986        boolean badApp = false;
4987        boolean didSomething = false;
4988
4989        // See if the top visible activity is waiting to run in this process...
4990        if (normalMode) {
4991            try {
4992                if (mStackSupervisor.attachApplicationLocked(app)) {
4993                    didSomething = true;
4994                }
4995            } catch (Exception e) {
4996                badApp = true;
4997            }
4998        }
4999
5000        // Find any services that should be running in this process...
5001        if (!badApp) {
5002            try {
5003                didSomething |= mServices.attachApplicationLocked(app, processName);
5004            } catch (Exception e) {
5005                badApp = true;
5006            }
5007        }
5008
5009        // Check if a next-broadcast receiver is in this process...
5010        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5011            try {
5012                didSomething |= sendPendingBroadcastsLocked(app);
5013            } catch (Exception e) {
5014                // If the app died trying to launch the receiver we declare it 'bad'
5015                badApp = true;
5016            }
5017        }
5018
5019        // Check whether the next backup agent is in this process...
5020        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5021            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5022            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5023            try {
5024                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5025                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5026                        mBackupTarget.backupMode);
5027            } catch (Exception e) {
5028                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5029                e.printStackTrace();
5030            }
5031        }
5032
5033        if (badApp) {
5034            // todo: Also need to kill application to deal with all
5035            // kinds of exceptions.
5036            handleAppDiedLocked(app, false, true);
5037            return false;
5038        }
5039
5040        if (!didSomething) {
5041            updateOomAdjLocked();
5042        }
5043
5044        return true;
5045    }
5046
5047    @Override
5048    public final void attachApplication(IApplicationThread thread) {
5049        synchronized (this) {
5050            int callingPid = Binder.getCallingPid();
5051            final long origId = Binder.clearCallingIdentity();
5052            attachApplicationLocked(thread, callingPid);
5053            Binder.restoreCallingIdentity(origId);
5054        }
5055    }
5056
5057    @Override
5058    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5059        final long origId = Binder.clearCallingIdentity();
5060        synchronized (this) {
5061            ActivityStack stack = ActivityRecord.getStackLocked(token);
5062            if (stack != null) {
5063                ActivityRecord r =
5064                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5065                if (stopProfiling) {
5066                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5067                        try {
5068                            mProfileFd.close();
5069                        } catch (IOException e) {
5070                        }
5071                        clearProfilerLocked();
5072                    }
5073                }
5074            }
5075        }
5076        Binder.restoreCallingIdentity(origId);
5077    }
5078
5079    void enableScreenAfterBoot() {
5080        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5081                SystemClock.uptimeMillis());
5082        mWindowManager.enableScreenAfterBoot();
5083
5084        synchronized (this) {
5085            updateEventDispatchingLocked();
5086        }
5087    }
5088
5089    @Override
5090    public void showBootMessage(final CharSequence msg, final boolean always) {
5091        enforceNotIsolatedCaller("showBootMessage");
5092        mWindowManager.showBootMessage(msg, always);
5093    }
5094
5095    @Override
5096    public void dismissKeyguardOnNextActivity() {
5097        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5098        final long token = Binder.clearCallingIdentity();
5099        try {
5100            synchronized (this) {
5101                if (DEBUG_LOCKSCREEN) logLockScreen("");
5102                if (mLockScreenShown) {
5103                    mLockScreenShown = false;
5104                    comeOutOfSleepIfNeededLocked();
5105                }
5106                mStackSupervisor.setDismissKeyguard(true);
5107            }
5108        } finally {
5109            Binder.restoreCallingIdentity(token);
5110        }
5111    }
5112
5113    final void finishBooting() {
5114        IntentFilter pkgFilter = new IntentFilter();
5115        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5116        pkgFilter.addDataScheme("package");
5117        mContext.registerReceiver(new BroadcastReceiver() {
5118            @Override
5119            public void onReceive(Context context, Intent intent) {
5120                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5121                if (pkgs != null) {
5122                    for (String pkg : pkgs) {
5123                        synchronized (ActivityManagerService.this) {
5124                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0,
5125                                    "finished booting")) {
5126                                setResultCode(Activity.RESULT_OK);
5127                                return;
5128                            }
5129                        }
5130                    }
5131                }
5132            }
5133        }, pkgFilter);
5134
5135        synchronized (this) {
5136            // Ensure that any processes we had put on hold are now started
5137            // up.
5138            final int NP = mProcessesOnHold.size();
5139            if (NP > 0) {
5140                ArrayList<ProcessRecord> procs =
5141                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5142                for (int ip=0; ip<NP; ip++) {
5143                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5144                            + procs.get(ip));
5145                    startProcessLocked(procs.get(ip), "on-hold", null);
5146                }
5147            }
5148
5149            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
5150                // Start looking for apps that are abusing wake locks.
5151                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5152                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5153                // Tell anyone interested that we are done booting!
5154                SystemProperties.set("sys.boot_completed", "1");
5155                SystemProperties.set("dev.bootcomplete", "1");
5156                for (int i=0; i<mStartedUsers.size(); i++) {
5157                    UserStartedState uss = mStartedUsers.valueAt(i);
5158                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5159                        uss.mState = UserStartedState.STATE_RUNNING;
5160                        final int userId = mStartedUsers.keyAt(i);
5161                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5162                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5163                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5164                        broadcastIntentLocked(null, null, intent, null,
5165                                new IIntentReceiver.Stub() {
5166                                    @Override
5167                                    public void performReceive(Intent intent, int resultCode,
5168                                            String data, Bundle extras, boolean ordered,
5169                                            boolean sticky, int sendingUser) {
5170                                        synchronized (ActivityManagerService.this) {
5171                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5172                                                    true, false);
5173                                        }
5174                                    }
5175                                },
5176                                0, null, null,
5177                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5178                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5179                                userId);
5180                    }
5181                }
5182            }
5183        }
5184    }
5185
5186    final void ensureBootCompleted() {
5187        boolean booting;
5188        boolean enableScreen;
5189        synchronized (this) {
5190            booting = mBooting;
5191            mBooting = false;
5192            enableScreen = !mBooted;
5193            mBooted = true;
5194        }
5195
5196        if (booting) {
5197            finishBooting();
5198        }
5199
5200        if (enableScreen) {
5201            enableScreenAfterBoot();
5202        }
5203    }
5204
5205    @Override
5206    public final void activityResumed(IBinder token) {
5207        final long origId = Binder.clearCallingIdentity();
5208        synchronized(this) {
5209            ActivityStack stack = ActivityRecord.getStackLocked(token);
5210            if (stack != null) {
5211                ActivityRecord.activityResumedLocked(token);
5212            }
5213        }
5214        Binder.restoreCallingIdentity(origId);
5215    }
5216
5217    @Override
5218    public final void activityPaused(IBinder token) {
5219        final long origId = Binder.clearCallingIdentity();
5220        synchronized(this) {
5221            ActivityStack stack = ActivityRecord.getStackLocked(token);
5222            if (stack != null) {
5223                stack.activityPausedLocked(token, false);
5224            }
5225        }
5226        Binder.restoreCallingIdentity(origId);
5227    }
5228
5229    @Override
5230    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5231            CharSequence description) {
5232        if (localLOGV) Slog.v(
5233            TAG, "Activity stopped: token=" + token);
5234
5235        // Refuse possible leaked file descriptors
5236        if (icicle != null && icicle.hasFileDescriptors()) {
5237            throw new IllegalArgumentException("File descriptors passed in Bundle");
5238        }
5239
5240        ActivityRecord r = null;
5241
5242        final long origId = Binder.clearCallingIdentity();
5243
5244        synchronized (this) {
5245            r = ActivityRecord.isInStackLocked(token);
5246            if (r != null) {
5247                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5248            }
5249        }
5250
5251        if (r != null) {
5252            sendPendingThumbnail(r, null, null, null, false);
5253        }
5254
5255        trimApplications();
5256
5257        Binder.restoreCallingIdentity(origId);
5258    }
5259
5260    @Override
5261    public final void activityDestroyed(IBinder token) {
5262        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5263        synchronized (this) {
5264            ActivityStack stack = ActivityRecord.getStackLocked(token);
5265            if (stack != null) {
5266                stack.activityDestroyedLocked(token);
5267            }
5268        }
5269    }
5270
5271    @Override
5272    public String getCallingPackage(IBinder token) {
5273        synchronized (this) {
5274            ActivityRecord r = getCallingRecordLocked(token);
5275            return r != null ? r.info.packageName : null;
5276        }
5277    }
5278
5279    @Override
5280    public ComponentName getCallingActivity(IBinder token) {
5281        synchronized (this) {
5282            ActivityRecord r = getCallingRecordLocked(token);
5283            return r != null ? r.intent.getComponent() : null;
5284        }
5285    }
5286
5287    private ActivityRecord getCallingRecordLocked(IBinder token) {
5288        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5289        if (r == null) {
5290            return null;
5291        }
5292        return r.resultTo;
5293    }
5294
5295    @Override
5296    public ComponentName getActivityClassForToken(IBinder token) {
5297        synchronized(this) {
5298            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5299            if (r == null) {
5300                return null;
5301            }
5302            return r.intent.getComponent();
5303        }
5304    }
5305
5306    @Override
5307    public String getPackageForToken(IBinder token) {
5308        synchronized(this) {
5309            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5310            if (r == null) {
5311                return null;
5312            }
5313            return r.packageName;
5314        }
5315    }
5316
5317    @Override
5318    public IIntentSender getIntentSender(int type,
5319            String packageName, IBinder token, String resultWho,
5320            int requestCode, Intent[] intents, String[] resolvedTypes,
5321            int flags, Bundle options, int userId) {
5322        enforceNotIsolatedCaller("getIntentSender");
5323        // Refuse possible leaked file descriptors
5324        if (intents != null) {
5325            if (intents.length < 1) {
5326                throw new IllegalArgumentException("Intents array length must be >= 1");
5327            }
5328            for (int i=0; i<intents.length; i++) {
5329                Intent intent = intents[i];
5330                if (intent != null) {
5331                    if (intent.hasFileDescriptors()) {
5332                        throw new IllegalArgumentException("File descriptors passed in Intent");
5333                    }
5334                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5335                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5336                        throw new IllegalArgumentException(
5337                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5338                    }
5339                    intents[i] = new Intent(intent);
5340                }
5341            }
5342            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5343                throw new IllegalArgumentException(
5344                        "Intent array length does not match resolvedTypes length");
5345            }
5346        }
5347        if (options != null) {
5348            if (options.hasFileDescriptors()) {
5349                throw new IllegalArgumentException("File descriptors passed in options");
5350            }
5351        }
5352
5353        synchronized(this) {
5354            int callingUid = Binder.getCallingUid();
5355            int origUserId = userId;
5356            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5357                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5358                    "getIntentSender", null);
5359            if (origUserId == UserHandle.USER_CURRENT) {
5360                // We don't want to evaluate this until the pending intent is
5361                // actually executed.  However, we do want to always do the
5362                // security checking for it above.
5363                userId = UserHandle.USER_CURRENT;
5364            }
5365            try {
5366                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5367                    int uid = AppGlobals.getPackageManager()
5368                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5369                    if (!UserHandle.isSameApp(callingUid, uid)) {
5370                        String msg = "Permission Denial: getIntentSender() from pid="
5371                            + Binder.getCallingPid()
5372                            + ", uid=" + Binder.getCallingUid()
5373                            + ", (need uid=" + uid + ")"
5374                            + " is not allowed to send as package " + packageName;
5375                        Slog.w(TAG, msg);
5376                        throw new SecurityException(msg);
5377                    }
5378                }
5379
5380                return getIntentSenderLocked(type, packageName, callingUid, userId,
5381                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5382
5383            } catch (RemoteException e) {
5384                throw new SecurityException(e);
5385            }
5386        }
5387    }
5388
5389    IIntentSender getIntentSenderLocked(int type, String packageName,
5390            int callingUid, int userId, IBinder token, String resultWho,
5391            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5392            Bundle options) {
5393        if (DEBUG_MU)
5394            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5395        ActivityRecord activity = null;
5396        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5397            activity = ActivityRecord.isInStackLocked(token);
5398            if (activity == null) {
5399                return null;
5400            }
5401            if (activity.finishing) {
5402                return null;
5403            }
5404        }
5405
5406        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5407        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5408        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5409        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5410                |PendingIntent.FLAG_UPDATE_CURRENT);
5411
5412        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5413                type, packageName, activity, resultWho,
5414                requestCode, intents, resolvedTypes, flags, options, userId);
5415        WeakReference<PendingIntentRecord> ref;
5416        ref = mIntentSenderRecords.get(key);
5417        PendingIntentRecord rec = ref != null ? ref.get() : null;
5418        if (rec != null) {
5419            if (!cancelCurrent) {
5420                if (updateCurrent) {
5421                    if (rec.key.requestIntent != null) {
5422                        rec.key.requestIntent.replaceExtras(intents != null ?
5423                                intents[intents.length - 1] : null);
5424                    }
5425                    if (intents != null) {
5426                        intents[intents.length-1] = rec.key.requestIntent;
5427                        rec.key.allIntents = intents;
5428                        rec.key.allResolvedTypes = resolvedTypes;
5429                    } else {
5430                        rec.key.allIntents = null;
5431                        rec.key.allResolvedTypes = null;
5432                    }
5433                }
5434                return rec;
5435            }
5436            rec.canceled = true;
5437            mIntentSenderRecords.remove(key);
5438        }
5439        if (noCreate) {
5440            return rec;
5441        }
5442        rec = new PendingIntentRecord(this, key, callingUid);
5443        mIntentSenderRecords.put(key, rec.ref);
5444        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5445            if (activity.pendingResults == null) {
5446                activity.pendingResults
5447                        = new HashSet<WeakReference<PendingIntentRecord>>();
5448            }
5449            activity.pendingResults.add(rec.ref);
5450        }
5451        return rec;
5452    }
5453
5454    @Override
5455    public void cancelIntentSender(IIntentSender sender) {
5456        if (!(sender instanceof PendingIntentRecord)) {
5457            return;
5458        }
5459        synchronized(this) {
5460            PendingIntentRecord rec = (PendingIntentRecord)sender;
5461            try {
5462                int uid = AppGlobals.getPackageManager()
5463                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5464                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5465                    String msg = "Permission Denial: cancelIntentSender() from pid="
5466                        + Binder.getCallingPid()
5467                        + ", uid=" + Binder.getCallingUid()
5468                        + " is not allowed to cancel packges "
5469                        + rec.key.packageName;
5470                    Slog.w(TAG, msg);
5471                    throw new SecurityException(msg);
5472                }
5473            } catch (RemoteException e) {
5474                throw new SecurityException(e);
5475            }
5476            cancelIntentSenderLocked(rec, true);
5477        }
5478    }
5479
5480    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5481        rec.canceled = true;
5482        mIntentSenderRecords.remove(rec.key);
5483        if (cleanActivity && rec.key.activity != null) {
5484            rec.key.activity.pendingResults.remove(rec.ref);
5485        }
5486    }
5487
5488    @Override
5489    public String getPackageForIntentSender(IIntentSender pendingResult) {
5490        if (!(pendingResult instanceof PendingIntentRecord)) {
5491            return null;
5492        }
5493        try {
5494            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5495            return res.key.packageName;
5496        } catch (ClassCastException e) {
5497        }
5498        return null;
5499    }
5500
5501    @Override
5502    public int getUidForIntentSender(IIntentSender sender) {
5503        if (sender instanceof PendingIntentRecord) {
5504            try {
5505                PendingIntentRecord res = (PendingIntentRecord)sender;
5506                return res.uid;
5507            } catch (ClassCastException e) {
5508            }
5509        }
5510        return -1;
5511    }
5512
5513    @Override
5514    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5515        if (!(pendingResult instanceof PendingIntentRecord)) {
5516            return false;
5517        }
5518        try {
5519            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5520            if (res.key.allIntents == null) {
5521                return false;
5522            }
5523            for (int i=0; i<res.key.allIntents.length; i++) {
5524                Intent intent = res.key.allIntents[i];
5525                if (intent.getPackage() != null && intent.getComponent() != null) {
5526                    return false;
5527                }
5528            }
5529            return true;
5530        } catch (ClassCastException e) {
5531        }
5532        return false;
5533    }
5534
5535    @Override
5536    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5537        if (!(pendingResult instanceof PendingIntentRecord)) {
5538            return false;
5539        }
5540        try {
5541            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5542            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5543                return true;
5544            }
5545            return false;
5546        } catch (ClassCastException e) {
5547        }
5548        return false;
5549    }
5550
5551    @Override
5552    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5553        if (!(pendingResult instanceof PendingIntentRecord)) {
5554            return null;
5555        }
5556        try {
5557            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5558            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5559        } catch (ClassCastException e) {
5560        }
5561        return null;
5562    }
5563
5564    @Override
5565    public void setProcessLimit(int max) {
5566        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5567                "setProcessLimit()");
5568        synchronized (this) {
5569            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5570            mProcessLimitOverride = max;
5571        }
5572        trimApplications();
5573    }
5574
5575    @Override
5576    public int getProcessLimit() {
5577        synchronized (this) {
5578            return mProcessLimitOverride;
5579        }
5580    }
5581
5582    void foregroundTokenDied(ForegroundToken token) {
5583        synchronized (ActivityManagerService.this) {
5584            synchronized (mPidsSelfLocked) {
5585                ForegroundToken cur
5586                    = mForegroundProcesses.get(token.pid);
5587                if (cur != token) {
5588                    return;
5589                }
5590                mForegroundProcesses.remove(token.pid);
5591                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5592                if (pr == null) {
5593                    return;
5594                }
5595                pr.forcingToForeground = null;
5596                pr.foregroundServices = false;
5597            }
5598            updateOomAdjLocked();
5599        }
5600    }
5601
5602    @Override
5603    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5604        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5605                "setProcessForeground()");
5606        synchronized(this) {
5607            boolean changed = false;
5608
5609            synchronized (mPidsSelfLocked) {
5610                ProcessRecord pr = mPidsSelfLocked.get(pid);
5611                if (pr == null && isForeground) {
5612                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5613                    return;
5614                }
5615                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5616                if (oldToken != null) {
5617                    oldToken.token.unlinkToDeath(oldToken, 0);
5618                    mForegroundProcesses.remove(pid);
5619                    if (pr != null) {
5620                        pr.forcingToForeground = null;
5621                    }
5622                    changed = true;
5623                }
5624                if (isForeground && token != null) {
5625                    ForegroundToken newToken = new ForegroundToken() {
5626                        @Override
5627                        public void binderDied() {
5628                            foregroundTokenDied(this);
5629                        }
5630                    };
5631                    newToken.pid = pid;
5632                    newToken.token = token;
5633                    try {
5634                        token.linkToDeath(newToken, 0);
5635                        mForegroundProcesses.put(pid, newToken);
5636                        pr.forcingToForeground = token;
5637                        changed = true;
5638                    } catch (RemoteException e) {
5639                        // If the process died while doing this, we will later
5640                        // do the cleanup with the process death link.
5641                    }
5642                }
5643            }
5644
5645            if (changed) {
5646                updateOomAdjLocked();
5647            }
5648        }
5649    }
5650
5651    // =========================================================
5652    // PERMISSIONS
5653    // =========================================================
5654
5655    static class PermissionController extends IPermissionController.Stub {
5656        ActivityManagerService mActivityManagerService;
5657        PermissionController(ActivityManagerService activityManagerService) {
5658            mActivityManagerService = activityManagerService;
5659        }
5660
5661        @Override
5662        public boolean checkPermission(String permission, int pid, int uid) {
5663            return mActivityManagerService.checkPermission(permission, pid,
5664                    uid) == PackageManager.PERMISSION_GRANTED;
5665        }
5666    }
5667
5668    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5669        @Override
5670        public int checkComponentPermission(String permission, int pid, int uid,
5671                int owningUid, boolean exported) {
5672            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5673                    owningUid, exported);
5674        }
5675
5676        @Override
5677        public Object getAMSLock() {
5678            return ActivityManagerService.this;
5679        }
5680    }
5681
5682    /**
5683     * This can be called with or without the global lock held.
5684     */
5685    int checkComponentPermission(String permission, int pid, int uid,
5686            int owningUid, boolean exported) {
5687        // We might be performing an operation on behalf of an indirect binder
5688        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5689        // client identity accordingly before proceeding.
5690        Identity tlsIdentity = sCallerIdentity.get();
5691        if (tlsIdentity != null) {
5692            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5693                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5694            uid = tlsIdentity.uid;
5695            pid = tlsIdentity.pid;
5696        }
5697
5698        if (pid == MY_PID) {
5699            return PackageManager.PERMISSION_GRANTED;
5700        }
5701
5702        return ActivityManager.checkComponentPermission(permission, uid,
5703                owningUid, exported);
5704    }
5705
5706    /**
5707     * As the only public entry point for permissions checking, this method
5708     * can enforce the semantic that requesting a check on a null global
5709     * permission is automatically denied.  (Internally a null permission
5710     * string is used when calling {@link #checkComponentPermission} in cases
5711     * when only uid-based security is needed.)
5712     *
5713     * This can be called with or without the global lock held.
5714     */
5715    @Override
5716    public int checkPermission(String permission, int pid, int uid) {
5717        if (permission == null) {
5718            return PackageManager.PERMISSION_DENIED;
5719        }
5720        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5721    }
5722
5723    /**
5724     * Binder IPC calls go through the public entry point.
5725     * This can be called with or without the global lock held.
5726     */
5727    int checkCallingPermission(String permission) {
5728        return checkPermission(permission,
5729                Binder.getCallingPid(),
5730                UserHandle.getAppId(Binder.getCallingUid()));
5731    }
5732
5733    /**
5734     * This can be called with or without the global lock held.
5735     */
5736    void enforceCallingPermission(String permission, String func) {
5737        if (checkCallingPermission(permission)
5738                == PackageManager.PERMISSION_GRANTED) {
5739            return;
5740        }
5741
5742        String msg = "Permission Denial: " + func + " from pid="
5743                + Binder.getCallingPid()
5744                + ", uid=" + Binder.getCallingUid()
5745                + " requires " + permission;
5746        Slog.w(TAG, msg);
5747        throw new SecurityException(msg);
5748    }
5749
5750    /**
5751     * Determine if UID is holding permissions required to access {@link Uri} in
5752     * the given {@link ProviderInfo}. Final permission checking is always done
5753     * in {@link ContentProvider}.
5754     */
5755    private final boolean checkHoldingPermissionsLocked(
5756            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5757        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5758                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5759
5760        if (pi.applicationInfo.uid == uid) {
5761            return true;
5762        } else if (!pi.exported) {
5763            return false;
5764        }
5765
5766        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5767        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5768        try {
5769            // check if target holds top-level <provider> permissions
5770            if (!readMet && pi.readPermission != null
5771                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5772                readMet = true;
5773            }
5774            if (!writeMet && pi.writePermission != null
5775                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5776                writeMet = true;
5777            }
5778
5779            // track if unprotected read/write is allowed; any denied
5780            // <path-permission> below removes this ability
5781            boolean allowDefaultRead = pi.readPermission == null;
5782            boolean allowDefaultWrite = pi.writePermission == null;
5783
5784            // check if target holds any <path-permission> that match uri
5785            final PathPermission[] pps = pi.pathPermissions;
5786            if (pps != null) {
5787                final String path = uri.getPath();
5788                int i = pps.length;
5789                while (i > 0 && (!readMet || !writeMet)) {
5790                    i--;
5791                    PathPermission pp = pps[i];
5792                    if (pp.match(path)) {
5793                        if (!readMet) {
5794                            final String pprperm = pp.getReadPermission();
5795                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5796                                    + pprperm + " for " + pp.getPath()
5797                                    + ": match=" + pp.match(path)
5798                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5799                            if (pprperm != null) {
5800                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5801                                    readMet = true;
5802                                } else {
5803                                    allowDefaultRead = false;
5804                                }
5805                            }
5806                        }
5807                        if (!writeMet) {
5808                            final String ppwperm = pp.getWritePermission();
5809                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5810                                    + ppwperm + " for " + pp.getPath()
5811                                    + ": match=" + pp.match(path)
5812                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5813                            if (ppwperm != null) {
5814                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5815                                    writeMet = true;
5816                                } else {
5817                                    allowDefaultWrite = false;
5818                                }
5819                            }
5820                        }
5821                    }
5822                }
5823            }
5824
5825            // grant unprotected <provider> read/write, if not blocked by
5826            // <path-permission> above
5827            if (allowDefaultRead) readMet = true;
5828            if (allowDefaultWrite) writeMet = true;
5829
5830        } catch (RemoteException e) {
5831            return false;
5832        }
5833
5834        return readMet && writeMet;
5835    }
5836
5837    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5838        ProviderInfo pi = null;
5839        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5840        if (cpr != null) {
5841            pi = cpr.info;
5842        } else {
5843            try {
5844                pi = AppGlobals.getPackageManager().resolveContentProvider(
5845                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5846            } catch (RemoteException ex) {
5847            }
5848        }
5849        return pi;
5850    }
5851
5852    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5853        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5854        if (targetUris != null) {
5855            return targetUris.get(uri);
5856        } else {
5857            return null;
5858        }
5859    }
5860
5861    private UriPermission findOrCreateUriPermissionLocked(
5862            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5863        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5864        if (targetUris == null) {
5865            targetUris = Maps.newArrayMap();
5866            mGrantedUriPermissions.put(targetUid, targetUris);
5867        }
5868
5869        UriPermission perm = targetUris.get(uri);
5870        if (perm == null) {
5871            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5872            targetUris.put(uri, perm);
5873        }
5874
5875        return perm;
5876    }
5877
5878    private final boolean checkUriPermissionLocked(
5879            Uri uri, int uid, int modeFlags, int minStrength) {
5880        // Root gets to do everything.
5881        if (uid == 0) {
5882            return true;
5883        }
5884        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5885        if (perms == null) return false;
5886        UriPermission perm = perms.get(uri);
5887        if (perm == null) return false;
5888        return perm.getStrength(modeFlags) >= minStrength;
5889    }
5890
5891    @Override
5892    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5893        enforceNotIsolatedCaller("checkUriPermission");
5894
5895        // Another redirected-binder-call permissions check as in
5896        // {@link checkComponentPermission}.
5897        Identity tlsIdentity = sCallerIdentity.get();
5898        if (tlsIdentity != null) {
5899            uid = tlsIdentity.uid;
5900            pid = tlsIdentity.pid;
5901        }
5902
5903        // Our own process gets to do everything.
5904        if (pid == MY_PID) {
5905            return PackageManager.PERMISSION_GRANTED;
5906        }
5907        synchronized(this) {
5908            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5909                    ? PackageManager.PERMISSION_GRANTED
5910                    : PackageManager.PERMISSION_DENIED;
5911        }
5912    }
5913
5914    /**
5915     * Check if the targetPkg can be granted permission to access uri by
5916     * the callingUid using the given modeFlags.  Throws a security exception
5917     * if callingUid is not allowed to do this.  Returns the uid of the target
5918     * if the URI permission grant should be performed; returns -1 if it is not
5919     * needed (for example targetPkg already has permission to access the URI).
5920     * If you already know the uid of the target, you can supply it in
5921     * lastTargetUid else set that to -1.
5922     */
5923    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5924            Uri uri, int modeFlags, int lastTargetUid) {
5925        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5926        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5927                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5928        if (modeFlags == 0) {
5929            return -1;
5930        }
5931
5932        if (targetPkg != null) {
5933            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5934                    "Checking grant " + targetPkg + " permission to " + uri);
5935        }
5936
5937        final IPackageManager pm = AppGlobals.getPackageManager();
5938
5939        // If this is not a content: uri, we can't do anything with it.
5940        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5941            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5942                    "Can't grant URI permission for non-content URI: " + uri);
5943            return -1;
5944        }
5945
5946        final String authority = uri.getAuthority();
5947        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5948        if (pi == null) {
5949            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5950            return -1;
5951        }
5952
5953        int targetUid = lastTargetUid;
5954        if (targetUid < 0 && targetPkg != null) {
5955            try {
5956                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5957                if (targetUid < 0) {
5958                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5959                            "Can't grant URI permission no uid for: " + targetPkg);
5960                    return -1;
5961                }
5962            } catch (RemoteException ex) {
5963                return -1;
5964            }
5965        }
5966
5967        if (targetUid >= 0) {
5968            // First...  does the target actually need this permission?
5969            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5970                // No need to grant the target this permission.
5971                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5972                        "Target " + targetPkg + " already has full permission to " + uri);
5973                return -1;
5974            }
5975        } else {
5976            // First...  there is no target package, so can anyone access it?
5977            boolean allowed = pi.exported;
5978            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5979                if (pi.readPermission != null) {
5980                    allowed = false;
5981                }
5982            }
5983            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5984                if (pi.writePermission != null) {
5985                    allowed = false;
5986                }
5987            }
5988            if (allowed) {
5989                return -1;
5990            }
5991        }
5992
5993        // Second...  is the provider allowing granting of URI permissions?
5994        if (!pi.grantUriPermissions) {
5995            throw new SecurityException("Provider " + pi.packageName
5996                    + "/" + pi.name
5997                    + " does not allow granting of Uri permissions (uri "
5998                    + uri + ")");
5999        }
6000        if (pi.uriPermissionPatterns != null) {
6001            final int N = pi.uriPermissionPatterns.length;
6002            boolean allowed = false;
6003            for (int i=0; i<N; i++) {
6004                if (pi.uriPermissionPatterns[i] != null
6005                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6006                    allowed = true;
6007                    break;
6008                }
6009            }
6010            if (!allowed) {
6011                throw new SecurityException("Provider " + pi.packageName
6012                        + "/" + pi.name
6013                        + " does not allow granting of permission to path of Uri "
6014                        + uri);
6015            }
6016        }
6017
6018        // Third...  does the caller itself have permission to access
6019        // this uri?
6020        if (callingUid != Process.myUid()) {
6021            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6022                // Require they hold a strong enough Uri permission
6023                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6024                        : UriPermission.STRENGTH_OWNED;
6025                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6026                    throw new SecurityException("Uid " + callingUid
6027                            + " does not have permission to uri " + uri);
6028                }
6029            }
6030        }
6031
6032        return targetUid;
6033    }
6034
6035    @Override
6036    public int checkGrantUriPermission(int callingUid, String targetPkg,
6037            Uri uri, int modeFlags) {
6038        enforceNotIsolatedCaller("checkGrantUriPermission");
6039        synchronized(this) {
6040            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6041        }
6042    }
6043
6044    void grantUriPermissionUncheckedLocked(
6045            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6046        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6047        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6048                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6049        if (modeFlags == 0) {
6050            return;
6051        }
6052
6053        // So here we are: the caller has the assumed permission
6054        // to the uri, and the target doesn't.  Let's now give this to
6055        // the target.
6056
6057        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6058                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6059
6060        final String authority = uri.getAuthority();
6061        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6062        if (pi == null) {
6063            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6064            return;
6065        }
6066
6067        final UriPermission perm = findOrCreateUriPermissionLocked(
6068                pi.packageName, targetPkg, targetUid, uri);
6069        perm.grantModes(modeFlags, persistable, owner);
6070    }
6071
6072    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6073            int modeFlags, UriPermissionOwner owner) {
6074        if (targetPkg == null) {
6075            throw new NullPointerException("targetPkg");
6076        }
6077
6078        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6079        if (targetUid < 0) {
6080            return;
6081        }
6082
6083        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6084    }
6085
6086    static class NeededUriGrants extends ArrayList<Uri> {
6087        final String targetPkg;
6088        final int targetUid;
6089        final int flags;
6090
6091        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6092            this.targetPkg = targetPkg;
6093            this.targetUid = targetUid;
6094            this.flags = flags;
6095        }
6096    }
6097
6098    /**
6099     * Like checkGrantUriPermissionLocked, but takes an Intent.
6100     */
6101    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6102            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6103        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6104                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6105                + " clip=" + (intent != null ? intent.getClipData() : null)
6106                + " from " + intent + "; flags=0x"
6107                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6108
6109        if (targetPkg == null) {
6110            throw new NullPointerException("targetPkg");
6111        }
6112
6113        if (intent == null) {
6114            return null;
6115        }
6116        Uri data = intent.getData();
6117        ClipData clip = intent.getClipData();
6118        if (data == null && clip == null) {
6119            return null;
6120        }
6121
6122        if (data != null) {
6123            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6124                mode, needed != null ? needed.targetUid : -1);
6125            if (targetUid > 0) {
6126                if (needed == null) {
6127                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6128                }
6129                needed.add(data);
6130            }
6131        }
6132        if (clip != null) {
6133            for (int i=0; i<clip.getItemCount(); i++) {
6134                Uri uri = clip.getItemAt(i).getUri();
6135                if (uri != null) {
6136                    int targetUid = -1;
6137                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6138                            mode, needed != null ? needed.targetUid : -1);
6139                    if (targetUid > 0) {
6140                        if (needed == null) {
6141                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6142                        }
6143                        needed.add(uri);
6144                    }
6145                } else {
6146                    Intent clipIntent = clip.getItemAt(i).getIntent();
6147                    if (clipIntent != null) {
6148                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6149                                callingUid, targetPkg, clipIntent, mode, needed);
6150                        if (newNeeded != null) {
6151                            needed = newNeeded;
6152                        }
6153                    }
6154                }
6155            }
6156        }
6157
6158        return needed;
6159    }
6160
6161    /**
6162     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6163     */
6164    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6165            UriPermissionOwner owner) {
6166        if (needed != null) {
6167            for (int i=0; i<needed.size(); i++) {
6168                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6169                        needed.get(i), needed.flags, owner);
6170            }
6171        }
6172    }
6173
6174    void grantUriPermissionFromIntentLocked(int callingUid,
6175            String targetPkg, Intent intent, UriPermissionOwner owner) {
6176        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6177                intent, intent != null ? intent.getFlags() : 0, null);
6178        if (needed == null) {
6179            return;
6180        }
6181
6182        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6183    }
6184
6185    @Override
6186    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6187            Uri uri, int modeFlags) {
6188        enforceNotIsolatedCaller("grantUriPermission");
6189        synchronized(this) {
6190            final ProcessRecord r = getRecordForAppLocked(caller);
6191            if (r == null) {
6192                throw new SecurityException("Unable to find app for caller "
6193                        + caller
6194                        + " when granting permission to uri " + uri);
6195            }
6196            if (targetPkg == null) {
6197                throw new IllegalArgumentException("null target");
6198            }
6199            if (uri == null) {
6200                throw new IllegalArgumentException("null uri");
6201            }
6202
6203            // Persistable only supported through Intents
6204            Preconditions.checkFlagsArgument(modeFlags,
6205                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6206
6207            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6208                    null);
6209        }
6210    }
6211
6212    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6213        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6214                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6215            ArrayMap<Uri, UriPermission> perms
6216                    = mGrantedUriPermissions.get(perm.targetUid);
6217            if (perms != null) {
6218                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6219                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6220                perms.remove(perm.uri);
6221                if (perms.size() == 0) {
6222                    mGrantedUriPermissions.remove(perm.targetUid);
6223                }
6224            }
6225        }
6226    }
6227
6228    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6229        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6230
6231        final IPackageManager pm = AppGlobals.getPackageManager();
6232        final String authority = uri.getAuthority();
6233        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6234        if (pi == null) {
6235            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6236            return;
6237        }
6238
6239        // Does the caller have this permission on the URI?
6240        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6241            // Right now, if you are not the original owner of the permission,
6242            // you are not allowed to revoke it.
6243            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6244                throw new SecurityException("Uid " + callingUid
6245                        + " does not have permission to uri " + uri);
6246            //}
6247        }
6248
6249        boolean persistChanged = false;
6250
6251        // Go through all of the permissions and remove any that match.
6252        final List<String> SEGMENTS = uri.getPathSegments();
6253        if (SEGMENTS != null) {
6254            final int NS = SEGMENTS.size();
6255            int N = mGrantedUriPermissions.size();
6256            for (int i=0; i<N; i++) {
6257                ArrayMap<Uri, UriPermission> perms
6258                        = mGrantedUriPermissions.valueAt(i);
6259                Iterator<UriPermission> it = perms.values().iterator();
6260            toploop:
6261                while (it.hasNext()) {
6262                    UriPermission perm = it.next();
6263                    Uri targetUri = perm.uri;
6264                    if (!authority.equals(targetUri.getAuthority())) {
6265                        continue;
6266                    }
6267                    List<String> targetSegments = targetUri.getPathSegments();
6268                    if (targetSegments == null) {
6269                        continue;
6270                    }
6271                    if (targetSegments.size() < NS) {
6272                        continue;
6273                    }
6274                    for (int j=0; j<NS; j++) {
6275                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6276                            continue toploop;
6277                        }
6278                    }
6279                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6280                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6281                    persistChanged |= perm.clearModes(modeFlags, true);
6282                    if (perm.modeFlags == 0) {
6283                        it.remove();
6284                    }
6285                }
6286                if (perms.size() == 0) {
6287                    mGrantedUriPermissions.remove(
6288                            mGrantedUriPermissions.keyAt(i));
6289                    N--;
6290                    i--;
6291                }
6292            }
6293        }
6294
6295        if (persistChanged) {
6296            schedulePersistUriGrants();
6297        }
6298    }
6299
6300    @Override
6301    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6302            int modeFlags) {
6303        enforceNotIsolatedCaller("revokeUriPermission");
6304        synchronized(this) {
6305            final ProcessRecord r = getRecordForAppLocked(caller);
6306            if (r == null) {
6307                throw new SecurityException("Unable to find app for caller "
6308                        + caller
6309                        + " when revoking permission to uri " + uri);
6310            }
6311            if (uri == null) {
6312                Slog.w(TAG, "revokeUriPermission: null uri");
6313                return;
6314            }
6315
6316            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6317                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6318            if (modeFlags == 0) {
6319                return;
6320            }
6321
6322            final IPackageManager pm = AppGlobals.getPackageManager();
6323            final String authority = uri.getAuthority();
6324            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6325            if (pi == null) {
6326                Slog.w(TAG, "No content provider found for permission revoke: "
6327                        + uri.toSafeString());
6328                return;
6329            }
6330
6331            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6332        }
6333    }
6334
6335    /**
6336     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6337     * given package.
6338     *
6339     * @param packageName Package name to match, or {@code null} to apply to all
6340     *            packages.
6341     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6342     *            to all users.
6343     * @param persistable If persistable grants should be removed.
6344     */
6345    private void removeUriPermissionsForPackageLocked(
6346            String packageName, int userHandle, boolean persistable) {
6347        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6348            throw new IllegalArgumentException("Must narrow by either package or user");
6349        }
6350
6351        boolean persistChanged = false;
6352
6353        final int size = mGrantedUriPermissions.size();
6354        for (int i = 0; i < size; i++) {
6355            // Only inspect grants matching user
6356            if (userHandle == UserHandle.USER_ALL
6357                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6358                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6359                        .values().iterator();
6360                while (it.hasNext()) {
6361                    final UriPermission perm = it.next();
6362
6363                    // Only inspect grants matching package
6364                    if (packageName == null || perm.sourcePkg.equals(packageName)
6365                            || perm.targetPkg.equals(packageName)) {
6366                        persistChanged |= perm.clearModes(~0, persistable);
6367
6368                        // Only remove when no modes remain; any persisted grants
6369                        // will keep this alive.
6370                        if (perm.modeFlags == 0) {
6371                            it.remove();
6372                        }
6373                    }
6374                }
6375            }
6376        }
6377
6378        if (persistChanged) {
6379            schedulePersistUriGrants();
6380        }
6381    }
6382
6383    @Override
6384    public IBinder newUriPermissionOwner(String name) {
6385        enforceNotIsolatedCaller("newUriPermissionOwner");
6386        synchronized(this) {
6387            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6388            return owner.getExternalTokenLocked();
6389        }
6390    }
6391
6392    @Override
6393    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6394            Uri uri, int modeFlags) {
6395        synchronized(this) {
6396            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6397            if (owner == null) {
6398                throw new IllegalArgumentException("Unknown owner: " + token);
6399            }
6400            if (fromUid != Binder.getCallingUid()) {
6401                if (Binder.getCallingUid() != Process.myUid()) {
6402                    // Only system code can grant URI permissions on behalf
6403                    // of other users.
6404                    throw new SecurityException("nice try");
6405                }
6406            }
6407            if (targetPkg == null) {
6408                throw new IllegalArgumentException("null target");
6409            }
6410            if (uri == null) {
6411                throw new IllegalArgumentException("null uri");
6412            }
6413
6414            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6415        }
6416    }
6417
6418    @Override
6419    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6420        synchronized(this) {
6421            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6422            if (owner == null) {
6423                throw new IllegalArgumentException("Unknown owner: " + token);
6424            }
6425
6426            if (uri == null) {
6427                owner.removeUriPermissionsLocked(mode);
6428            } else {
6429                owner.removeUriPermissionLocked(uri, mode);
6430            }
6431        }
6432    }
6433
6434    private void schedulePersistUriGrants() {
6435        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6436            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6437                    10 * DateUtils.SECOND_IN_MILLIS);
6438        }
6439    }
6440
6441    private void writeGrantedUriPermissions() {
6442        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6443
6444        // Snapshot permissions so we can persist without lock
6445        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6446        synchronized (this) {
6447            final int size = mGrantedUriPermissions.size();
6448            for (int i = 0 ; i < size; i++) {
6449                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6450                    if (perm.persistedModeFlags != 0) {
6451                        persist.add(perm.snapshot());
6452                    }
6453                }
6454            }
6455        }
6456
6457        FileOutputStream fos = null;
6458        try {
6459            fos = mGrantFile.startWrite();
6460
6461            XmlSerializer out = new FastXmlSerializer();
6462            out.setOutput(fos, "utf-8");
6463            out.startDocument(null, true);
6464            out.startTag(null, TAG_URI_GRANTS);
6465            for (UriPermission.Snapshot perm : persist) {
6466                out.startTag(null, TAG_URI_GRANT);
6467                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6468                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6469                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6470                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6471                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6472                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6473                out.endTag(null, TAG_URI_GRANT);
6474            }
6475            out.endTag(null, TAG_URI_GRANTS);
6476            out.endDocument();
6477
6478            mGrantFile.finishWrite(fos);
6479        } catch (IOException e) {
6480            if (fos != null) {
6481                mGrantFile.failWrite(fos);
6482            }
6483        }
6484    }
6485
6486    private void readGrantedUriPermissionsLocked() {
6487        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6488
6489        final long now = System.currentTimeMillis();
6490
6491        FileInputStream fis = null;
6492        try {
6493            fis = mGrantFile.openRead();
6494            final XmlPullParser in = Xml.newPullParser();
6495            in.setInput(fis, null);
6496
6497            int type;
6498            while ((type = in.next()) != END_DOCUMENT) {
6499                final String tag = in.getName();
6500                if (type == START_TAG) {
6501                    if (TAG_URI_GRANT.equals(tag)) {
6502                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6503                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6504                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6505                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6506                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6507                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6508
6509                        // Sanity check that provider still belongs to source package
6510                        final ProviderInfo pi = getProviderInfoLocked(
6511                                uri.getAuthority(), userHandle);
6512                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6513                            int targetUid = -1;
6514                            try {
6515                                targetUid = AppGlobals.getPackageManager()
6516                                        .getPackageUid(targetPkg, userHandle);
6517                            } catch (RemoteException e) {
6518                            }
6519                            if (targetUid != -1) {
6520                                final UriPermission perm = findOrCreateUriPermissionLocked(
6521                                        sourcePkg, targetPkg, targetUid, uri);
6522                                perm.initPersistedModes(modeFlags, createdTime);
6523                            }
6524                        } else {
6525                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6526                                    + " but instead found " + pi);
6527                        }
6528                    }
6529                }
6530            }
6531        } catch (FileNotFoundException e) {
6532            // Missing grants is okay
6533        } catch (IOException e) {
6534            Log.wtf(TAG, "Failed reading Uri grants", e);
6535        } catch (XmlPullParserException e) {
6536            Log.wtf(TAG, "Failed reading Uri grants", e);
6537        } finally {
6538            IoUtils.closeQuietly(fis);
6539        }
6540    }
6541
6542    @Override
6543    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6544        enforceNotIsolatedCaller("takePersistableUriPermission");
6545
6546        Preconditions.checkFlagsArgument(modeFlags,
6547                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6548
6549        synchronized (this) {
6550            final int callingUid = Binder.getCallingUid();
6551            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6552            if (perm == null) {
6553                throw new SecurityException("No permission grant found for UID " + callingUid
6554                        + " and Uri " + uri.toSafeString());
6555            }
6556
6557            boolean persistChanged = perm.takePersistableModes(modeFlags);
6558            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6559
6560            if (persistChanged) {
6561                schedulePersistUriGrants();
6562            }
6563        }
6564    }
6565
6566    @Override
6567    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6568        enforceNotIsolatedCaller("releasePersistableUriPermission");
6569
6570        Preconditions.checkFlagsArgument(modeFlags,
6571                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6572
6573        synchronized (this) {
6574            final int callingUid = Binder.getCallingUid();
6575
6576            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6577            if (perm == null) {
6578                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6579                        + uri.toSafeString());
6580                return;
6581            }
6582
6583            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6584            removeUriPermissionIfNeededLocked(perm);
6585            if (persistChanged) {
6586                schedulePersistUriGrants();
6587            }
6588        }
6589    }
6590
6591    /**
6592     * Prune any older {@link UriPermission} for the given UID until outstanding
6593     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6594     *
6595     * @return if any mutations occured that require persisting.
6596     */
6597    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6598        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6599        if (perms == null) return false;
6600        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6601
6602        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6603        for (UriPermission perm : perms.values()) {
6604            if (perm.persistedModeFlags != 0) {
6605                persisted.add(perm);
6606            }
6607        }
6608
6609        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6610        if (trimCount <= 0) return false;
6611
6612        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6613        for (int i = 0; i < trimCount; i++) {
6614            final UriPermission perm = persisted.get(i);
6615
6616            if (DEBUG_URI_PERMISSION) {
6617                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6618            }
6619
6620            perm.releasePersistableModes(~0);
6621            removeUriPermissionIfNeededLocked(perm);
6622        }
6623
6624        return true;
6625    }
6626
6627    @Override
6628    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6629            String packageName, boolean incoming) {
6630        enforceNotIsolatedCaller("getPersistedUriPermissions");
6631        Preconditions.checkNotNull(packageName, "packageName");
6632
6633        final int callingUid = Binder.getCallingUid();
6634        final IPackageManager pm = AppGlobals.getPackageManager();
6635        try {
6636            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6637            if (packageUid != callingUid) {
6638                throw new SecurityException(
6639                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6640            }
6641        } catch (RemoteException e) {
6642            throw new SecurityException("Failed to verify package name ownership");
6643        }
6644
6645        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6646        synchronized (this) {
6647            if (incoming) {
6648                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6649                if (perms == null) {
6650                    Slog.w(TAG, "No permission grants found for " + packageName);
6651                } else {
6652                    final int size = perms.size();
6653                    for (int i = 0; i < size; i++) {
6654                        final UriPermission perm = perms.valueAt(i);
6655                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6656                            result.add(perm.buildPersistedPublicApiObject());
6657                        }
6658                    }
6659                }
6660            } else {
6661                final int size = mGrantedUriPermissions.size();
6662                for (int i = 0; i < size; i++) {
6663                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6664                    final int permsSize = perms.size();
6665                    for (int j = 0; j < permsSize; j++) {
6666                        final UriPermission perm = perms.valueAt(j);
6667                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6668                            result.add(perm.buildPersistedPublicApiObject());
6669                        }
6670                    }
6671                }
6672            }
6673        }
6674        return new ParceledListSlice<android.content.UriPermission>(result);
6675    }
6676
6677    @Override
6678    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6679        synchronized (this) {
6680            ProcessRecord app =
6681                who != null ? getRecordForAppLocked(who) : null;
6682            if (app == null) return;
6683
6684            Message msg = Message.obtain();
6685            msg.what = WAIT_FOR_DEBUGGER_MSG;
6686            msg.obj = app;
6687            msg.arg1 = waiting ? 1 : 0;
6688            mHandler.sendMessage(msg);
6689        }
6690    }
6691
6692    @Override
6693    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6694        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6695        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6696        outInfo.availMem = Process.getFreeMemory();
6697        outInfo.totalMem = Process.getTotalMemory();
6698        outInfo.threshold = homeAppMem;
6699        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6700        outInfo.hiddenAppThreshold = cachedAppMem;
6701        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6702                ProcessList.SERVICE_ADJ);
6703        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6704                ProcessList.VISIBLE_APP_ADJ);
6705        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6706                ProcessList.FOREGROUND_APP_ADJ);
6707    }
6708
6709    // =========================================================
6710    // TASK MANAGEMENT
6711    // =========================================================
6712
6713    @Override
6714    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6715                         IThumbnailReceiver receiver) {
6716        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6717
6718        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6719        ActivityRecord topRecord = null;
6720
6721        synchronized(this) {
6722            if (localLOGV) Slog.v(
6723                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6724                + ", receiver=" + receiver);
6725
6726            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6727                    != PackageManager.PERMISSION_GRANTED) {
6728                if (receiver != null) {
6729                    // If the caller wants to wait for pending thumbnails,
6730                    // it ain't gonna get them.
6731                    try {
6732                        receiver.finished();
6733                    } catch (RemoteException ex) {
6734                    }
6735                }
6736                String msg = "Permission Denial: getTasks() from pid="
6737                        + Binder.getCallingPid()
6738                        + ", uid=" + Binder.getCallingUid()
6739                        + " requires " + android.Manifest.permission.GET_TASKS;
6740                Slog.w(TAG, msg);
6741                throw new SecurityException(msg);
6742            }
6743
6744            // TODO: Improve with MRU list from all ActivityStacks.
6745            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6746
6747            if (!pending.pendingRecords.isEmpty()) {
6748                mPendingThumbnails.add(pending);
6749            }
6750        }
6751
6752        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6753
6754        if (topRecord != null) {
6755            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6756            try {
6757                IApplicationThread topThumbnail = topRecord.app.thread;
6758                topThumbnail.requestThumbnail(topRecord.appToken);
6759            } catch (Exception e) {
6760                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6761                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6762            }
6763        }
6764
6765        if (pending == null && receiver != null) {
6766            // In this case all thumbnails were available and the client
6767            // is being asked to be told when the remaining ones come in...
6768            // which is unusually, since the top-most currently running
6769            // activity should never have a canned thumbnail!  Oh well.
6770            try {
6771                receiver.finished();
6772            } catch (RemoteException ex) {
6773            }
6774        }
6775
6776        return list;
6777    }
6778
6779    TaskRecord getMostRecentTask() {
6780        return mRecentTasks.get(0);
6781    }
6782
6783    @Override
6784    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6785            int flags, int userId) {
6786        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6787                false, true, "getRecentTasks", null);
6788
6789        synchronized (this) {
6790            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6791                    "getRecentTasks()");
6792            final boolean detailed = checkCallingPermission(
6793                    android.Manifest.permission.GET_DETAILED_TASKS)
6794                    == PackageManager.PERMISSION_GRANTED;
6795
6796            IPackageManager pm = AppGlobals.getPackageManager();
6797
6798            final int N = mRecentTasks.size();
6799            ArrayList<ActivityManager.RecentTaskInfo> res
6800                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6801                            maxNum < N ? maxNum : N);
6802            for (int i=0; i<N && maxNum > 0; i++) {
6803                TaskRecord tr = mRecentTasks.get(i);
6804                // Only add calling user's recent tasks
6805                if (tr.userId != userId) continue;
6806                // Return the entry if desired by the caller.  We always return
6807                // the first entry, because callers always expect this to be the
6808                // foreground app.  We may filter others if the caller has
6809                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6810                // we should exclude the entry.
6811
6812                if (i == 0
6813                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6814                        || (tr.intent == null)
6815                        || ((tr.intent.getFlags()
6816                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6817                    ActivityManager.RecentTaskInfo rti
6818                            = new ActivityManager.RecentTaskInfo();
6819                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6820                    rti.persistentId = tr.taskId;
6821                    rti.baseIntent = new Intent(
6822                            tr.intent != null ? tr.intent : tr.affinityIntent);
6823                    if (!detailed) {
6824                        rti.baseIntent.replaceExtras((Bundle)null);
6825                    }
6826                    rti.origActivity = tr.origActivity;
6827                    rti.description = tr.lastDescription;
6828                    rti.stackId = tr.stack.mStackId;
6829
6830                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6831                        // Check whether this activity is currently available.
6832                        try {
6833                            if (rti.origActivity != null) {
6834                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6835                                        == null) {
6836                                    continue;
6837                                }
6838                            } else if (rti.baseIntent != null) {
6839                                if (pm.queryIntentActivities(rti.baseIntent,
6840                                        null, 0, userId) == null) {
6841                                    continue;
6842                                }
6843                            }
6844                        } catch (RemoteException e) {
6845                            // Will never happen.
6846                        }
6847                    }
6848
6849                    res.add(rti);
6850                    maxNum--;
6851                }
6852            }
6853            return res;
6854        }
6855    }
6856
6857    private TaskRecord recentTaskForIdLocked(int id) {
6858        final int N = mRecentTasks.size();
6859            for (int i=0; i<N; i++) {
6860                TaskRecord tr = mRecentTasks.get(i);
6861                if (tr.taskId == id) {
6862                    return tr;
6863                }
6864            }
6865            return null;
6866    }
6867
6868    @Override
6869    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6870        synchronized (this) {
6871            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6872                    "getTaskThumbnails()");
6873            TaskRecord tr = recentTaskForIdLocked(id);
6874            if (tr != null) {
6875                return tr.getTaskThumbnailsLocked();
6876            }
6877        }
6878        return null;
6879    }
6880
6881    @Override
6882    public Bitmap getTaskTopThumbnail(int id) {
6883        synchronized (this) {
6884            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6885                    "getTaskTopThumbnail()");
6886            TaskRecord tr = recentTaskForIdLocked(id);
6887            if (tr != null) {
6888                return tr.getTaskTopThumbnailLocked();
6889            }
6890        }
6891        return null;
6892    }
6893
6894    @Override
6895    public boolean removeSubTask(int taskId, int subTaskIndex) {
6896        synchronized (this) {
6897            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6898                    "removeSubTask()");
6899            long ident = Binder.clearCallingIdentity();
6900            try {
6901                TaskRecord tr = recentTaskForIdLocked(taskId);
6902                if (tr != null) {
6903                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6904                }
6905                return false;
6906            } finally {
6907                Binder.restoreCallingIdentity(ident);
6908            }
6909        }
6910    }
6911
6912    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6913        if (!pr.killedByAm) {
6914            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6915            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6916                    pr.processName, pr.setAdj, reason);
6917            pr.killedByAm = true;
6918            Process.killProcessQuiet(pr.pid);
6919        }
6920    }
6921
6922    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6923        tr.disposeThumbnail();
6924        mRecentTasks.remove(tr);
6925        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6926        Intent baseIntent = new Intent(
6927                tr.intent != null ? tr.intent : tr.affinityIntent);
6928        ComponentName component = baseIntent.getComponent();
6929        if (component == null) {
6930            Slog.w(TAG, "Now component for base intent of task: " + tr);
6931            return;
6932        }
6933
6934        // Find any running services associated with this app.
6935        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6936
6937        if (killProcesses) {
6938            // Find any running processes associated with this app.
6939            final String pkg = component.getPackageName();
6940            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6941            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6942            for (int i=0; i<pmap.size(); i++) {
6943                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6944                for (int j=0; j<uids.size(); j++) {
6945                    ProcessRecord proc = uids.valueAt(j);
6946                    if (proc.userId != tr.userId) {
6947                        continue;
6948                    }
6949                    if (!proc.pkgList.containsKey(pkg)) {
6950                        continue;
6951                    }
6952                    procs.add(proc);
6953                }
6954            }
6955
6956            // Kill the running processes.
6957            for (int i=0; i<procs.size(); i++) {
6958                ProcessRecord pr = procs.get(i);
6959                if (pr == mHomeProcess) {
6960                    // Don't kill the home process along with tasks from the same package.
6961                    continue;
6962                }
6963                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6964                    killUnneededProcessLocked(pr, "remove task");
6965                } else {
6966                    pr.waitingToKill = "remove task";
6967                }
6968            }
6969        }
6970    }
6971
6972    @Override
6973    public boolean removeTask(int taskId, int flags) {
6974        synchronized (this) {
6975            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6976                    "removeTask()");
6977            long ident = Binder.clearCallingIdentity();
6978            try {
6979                TaskRecord tr = recentTaskForIdLocked(taskId);
6980                if (tr != null) {
6981                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
6982                    if (r != null) {
6983                        cleanUpRemovedTaskLocked(tr, flags);
6984                        return true;
6985                    }
6986                    if (tr.mActivities.size() == 0) {
6987                        // Caller is just removing a recent task that is
6988                        // not actively running.  That is easy!
6989                        cleanUpRemovedTaskLocked(tr, flags);
6990                        return true;
6991                    }
6992                    Slog.w(TAG, "removeTask: task " + taskId
6993                            + " does not have activities to remove, "
6994                            + " but numActivities=" + tr.numActivities
6995                            + ": " + tr);
6996                }
6997            } finally {
6998                Binder.restoreCallingIdentity(ident);
6999            }
7000        }
7001        return false;
7002    }
7003
7004    /**
7005     * TODO: Add mController hook
7006     */
7007    @Override
7008    public void moveTaskToFront(int task, int flags, Bundle options) {
7009        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7010                "moveTaskToFront()");
7011
7012        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
7013        synchronized(this) {
7014            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7015                    Binder.getCallingUid(), "Task to front")) {
7016                ActivityOptions.abort(options);
7017                return;
7018            }
7019            final long origId = Binder.clearCallingIdentity();
7020            try {
7021                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7022            } finally {
7023                Binder.restoreCallingIdentity(origId);
7024            }
7025            ActivityOptions.abort(options);
7026        }
7027    }
7028
7029    @Override
7030    public void moveTaskToBack(int taskId) {
7031        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7032                "moveTaskToBack()");
7033
7034        synchronized(this) {
7035            TaskRecord tr = recentTaskForIdLocked(taskId);
7036            if (tr != null) {
7037                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7038                ActivityStack stack = tr.stack;
7039                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7040                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7041                            Binder.getCallingUid(), "Task to back")) {
7042                        return;
7043                    }
7044                }
7045                final long origId = Binder.clearCallingIdentity();
7046                try {
7047                    stack.moveTaskToBackLocked(taskId, null);
7048                } finally {
7049                    Binder.restoreCallingIdentity(origId);
7050                }
7051            }
7052        }
7053    }
7054
7055    /**
7056     * Moves an activity, and all of the other activities within the same task, to the bottom
7057     * of the history stack.  The activity's order within the task is unchanged.
7058     *
7059     * @param token A reference to the activity we wish to move
7060     * @param nonRoot If false then this only works if the activity is the root
7061     *                of a task; if true it will work for any activity in a task.
7062     * @return Returns true if the move completed, false if not.
7063     */
7064    @Override
7065    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7066        enforceNotIsolatedCaller("moveActivityTaskToBack");
7067        synchronized(this) {
7068            final long origId = Binder.clearCallingIdentity();
7069            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7070            if (taskId >= 0) {
7071                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7072            }
7073            Binder.restoreCallingIdentity(origId);
7074        }
7075        return false;
7076    }
7077
7078    @Override
7079    public void moveTaskBackwards(int task) {
7080        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7081                "moveTaskBackwards()");
7082
7083        synchronized(this) {
7084            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7085                    Binder.getCallingUid(), "Task backwards")) {
7086                return;
7087            }
7088            final long origId = Binder.clearCallingIdentity();
7089            moveTaskBackwardsLocked(task);
7090            Binder.restoreCallingIdentity(origId);
7091        }
7092    }
7093
7094    private final void moveTaskBackwardsLocked(int task) {
7095        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7096    }
7097
7098    @Override
7099    public IBinder getHomeActivityToken() throws RemoteException {
7100        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7101                "getHomeActivityToken()");
7102        synchronized (this) {
7103            return mStackSupervisor.getHomeActivityToken();
7104        }
7105    }
7106
7107    @Override
7108    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7109            IActivityContainerCallback callback) throws RemoteException {
7110        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7111                "createActivityContainer()");
7112        synchronized (this) {
7113            if (parentActivityToken == null) {
7114                throw new IllegalArgumentException("parent token must not be null");
7115            }
7116            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7117            if (r == null) {
7118                return null;
7119            }
7120            return mStackSupervisor.createActivityContainer(r, callback);
7121        }
7122    }
7123
7124    @Override
7125    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7126            throws RemoteException {
7127        synchronized (this) {
7128            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7129            if (stack != null) {
7130                return stack.mActivityContainer;
7131            }
7132            return null;
7133        }
7134    }
7135
7136    @Override
7137    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7138        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7139                "moveTaskToStack()");
7140        if (stackId == HOME_STACK_ID) {
7141            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7142                    new RuntimeException("here").fillInStackTrace());
7143        }
7144        synchronized (this) {
7145            long ident = Binder.clearCallingIdentity();
7146            try {
7147                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7148                        + stackId + " toTop=" + toTop);
7149                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7150            } finally {
7151                Binder.restoreCallingIdentity(ident);
7152            }
7153        }
7154    }
7155
7156    @Override
7157    public void resizeStack(int stackBoxId, Rect bounds) {
7158        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7159                "resizeStackBox()");
7160        long ident = Binder.clearCallingIdentity();
7161        try {
7162            mWindowManager.resizeStack(stackBoxId, bounds);
7163        } finally {
7164            Binder.restoreCallingIdentity(ident);
7165        }
7166    }
7167
7168    @Override
7169    public List<StackInfo> getAllStackInfos() {
7170        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7171                "getAllStackInfos()");
7172        long ident = Binder.clearCallingIdentity();
7173        try {
7174            synchronized (this) {
7175                return mStackSupervisor.getAllStackInfosLocked();
7176            }
7177        } finally {
7178            Binder.restoreCallingIdentity(ident);
7179        }
7180    }
7181
7182    @Override
7183    public StackInfo getStackInfo(int stackId) {
7184        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7185                "getStackInfo()");
7186        long ident = Binder.clearCallingIdentity();
7187        try {
7188            synchronized (this) {
7189                return mStackSupervisor.getStackInfoLocked(stackId);
7190            }
7191        } finally {
7192            Binder.restoreCallingIdentity(ident);
7193        }
7194    }
7195
7196    @Override
7197    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7198        synchronized(this) {
7199            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7200        }
7201    }
7202
7203    // =========================================================
7204    // THUMBNAILS
7205    // =========================================================
7206
7207    public void reportThumbnail(IBinder token,
7208            Bitmap thumbnail, CharSequence description) {
7209        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7210        final long origId = Binder.clearCallingIdentity();
7211        sendPendingThumbnail(null, token, thumbnail, description, true);
7212        Binder.restoreCallingIdentity(origId);
7213    }
7214
7215    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7216            Bitmap thumbnail, CharSequence description, boolean always) {
7217        TaskRecord task;
7218        ArrayList<PendingThumbnailsRecord> receivers = null;
7219
7220        //System.out.println("Send pending thumbnail: " + r);
7221
7222        synchronized(this) {
7223            if (r == null) {
7224                r = ActivityRecord.isInStackLocked(token);
7225                if (r == null) {
7226                    return;
7227                }
7228            }
7229            if (thumbnail == null && r.thumbHolder != null) {
7230                thumbnail = r.thumbHolder.lastThumbnail;
7231                description = r.thumbHolder.lastDescription;
7232            }
7233            if (thumbnail == null && !always) {
7234                // If there is no thumbnail, and this entry is not actually
7235                // going away, then abort for now and pick up the next
7236                // thumbnail we get.
7237                return;
7238            }
7239            task = r.task;
7240
7241            int N = mPendingThumbnails.size();
7242            int i=0;
7243            while (i<N) {
7244                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7245                //System.out.println("Looking in " + pr.pendingRecords);
7246                if (pr.pendingRecords.remove(r)) {
7247                    if (receivers == null) {
7248                        receivers = new ArrayList<PendingThumbnailsRecord>();
7249                    }
7250                    receivers.add(pr);
7251                    if (pr.pendingRecords.size() == 0) {
7252                        pr.finished = true;
7253                        mPendingThumbnails.remove(i);
7254                        N--;
7255                        continue;
7256                    }
7257                }
7258                i++;
7259            }
7260        }
7261
7262        if (receivers != null) {
7263            final int N = receivers.size();
7264            for (int i=0; i<N; i++) {
7265                try {
7266                    PendingThumbnailsRecord pr = receivers.get(i);
7267                    pr.receiver.newThumbnail(
7268                        task != null ? task.taskId : -1, thumbnail, description);
7269                    if (pr.finished) {
7270                        pr.receiver.finished();
7271                    }
7272                } catch (Exception e) {
7273                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7274                }
7275            }
7276        }
7277    }
7278
7279    // =========================================================
7280    // CONTENT PROVIDERS
7281    // =========================================================
7282
7283    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7284        List<ProviderInfo> providers = null;
7285        try {
7286            providers = AppGlobals.getPackageManager().
7287                queryContentProviders(app.processName, app.uid,
7288                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7289        } catch (RemoteException ex) {
7290        }
7291        if (DEBUG_MU)
7292            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7293        int userId = app.userId;
7294        if (providers != null) {
7295            int N = providers.size();
7296            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7297            for (int i=0; i<N; i++) {
7298                ProviderInfo cpi =
7299                    (ProviderInfo)providers.get(i);
7300                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7301                        cpi.name, cpi.flags);
7302                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7303                    // This is a singleton provider, but a user besides the
7304                    // default user is asking to initialize a process it runs
7305                    // in...  well, no, it doesn't actually run in this process,
7306                    // it runs in the process of the default user.  Get rid of it.
7307                    providers.remove(i);
7308                    N--;
7309                    i--;
7310                    continue;
7311                }
7312
7313                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7314                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7315                if (cpr == null) {
7316                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7317                    mProviderMap.putProviderByClass(comp, cpr);
7318                }
7319                if (DEBUG_MU)
7320                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7321                app.pubProviders.put(cpi.name, cpr);
7322                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7323                    // Don't add this if it is a platform component that is marked
7324                    // to run in multiple processes, because this is actually
7325                    // part of the framework so doesn't make sense to track as a
7326                    // separate apk in the process.
7327                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7328                }
7329                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7330            }
7331        }
7332        return providers;
7333    }
7334
7335    /**
7336     * Check if {@link ProcessRecord} has a possible chance at accessing the
7337     * given {@link ProviderInfo}. Final permission checking is always done
7338     * in {@link ContentProvider}.
7339     */
7340    private final String checkContentProviderPermissionLocked(
7341            ProviderInfo cpi, ProcessRecord r) {
7342        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7343        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7344        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7345                cpi.applicationInfo.uid, cpi.exported)
7346                == PackageManager.PERMISSION_GRANTED) {
7347            return null;
7348        }
7349        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7350                cpi.applicationInfo.uid, cpi.exported)
7351                == PackageManager.PERMISSION_GRANTED) {
7352            return null;
7353        }
7354
7355        PathPermission[] pps = cpi.pathPermissions;
7356        if (pps != null) {
7357            int i = pps.length;
7358            while (i > 0) {
7359                i--;
7360                PathPermission pp = pps[i];
7361                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7362                        cpi.applicationInfo.uid, cpi.exported)
7363                        == PackageManager.PERMISSION_GRANTED) {
7364                    return null;
7365                }
7366                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7367                        cpi.applicationInfo.uid, cpi.exported)
7368                        == PackageManager.PERMISSION_GRANTED) {
7369                    return null;
7370                }
7371            }
7372        }
7373
7374        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7375        if (perms != null) {
7376            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7377                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7378                    return null;
7379                }
7380            }
7381        }
7382
7383        String msg;
7384        if (!cpi.exported) {
7385            msg = "Permission Denial: opening provider " + cpi.name
7386                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7387                    + ", uid=" + callingUid + ") that is not exported from uid "
7388                    + cpi.applicationInfo.uid;
7389        } else {
7390            msg = "Permission Denial: opening provider " + cpi.name
7391                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7392                    + ", uid=" + callingUid + ") requires "
7393                    + cpi.readPermission + " or " + cpi.writePermission;
7394        }
7395        Slog.w(TAG, msg);
7396        return msg;
7397    }
7398
7399    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7400            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7401        if (r != null) {
7402            for (int i=0; i<r.conProviders.size(); i++) {
7403                ContentProviderConnection conn = r.conProviders.get(i);
7404                if (conn.provider == cpr) {
7405                    if (DEBUG_PROVIDER) Slog.v(TAG,
7406                            "Adding provider requested by "
7407                            + r.processName + " from process "
7408                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7409                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7410                    if (stable) {
7411                        conn.stableCount++;
7412                        conn.numStableIncs++;
7413                    } else {
7414                        conn.unstableCount++;
7415                        conn.numUnstableIncs++;
7416                    }
7417                    return conn;
7418                }
7419            }
7420            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7421            if (stable) {
7422                conn.stableCount = 1;
7423                conn.numStableIncs = 1;
7424            } else {
7425                conn.unstableCount = 1;
7426                conn.numUnstableIncs = 1;
7427            }
7428            cpr.connections.add(conn);
7429            r.conProviders.add(conn);
7430            return conn;
7431        }
7432        cpr.addExternalProcessHandleLocked(externalProcessToken);
7433        return null;
7434    }
7435
7436    boolean decProviderCountLocked(ContentProviderConnection conn,
7437            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7438        if (conn != null) {
7439            cpr = conn.provider;
7440            if (DEBUG_PROVIDER) Slog.v(TAG,
7441                    "Removing provider requested by "
7442                    + conn.client.processName + " from process "
7443                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7444                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7445            if (stable) {
7446                conn.stableCount--;
7447            } else {
7448                conn.unstableCount--;
7449            }
7450            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7451                cpr.connections.remove(conn);
7452                conn.client.conProviders.remove(conn);
7453                return true;
7454            }
7455            return false;
7456        }
7457        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7458        return false;
7459    }
7460
7461    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7462            String name, IBinder token, boolean stable, int userId) {
7463        ContentProviderRecord cpr;
7464        ContentProviderConnection conn = null;
7465        ProviderInfo cpi = null;
7466
7467        synchronized(this) {
7468            ProcessRecord r = null;
7469            if (caller != null) {
7470                r = getRecordForAppLocked(caller);
7471                if (r == null) {
7472                    throw new SecurityException(
7473                            "Unable to find app for caller " + caller
7474                          + " (pid=" + Binder.getCallingPid()
7475                          + ") when getting content provider " + name);
7476                }
7477            }
7478
7479            // First check if this content provider has been published...
7480            cpr = mProviderMap.getProviderByName(name, userId);
7481            boolean providerRunning = cpr != null;
7482            if (providerRunning) {
7483                cpi = cpr.info;
7484                String msg;
7485                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7486                    throw new SecurityException(msg);
7487                }
7488
7489                if (r != null && cpr.canRunHere(r)) {
7490                    // This provider has been published or is in the process
7491                    // of being published...  but it is also allowed to run
7492                    // in the caller's process, so don't make a connection
7493                    // and just let the caller instantiate its own instance.
7494                    ContentProviderHolder holder = cpr.newHolder(null);
7495                    // don't give caller the provider object, it needs
7496                    // to make its own.
7497                    holder.provider = null;
7498                    return holder;
7499                }
7500
7501                final long origId = Binder.clearCallingIdentity();
7502
7503                // In this case the provider instance already exists, so we can
7504                // return it right away.
7505                conn = incProviderCountLocked(r, cpr, token, stable);
7506                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7507                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7508                        // If this is a perceptible app accessing the provider,
7509                        // make sure to count it as being accessed and thus
7510                        // back up on the LRU list.  This is good because
7511                        // content providers are often expensive to start.
7512                        updateLruProcessLocked(cpr.proc, false, null);
7513                    }
7514                }
7515
7516                if (cpr.proc != null) {
7517                    if (false) {
7518                        if (cpr.name.flattenToShortString().equals(
7519                                "com.android.providers.calendar/.CalendarProvider2")) {
7520                            Slog.v(TAG, "****************** KILLING "
7521                                + cpr.name.flattenToShortString());
7522                            Process.killProcess(cpr.proc.pid);
7523                        }
7524                    }
7525                    boolean success = updateOomAdjLocked(cpr.proc);
7526                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7527                    // NOTE: there is still a race here where a signal could be
7528                    // pending on the process even though we managed to update its
7529                    // adj level.  Not sure what to do about this, but at least
7530                    // the race is now smaller.
7531                    if (!success) {
7532                        // Uh oh...  it looks like the provider's process
7533                        // has been killed on us.  We need to wait for a new
7534                        // process to be started, and make sure its death
7535                        // doesn't kill our process.
7536                        Slog.i(TAG,
7537                                "Existing provider " + cpr.name.flattenToShortString()
7538                                + " is crashing; detaching " + r);
7539                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7540                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7541                        if (!lastRef) {
7542                            // This wasn't the last ref our process had on
7543                            // the provider...  we have now been killed, bail.
7544                            return null;
7545                        }
7546                        providerRunning = false;
7547                        conn = null;
7548                    }
7549                }
7550
7551                Binder.restoreCallingIdentity(origId);
7552            }
7553
7554            boolean singleton;
7555            if (!providerRunning) {
7556                try {
7557                    cpi = AppGlobals.getPackageManager().
7558                        resolveContentProvider(name,
7559                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7560                } catch (RemoteException ex) {
7561                }
7562                if (cpi == null) {
7563                    return null;
7564                }
7565                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7566                        cpi.name, cpi.flags);
7567                if (singleton) {
7568                    userId = 0;
7569                }
7570                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7571
7572                String msg;
7573                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7574                    throw new SecurityException(msg);
7575                }
7576
7577                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7578                        && !cpi.processName.equals("system")) {
7579                    // If this content provider does not run in the system
7580                    // process, and the system is not yet ready to run other
7581                    // processes, then fail fast instead of hanging.
7582                    throw new IllegalArgumentException(
7583                            "Attempt to launch content provider before system ready");
7584                }
7585
7586                // Make sure that the user who owns this provider is started.  If not,
7587                // we don't want to allow it to run.
7588                if (mStartedUsers.get(userId) == null) {
7589                    Slog.w(TAG, "Unable to launch app "
7590                            + cpi.applicationInfo.packageName + "/"
7591                            + cpi.applicationInfo.uid + " for provider "
7592                            + name + ": user " + userId + " is stopped");
7593                    return null;
7594                }
7595
7596                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7597                cpr = mProviderMap.getProviderByClass(comp, userId);
7598                final boolean firstClass = cpr == null;
7599                if (firstClass) {
7600                    try {
7601                        ApplicationInfo ai =
7602                            AppGlobals.getPackageManager().
7603                                getApplicationInfo(
7604                                        cpi.applicationInfo.packageName,
7605                                        STOCK_PM_FLAGS, userId);
7606                        if (ai == null) {
7607                            Slog.w(TAG, "No package info for content provider "
7608                                    + cpi.name);
7609                            return null;
7610                        }
7611                        ai = getAppInfoForUser(ai, userId);
7612                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7613                    } catch (RemoteException ex) {
7614                        // pm is in same process, this will never happen.
7615                    }
7616                }
7617
7618                if (r != null && cpr.canRunHere(r)) {
7619                    // If this is a multiprocess provider, then just return its
7620                    // info and allow the caller to instantiate it.  Only do
7621                    // this if the provider is the same user as the caller's
7622                    // process, or can run as root (so can be in any process).
7623                    return cpr.newHolder(null);
7624                }
7625
7626                if (DEBUG_PROVIDER) {
7627                    RuntimeException e = new RuntimeException("here");
7628                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7629                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7630                }
7631
7632                // This is single process, and our app is now connecting to it.
7633                // See if we are already in the process of launching this
7634                // provider.
7635                final int N = mLaunchingProviders.size();
7636                int i;
7637                for (i=0; i<N; i++) {
7638                    if (mLaunchingProviders.get(i) == cpr) {
7639                        break;
7640                    }
7641                }
7642
7643                // If the provider is not already being launched, then get it
7644                // started.
7645                if (i >= N) {
7646                    final long origId = Binder.clearCallingIdentity();
7647
7648                    try {
7649                        // Content provider is now in use, its package can't be stopped.
7650                        try {
7651                            AppGlobals.getPackageManager().setPackageStoppedState(
7652                                    cpr.appInfo.packageName, false, userId);
7653                        } catch (RemoteException e) {
7654                        } catch (IllegalArgumentException e) {
7655                            Slog.w(TAG, "Failed trying to unstop package "
7656                                    + cpr.appInfo.packageName + ": " + e);
7657                        }
7658
7659                        // Use existing process if already started
7660                        ProcessRecord proc = getProcessRecordLocked(
7661                                cpi.processName, cpr.appInfo.uid, false);
7662                        if (proc != null && proc.thread != null) {
7663                            if (DEBUG_PROVIDER) {
7664                                Slog.d(TAG, "Installing in existing process " + proc);
7665                            }
7666                            proc.pubProviders.put(cpi.name, cpr);
7667                            try {
7668                                proc.thread.scheduleInstallProvider(cpi);
7669                            } catch (RemoteException e) {
7670                            }
7671                        } else {
7672                            proc = startProcessLocked(cpi.processName,
7673                                    cpr.appInfo, false, 0, "content provider",
7674                                    new ComponentName(cpi.applicationInfo.packageName,
7675                                            cpi.name), false, false, false);
7676                            if (proc == null) {
7677                                Slog.w(TAG, "Unable to launch app "
7678                                        + cpi.applicationInfo.packageName + "/"
7679                                        + cpi.applicationInfo.uid + " for provider "
7680                                        + name + ": process is bad");
7681                                return null;
7682                            }
7683                        }
7684                        cpr.launchingApp = proc;
7685                        mLaunchingProviders.add(cpr);
7686                    } finally {
7687                        Binder.restoreCallingIdentity(origId);
7688                    }
7689                }
7690
7691                // Make sure the provider is published (the same provider class
7692                // may be published under multiple names).
7693                if (firstClass) {
7694                    mProviderMap.putProviderByClass(comp, cpr);
7695                }
7696
7697                mProviderMap.putProviderByName(name, cpr);
7698                conn = incProviderCountLocked(r, cpr, token, stable);
7699                if (conn != null) {
7700                    conn.waiting = true;
7701                }
7702            }
7703        }
7704
7705        // Wait for the provider to be published...
7706        synchronized (cpr) {
7707            while (cpr.provider == null) {
7708                if (cpr.launchingApp == null) {
7709                    Slog.w(TAG, "Unable to launch app "
7710                            + cpi.applicationInfo.packageName + "/"
7711                            + cpi.applicationInfo.uid + " for provider "
7712                            + name + ": launching app became null");
7713                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7714                            UserHandle.getUserId(cpi.applicationInfo.uid),
7715                            cpi.applicationInfo.packageName,
7716                            cpi.applicationInfo.uid, name);
7717                    return null;
7718                }
7719                try {
7720                    if (DEBUG_MU) {
7721                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7722                                + cpr.launchingApp);
7723                    }
7724                    if (conn != null) {
7725                        conn.waiting = true;
7726                    }
7727                    cpr.wait();
7728                } catch (InterruptedException ex) {
7729                } finally {
7730                    if (conn != null) {
7731                        conn.waiting = false;
7732                    }
7733                }
7734            }
7735        }
7736        return cpr != null ? cpr.newHolder(conn) : null;
7737    }
7738
7739    public final ContentProviderHolder getContentProvider(
7740            IApplicationThread caller, String name, int userId, boolean stable) {
7741        enforceNotIsolatedCaller("getContentProvider");
7742        if (caller == null) {
7743            String msg = "null IApplicationThread when getting content provider "
7744                    + name;
7745            Slog.w(TAG, msg);
7746            throw new SecurityException(msg);
7747        }
7748
7749        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7750                false, true, "getContentProvider", null);
7751        return getContentProviderImpl(caller, name, null, stable, userId);
7752    }
7753
7754    public ContentProviderHolder getContentProviderExternal(
7755            String name, int userId, IBinder token) {
7756        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7757            "Do not have permission in call getContentProviderExternal()");
7758        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7759                false, true, "getContentProvider", null);
7760        return getContentProviderExternalUnchecked(name, token, userId);
7761    }
7762
7763    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7764            IBinder token, int userId) {
7765        return getContentProviderImpl(null, name, token, true, userId);
7766    }
7767
7768    /**
7769     * Drop a content provider from a ProcessRecord's bookkeeping
7770     */
7771    public void removeContentProvider(IBinder connection, boolean stable) {
7772        enforceNotIsolatedCaller("removeContentProvider");
7773        synchronized (this) {
7774            ContentProviderConnection conn;
7775            try {
7776                conn = (ContentProviderConnection)connection;
7777            } catch (ClassCastException e) {
7778                String msg ="removeContentProvider: " + connection
7779                        + " not a ContentProviderConnection";
7780                Slog.w(TAG, msg);
7781                throw new IllegalArgumentException(msg);
7782            }
7783            if (conn == null) {
7784                throw new NullPointerException("connection is null");
7785            }
7786            if (decProviderCountLocked(conn, null, null, stable)) {
7787                updateOomAdjLocked();
7788            }
7789        }
7790    }
7791
7792    public void removeContentProviderExternal(String name, IBinder token) {
7793        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7794            "Do not have permission in call removeContentProviderExternal()");
7795        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7796    }
7797
7798    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7799        synchronized (this) {
7800            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7801            if(cpr == null) {
7802                //remove from mProvidersByClass
7803                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7804                return;
7805            }
7806
7807            //update content provider record entry info
7808            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7809            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7810            if (localCpr.hasExternalProcessHandles()) {
7811                if (localCpr.removeExternalProcessHandleLocked(token)) {
7812                    updateOomAdjLocked();
7813                } else {
7814                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7815                            + " with no external reference for token: "
7816                            + token + ".");
7817                }
7818            } else {
7819                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7820                        + " with no external references.");
7821            }
7822        }
7823    }
7824
7825    public final void publishContentProviders(IApplicationThread caller,
7826            List<ContentProviderHolder> providers) {
7827        if (providers == null) {
7828            return;
7829        }
7830
7831        enforceNotIsolatedCaller("publishContentProviders");
7832        synchronized (this) {
7833            final ProcessRecord r = getRecordForAppLocked(caller);
7834            if (DEBUG_MU)
7835                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7836            if (r == null) {
7837                throw new SecurityException(
7838                        "Unable to find app for caller " + caller
7839                      + " (pid=" + Binder.getCallingPid()
7840                      + ") when publishing content providers");
7841            }
7842
7843            final long origId = Binder.clearCallingIdentity();
7844
7845            final int N = providers.size();
7846            for (int i=0; i<N; i++) {
7847                ContentProviderHolder src = providers.get(i);
7848                if (src == null || src.info == null || src.provider == null) {
7849                    continue;
7850                }
7851                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7852                if (DEBUG_MU)
7853                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7854                if (dst != null) {
7855                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7856                    mProviderMap.putProviderByClass(comp, dst);
7857                    String names[] = dst.info.authority.split(";");
7858                    for (int j = 0; j < names.length; j++) {
7859                        mProviderMap.putProviderByName(names[j], dst);
7860                    }
7861
7862                    int NL = mLaunchingProviders.size();
7863                    int j;
7864                    for (j=0; j<NL; j++) {
7865                        if (mLaunchingProviders.get(j) == dst) {
7866                            mLaunchingProviders.remove(j);
7867                            j--;
7868                            NL--;
7869                        }
7870                    }
7871                    synchronized (dst) {
7872                        dst.provider = src.provider;
7873                        dst.proc = r;
7874                        dst.notifyAll();
7875                    }
7876                    updateOomAdjLocked(r);
7877                }
7878            }
7879
7880            Binder.restoreCallingIdentity(origId);
7881        }
7882    }
7883
7884    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7885        ContentProviderConnection conn;
7886        try {
7887            conn = (ContentProviderConnection)connection;
7888        } catch (ClassCastException e) {
7889            String msg ="refContentProvider: " + connection
7890                    + " not a ContentProviderConnection";
7891            Slog.w(TAG, msg);
7892            throw new IllegalArgumentException(msg);
7893        }
7894        if (conn == null) {
7895            throw new NullPointerException("connection is null");
7896        }
7897
7898        synchronized (this) {
7899            if (stable > 0) {
7900                conn.numStableIncs += stable;
7901            }
7902            stable = conn.stableCount + stable;
7903            if (stable < 0) {
7904                throw new IllegalStateException("stableCount < 0: " + stable);
7905            }
7906
7907            if (unstable > 0) {
7908                conn.numUnstableIncs += unstable;
7909            }
7910            unstable = conn.unstableCount + unstable;
7911            if (unstable < 0) {
7912                throw new IllegalStateException("unstableCount < 0: " + unstable);
7913            }
7914
7915            if ((stable+unstable) <= 0) {
7916                throw new IllegalStateException("ref counts can't go to zero here: stable="
7917                        + stable + " unstable=" + unstable);
7918            }
7919            conn.stableCount = stable;
7920            conn.unstableCount = unstable;
7921            return !conn.dead;
7922        }
7923    }
7924
7925    public void unstableProviderDied(IBinder connection) {
7926        ContentProviderConnection conn;
7927        try {
7928            conn = (ContentProviderConnection)connection;
7929        } catch (ClassCastException e) {
7930            String msg ="refContentProvider: " + connection
7931                    + " not a ContentProviderConnection";
7932            Slog.w(TAG, msg);
7933            throw new IllegalArgumentException(msg);
7934        }
7935        if (conn == null) {
7936            throw new NullPointerException("connection is null");
7937        }
7938
7939        // Safely retrieve the content provider associated with the connection.
7940        IContentProvider provider;
7941        synchronized (this) {
7942            provider = conn.provider.provider;
7943        }
7944
7945        if (provider == null) {
7946            // Um, yeah, we're way ahead of you.
7947            return;
7948        }
7949
7950        // Make sure the caller is being honest with us.
7951        if (provider.asBinder().pingBinder()) {
7952            // Er, no, still looks good to us.
7953            synchronized (this) {
7954                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7955                        + " says " + conn + " died, but we don't agree");
7956                return;
7957            }
7958        }
7959
7960        // Well look at that!  It's dead!
7961        synchronized (this) {
7962            if (conn.provider.provider != provider) {
7963                // But something changed...  good enough.
7964                return;
7965            }
7966
7967            ProcessRecord proc = conn.provider.proc;
7968            if (proc == null || proc.thread == null) {
7969                // Seems like the process is already cleaned up.
7970                return;
7971            }
7972
7973            // As far as we're concerned, this is just like receiving a
7974            // death notification...  just a bit prematurely.
7975            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
7976                    + ") early provider death");
7977            final long ident = Binder.clearCallingIdentity();
7978            try {
7979                appDiedLocked(proc, proc.pid, proc.thread);
7980            } finally {
7981                Binder.restoreCallingIdentity(ident);
7982            }
7983        }
7984    }
7985
7986    @Override
7987    public void appNotRespondingViaProvider(IBinder connection) {
7988        enforceCallingPermission(
7989                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
7990
7991        final ContentProviderConnection conn = (ContentProviderConnection) connection;
7992        if (conn == null) {
7993            Slog.w(TAG, "ContentProviderConnection is null");
7994            return;
7995        }
7996
7997        final ProcessRecord host = conn.provider.proc;
7998        if (host == null) {
7999            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8000            return;
8001        }
8002
8003        final long token = Binder.clearCallingIdentity();
8004        try {
8005            appNotResponding(host, null, null, false, "ContentProvider not responding");
8006        } finally {
8007            Binder.restoreCallingIdentity(token);
8008        }
8009    }
8010
8011    public static final void installSystemProviders() {
8012        List<ProviderInfo> providers;
8013        synchronized (mSelf) {
8014            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
8015            providers = mSelf.generateApplicationProvidersLocked(app);
8016            if (providers != null) {
8017                for (int i=providers.size()-1; i>=0; i--) {
8018                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8019                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8020                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8021                                + ": not system .apk");
8022                        providers.remove(i);
8023                    }
8024                }
8025            }
8026        }
8027        if (providers != null) {
8028            mSystemThread.installSystemProviders(providers);
8029        }
8030
8031        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
8032
8033        mSelf.mUsageStatsService.monitorPackages();
8034    }
8035
8036    /**
8037     * Allows app to retrieve the MIME type of a URI without having permission
8038     * to access its content provider.
8039     *
8040     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8041     *
8042     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8043     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8044     */
8045    public String getProviderMimeType(Uri uri, int userId) {
8046        enforceNotIsolatedCaller("getProviderMimeType");
8047        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8048                userId, false, true, "getProviderMimeType", null);
8049        final String name = uri.getAuthority();
8050        final long ident = Binder.clearCallingIdentity();
8051        ContentProviderHolder holder = null;
8052
8053        try {
8054            holder = getContentProviderExternalUnchecked(name, null, userId);
8055            if (holder != null) {
8056                return holder.provider.getType(uri);
8057            }
8058        } catch (RemoteException e) {
8059            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8060            return null;
8061        } finally {
8062            if (holder != null) {
8063                removeContentProviderExternalUnchecked(name, null, userId);
8064            }
8065            Binder.restoreCallingIdentity(ident);
8066        }
8067
8068        return null;
8069    }
8070
8071    // =========================================================
8072    // GLOBAL MANAGEMENT
8073    // =========================================================
8074
8075    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8076            boolean isolated) {
8077        String proc = customProcess != null ? customProcess : info.processName;
8078        BatteryStatsImpl.Uid.Proc ps = null;
8079        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8080        int uid = info.uid;
8081        if (isolated) {
8082            int userId = UserHandle.getUserId(uid);
8083            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8084            while (true) {
8085                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8086                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8087                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8088                }
8089                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8090                mNextIsolatedProcessUid++;
8091                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8092                    // No process for this uid, use it.
8093                    break;
8094                }
8095                stepsLeft--;
8096                if (stepsLeft <= 0) {
8097                    return null;
8098                }
8099            }
8100        }
8101        return new ProcessRecord(stats, info, proc, uid);
8102    }
8103
8104    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8105        ProcessRecord app;
8106        if (!isolated) {
8107            app = getProcessRecordLocked(info.processName, info.uid, true);
8108        } else {
8109            app = null;
8110        }
8111
8112        if (app == null) {
8113            app = newProcessRecordLocked(info, null, isolated);
8114            mProcessNames.put(info.processName, app.uid, app);
8115            if (isolated) {
8116                mIsolatedProcesses.put(app.uid, app);
8117            }
8118            updateLruProcessLocked(app, false, null);
8119            updateOomAdjLocked();
8120        }
8121
8122        // This package really, really can not be stopped.
8123        try {
8124            AppGlobals.getPackageManager().setPackageStoppedState(
8125                    info.packageName, false, UserHandle.getUserId(app.uid));
8126        } catch (RemoteException e) {
8127        } catch (IllegalArgumentException e) {
8128            Slog.w(TAG, "Failed trying to unstop package "
8129                    + info.packageName + ": " + e);
8130        }
8131
8132        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8133                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8134            app.persistent = true;
8135            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8136        }
8137        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8138            mPersistentStartingProcesses.add(app);
8139            startProcessLocked(app, "added application", app.processName);
8140        }
8141
8142        return app;
8143    }
8144
8145    public void unhandledBack() {
8146        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8147                "unhandledBack()");
8148
8149        synchronized(this) {
8150            final long origId = Binder.clearCallingIdentity();
8151            try {
8152                getFocusedStack().unhandledBackLocked();
8153            } finally {
8154                Binder.restoreCallingIdentity(origId);
8155            }
8156        }
8157    }
8158
8159    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8160        enforceNotIsolatedCaller("openContentUri");
8161        final int userId = UserHandle.getCallingUserId();
8162        String name = uri.getAuthority();
8163        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8164        ParcelFileDescriptor pfd = null;
8165        if (cph != null) {
8166            // We record the binder invoker's uid in thread-local storage before
8167            // going to the content provider to open the file.  Later, in the code
8168            // that handles all permissions checks, we look for this uid and use
8169            // that rather than the Activity Manager's own uid.  The effect is that
8170            // we do the check against the caller's permissions even though it looks
8171            // to the content provider like the Activity Manager itself is making
8172            // the request.
8173            sCallerIdentity.set(new Identity(
8174                    Binder.getCallingPid(), Binder.getCallingUid()));
8175            try {
8176                pfd = cph.provider.openFile(null, uri, "r", null);
8177            } catch (FileNotFoundException e) {
8178                // do nothing; pfd will be returned null
8179            } finally {
8180                // Ensure that whatever happens, we clean up the identity state
8181                sCallerIdentity.remove();
8182            }
8183
8184            // We've got the fd now, so we're done with the provider.
8185            removeContentProviderExternalUnchecked(name, null, userId);
8186        } else {
8187            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8188        }
8189        return pfd;
8190    }
8191
8192    // Actually is sleeping or shutting down or whatever else in the future
8193    // is an inactive state.
8194    public boolean isSleepingOrShuttingDown() {
8195        return mSleeping || mShuttingDown;
8196    }
8197
8198    public void goingToSleep() {
8199        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8200                != PackageManager.PERMISSION_GRANTED) {
8201            throw new SecurityException("Requires permission "
8202                    + android.Manifest.permission.DEVICE_POWER);
8203        }
8204
8205        synchronized(this) {
8206            mWentToSleep = true;
8207            updateEventDispatchingLocked();
8208
8209            if (!mSleeping) {
8210                mSleeping = true;
8211                mStackSupervisor.goingToSleepLocked();
8212
8213                // Initialize the wake times of all processes.
8214                checkExcessivePowerUsageLocked(false);
8215                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8216                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8217                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8218            }
8219        }
8220    }
8221
8222    @Override
8223    public boolean shutdown(int timeout) {
8224        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8225                != PackageManager.PERMISSION_GRANTED) {
8226            throw new SecurityException("Requires permission "
8227                    + android.Manifest.permission.SHUTDOWN);
8228        }
8229
8230        boolean timedout = false;
8231
8232        synchronized(this) {
8233            mShuttingDown = true;
8234            updateEventDispatchingLocked();
8235            timedout = mStackSupervisor.shutdownLocked(timeout);
8236        }
8237
8238        mAppOpsService.shutdown();
8239        mUsageStatsService.shutdown();
8240        mBatteryStatsService.shutdown();
8241        synchronized (this) {
8242            mProcessStats.shutdownLocked();
8243        }
8244
8245        return timedout;
8246    }
8247
8248    public final void activitySlept(IBinder token) {
8249        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8250
8251        final long origId = Binder.clearCallingIdentity();
8252
8253        synchronized (this) {
8254            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8255            if (r != null) {
8256                mStackSupervisor.activitySleptLocked(r);
8257            }
8258        }
8259
8260        Binder.restoreCallingIdentity(origId);
8261    }
8262
8263    void logLockScreen(String msg) {
8264        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8265                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8266                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8267                mStackSupervisor.mDismissKeyguardOnNextActivity);
8268    }
8269
8270    private void comeOutOfSleepIfNeededLocked() {
8271        if (!mWentToSleep && !mLockScreenShown) {
8272            if (mSleeping) {
8273                mSleeping = false;
8274                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8275            }
8276        }
8277    }
8278
8279    public void wakingUp() {
8280        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8281                != PackageManager.PERMISSION_GRANTED) {
8282            throw new SecurityException("Requires permission "
8283                    + android.Manifest.permission.DEVICE_POWER);
8284        }
8285
8286        synchronized(this) {
8287            mWentToSleep = false;
8288            updateEventDispatchingLocked();
8289            comeOutOfSleepIfNeededLocked();
8290        }
8291    }
8292
8293    private void updateEventDispatchingLocked() {
8294        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8295    }
8296
8297    public void setLockScreenShown(boolean shown) {
8298        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8299                != PackageManager.PERMISSION_GRANTED) {
8300            throw new SecurityException("Requires permission "
8301                    + android.Manifest.permission.DEVICE_POWER);
8302        }
8303
8304        synchronized(this) {
8305            long ident = Binder.clearCallingIdentity();
8306            try {
8307                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8308                mLockScreenShown = shown;
8309                comeOutOfSleepIfNeededLocked();
8310            } finally {
8311                Binder.restoreCallingIdentity(ident);
8312            }
8313        }
8314    }
8315
8316    public void stopAppSwitches() {
8317        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8318                != PackageManager.PERMISSION_GRANTED) {
8319            throw new SecurityException("Requires permission "
8320                    + android.Manifest.permission.STOP_APP_SWITCHES);
8321        }
8322
8323        synchronized(this) {
8324            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8325                    + APP_SWITCH_DELAY_TIME;
8326            mDidAppSwitch = false;
8327            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8328            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8329            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8330        }
8331    }
8332
8333    public void resumeAppSwitches() {
8334        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8335                != PackageManager.PERMISSION_GRANTED) {
8336            throw new SecurityException("Requires permission "
8337                    + android.Manifest.permission.STOP_APP_SWITCHES);
8338        }
8339
8340        synchronized(this) {
8341            // Note that we don't execute any pending app switches... we will
8342            // let those wait until either the timeout, or the next start
8343            // activity request.
8344            mAppSwitchesAllowedTime = 0;
8345        }
8346    }
8347
8348    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8349            String name) {
8350        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8351            return true;
8352        }
8353
8354        final int perm = checkComponentPermission(
8355                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8356                callingUid, -1, true);
8357        if (perm == PackageManager.PERMISSION_GRANTED) {
8358            return true;
8359        }
8360
8361        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8362        return false;
8363    }
8364
8365    public void setDebugApp(String packageName, boolean waitForDebugger,
8366            boolean persistent) {
8367        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8368                "setDebugApp()");
8369
8370        long ident = Binder.clearCallingIdentity();
8371        try {
8372            // Note that this is not really thread safe if there are multiple
8373            // callers into it at the same time, but that's not a situation we
8374            // care about.
8375            if (persistent) {
8376                final ContentResolver resolver = mContext.getContentResolver();
8377                Settings.Global.putString(
8378                    resolver, Settings.Global.DEBUG_APP,
8379                    packageName);
8380                Settings.Global.putInt(
8381                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8382                    waitForDebugger ? 1 : 0);
8383            }
8384
8385            synchronized (this) {
8386                if (!persistent) {
8387                    mOrigDebugApp = mDebugApp;
8388                    mOrigWaitForDebugger = mWaitForDebugger;
8389                }
8390                mDebugApp = packageName;
8391                mWaitForDebugger = waitForDebugger;
8392                mDebugTransient = !persistent;
8393                if (packageName != null) {
8394                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8395                            UserHandle.USER_ALL, "set debug app");
8396                }
8397            }
8398        } finally {
8399            Binder.restoreCallingIdentity(ident);
8400        }
8401    }
8402
8403    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8404        synchronized (this) {
8405            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8406            if (!isDebuggable) {
8407                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8408                    throw new SecurityException("Process not debuggable: " + app.packageName);
8409                }
8410            }
8411
8412            mOpenGlTraceApp = processName;
8413        }
8414    }
8415
8416    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8417            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8418        synchronized (this) {
8419            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8420            if (!isDebuggable) {
8421                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8422                    throw new SecurityException("Process not debuggable: " + app.packageName);
8423                }
8424            }
8425            mProfileApp = processName;
8426            mProfileFile = profileFile;
8427            if (mProfileFd != null) {
8428                try {
8429                    mProfileFd.close();
8430                } catch (IOException e) {
8431                }
8432                mProfileFd = null;
8433            }
8434            mProfileFd = profileFd;
8435            mProfileType = 0;
8436            mAutoStopProfiler = autoStopProfiler;
8437        }
8438    }
8439
8440    @Override
8441    public void setAlwaysFinish(boolean enabled) {
8442        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8443                "setAlwaysFinish()");
8444
8445        Settings.Global.putInt(
8446                mContext.getContentResolver(),
8447                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8448
8449        synchronized (this) {
8450            mAlwaysFinishActivities = enabled;
8451        }
8452    }
8453
8454    @Override
8455    public void setActivityController(IActivityController controller) {
8456        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8457                "setActivityController()");
8458        synchronized (this) {
8459            mController = controller;
8460            Watchdog.getInstance().setActivityController(controller);
8461        }
8462    }
8463
8464    @Override
8465    public void setUserIsMonkey(boolean userIsMonkey) {
8466        synchronized (this) {
8467            synchronized (mPidsSelfLocked) {
8468                final int callingPid = Binder.getCallingPid();
8469                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8470                if (precessRecord == null) {
8471                    throw new SecurityException("Unknown process: " + callingPid);
8472                }
8473                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8474                    throw new SecurityException("Only an instrumentation process "
8475                            + "with a UiAutomation can call setUserIsMonkey");
8476                }
8477            }
8478            mUserIsMonkey = userIsMonkey;
8479        }
8480    }
8481
8482    @Override
8483    public boolean isUserAMonkey() {
8484        synchronized (this) {
8485            // If there is a controller also implies the user is a monkey.
8486            return (mUserIsMonkey || mController != null);
8487        }
8488    }
8489
8490    public void requestBugReport() {
8491        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8492        SystemProperties.set("ctl.start", "bugreport");
8493    }
8494
8495    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8496        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8497    }
8498
8499    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8500        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8501            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8502        }
8503        return KEY_DISPATCHING_TIMEOUT;
8504    }
8505
8506    @Override
8507    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8508        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8509                != PackageManager.PERMISSION_GRANTED) {
8510            throw new SecurityException("Requires permission "
8511                    + android.Manifest.permission.FILTER_EVENTS);
8512        }
8513        ProcessRecord proc;
8514        long timeout;
8515        synchronized (this) {
8516            synchronized (mPidsSelfLocked) {
8517                proc = mPidsSelfLocked.get(pid);
8518            }
8519            timeout = getInputDispatchingTimeoutLocked(proc);
8520        }
8521
8522        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8523            return -1;
8524        }
8525
8526        return timeout;
8527    }
8528
8529    /**
8530     * Handle input dispatching timeouts.
8531     * Returns whether input dispatching should be aborted or not.
8532     */
8533    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8534            final ActivityRecord activity, final ActivityRecord parent,
8535            final boolean aboveSystem, String reason) {
8536        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8537                != PackageManager.PERMISSION_GRANTED) {
8538            throw new SecurityException("Requires permission "
8539                    + android.Manifest.permission.FILTER_EVENTS);
8540        }
8541
8542        final String annotation;
8543        if (reason == null) {
8544            annotation = "Input dispatching timed out";
8545        } else {
8546            annotation = "Input dispatching timed out (" + reason + ")";
8547        }
8548
8549        if (proc != null) {
8550            synchronized (this) {
8551                if (proc.debugging) {
8552                    return false;
8553                }
8554
8555                if (mDidDexOpt) {
8556                    // Give more time since we were dexopting.
8557                    mDidDexOpt = false;
8558                    return false;
8559                }
8560
8561                if (proc.instrumentationClass != null) {
8562                    Bundle info = new Bundle();
8563                    info.putString("shortMsg", "keyDispatchingTimedOut");
8564                    info.putString("longMsg", annotation);
8565                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8566                    return true;
8567                }
8568            }
8569            mHandler.post(new Runnable() {
8570                @Override
8571                public void run() {
8572                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8573                }
8574            });
8575        }
8576
8577        return true;
8578    }
8579
8580    public Bundle getAssistContextExtras(int requestType) {
8581        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8582                "getAssistContextExtras()");
8583        PendingAssistExtras pae;
8584        Bundle extras = new Bundle();
8585        synchronized (this) {
8586            ActivityRecord activity = getFocusedStack().mResumedActivity;
8587            if (activity == null) {
8588                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8589                return null;
8590            }
8591            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8592            if (activity.app == null || activity.app.thread == null) {
8593                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8594                return extras;
8595            }
8596            if (activity.app.pid == Binder.getCallingPid()) {
8597                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8598                return extras;
8599            }
8600            pae = new PendingAssistExtras(activity);
8601            try {
8602                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8603                        requestType);
8604                mPendingAssistExtras.add(pae);
8605                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8606            } catch (RemoteException e) {
8607                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8608                return extras;
8609            }
8610        }
8611        synchronized (pae) {
8612            while (!pae.haveResult) {
8613                try {
8614                    pae.wait();
8615                } catch (InterruptedException e) {
8616                }
8617            }
8618            if (pae.result != null) {
8619                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8620            }
8621        }
8622        synchronized (this) {
8623            mPendingAssistExtras.remove(pae);
8624            mHandler.removeCallbacks(pae);
8625        }
8626        return extras;
8627    }
8628
8629    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8630        PendingAssistExtras pae = (PendingAssistExtras)token;
8631        synchronized (pae) {
8632            pae.result = extras;
8633            pae.haveResult = true;
8634            pae.notifyAll();
8635        }
8636    }
8637
8638    public void registerProcessObserver(IProcessObserver observer) {
8639        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8640                "registerProcessObserver()");
8641        synchronized (this) {
8642            mProcessObservers.register(observer);
8643        }
8644    }
8645
8646    @Override
8647    public void unregisterProcessObserver(IProcessObserver observer) {
8648        synchronized (this) {
8649            mProcessObservers.unregister(observer);
8650        }
8651    }
8652
8653    @Override
8654    public boolean convertFromTranslucent(IBinder token) {
8655        final long origId = Binder.clearCallingIdentity();
8656        try {
8657            synchronized (this) {
8658                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8659                if (r == null) {
8660                    return false;
8661                }
8662                if (r.changeWindowTranslucency(true)) {
8663                    mWindowManager.setAppFullscreen(token, true);
8664                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8665                    return true;
8666                }
8667                return false;
8668            }
8669        } finally {
8670            Binder.restoreCallingIdentity(origId);
8671        }
8672    }
8673
8674    @Override
8675    public boolean convertToTranslucent(IBinder token) {
8676        final long origId = Binder.clearCallingIdentity();
8677        try {
8678            synchronized (this) {
8679                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8680                if (r == null) {
8681                    return false;
8682                }
8683                if (r.changeWindowTranslucency(false)) {
8684                    r.task.stack.convertToTranslucent(r);
8685                    mWindowManager.setAppFullscreen(token, false);
8686                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8687                    return true;
8688                }
8689                return false;
8690            }
8691        } finally {
8692            Binder.restoreCallingIdentity(origId);
8693        }
8694    }
8695
8696    @Override
8697    public void setImmersive(IBinder token, boolean immersive) {
8698        synchronized(this) {
8699            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8700            if (r == null) {
8701                throw new IllegalArgumentException();
8702            }
8703            r.immersive = immersive;
8704
8705            // update associated state if we're frontmost
8706            if (r == mFocusedActivity) {
8707                if (DEBUG_IMMERSIVE) {
8708                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8709                }
8710                applyUpdateLockStateLocked(r);
8711            }
8712        }
8713    }
8714
8715    @Override
8716    public boolean isImmersive(IBinder token) {
8717        synchronized (this) {
8718            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8719            if (r == null) {
8720                throw new IllegalArgumentException();
8721            }
8722            return r.immersive;
8723        }
8724    }
8725
8726    public boolean isTopActivityImmersive() {
8727        enforceNotIsolatedCaller("startActivity");
8728        synchronized (this) {
8729            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8730            return (r != null) ? r.immersive : false;
8731        }
8732    }
8733
8734    public final void enterSafeMode() {
8735        synchronized(this) {
8736            // It only makes sense to do this before the system is ready
8737            // and started launching other packages.
8738            if (!mSystemReady) {
8739                try {
8740                    AppGlobals.getPackageManager().enterSafeMode();
8741                } catch (RemoteException e) {
8742                }
8743            }
8744        }
8745    }
8746
8747    public final void showSafeModeOverlay() {
8748        View v = LayoutInflater.from(mContext).inflate(
8749                com.android.internal.R.layout.safe_mode, null);
8750        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8751        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8752        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8753        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8754        lp.gravity = Gravity.BOTTOM | Gravity.START;
8755        lp.format = v.getBackground().getOpacity();
8756        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8757                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8758        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8759        ((WindowManager)mContext.getSystemService(
8760                Context.WINDOW_SERVICE)).addView(v, lp);
8761    }
8762
8763    public void noteWakeupAlarm(IIntentSender sender) {
8764        if (!(sender instanceof PendingIntentRecord)) {
8765            return;
8766        }
8767        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8768        synchronized (stats) {
8769            if (mBatteryStatsService.isOnBattery()) {
8770                mBatteryStatsService.enforceCallingPermission();
8771                PendingIntentRecord rec = (PendingIntentRecord)sender;
8772                int MY_UID = Binder.getCallingUid();
8773                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8774                BatteryStatsImpl.Uid.Pkg pkg =
8775                    stats.getPackageStatsLocked(uid, rec.key.packageName);
8776                pkg.incWakeupsLocked();
8777            }
8778        }
8779    }
8780
8781    public boolean killPids(int[] pids, String pReason, boolean secure) {
8782        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8783            throw new SecurityException("killPids only available to the system");
8784        }
8785        String reason = (pReason == null) ? "Unknown" : pReason;
8786        // XXX Note: don't acquire main activity lock here, because the window
8787        // manager calls in with its locks held.
8788
8789        boolean killed = false;
8790        synchronized (mPidsSelfLocked) {
8791            int[] types = new int[pids.length];
8792            int worstType = 0;
8793            for (int i=0; i<pids.length; i++) {
8794                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8795                if (proc != null) {
8796                    int type = proc.setAdj;
8797                    types[i] = type;
8798                    if (type > worstType) {
8799                        worstType = type;
8800                    }
8801                }
8802            }
8803
8804            // If the worst oom_adj is somewhere in the cached proc LRU range,
8805            // then constrain it so we will kill all cached procs.
8806            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8807                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8808                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8809            }
8810
8811            // If this is not a secure call, don't let it kill processes that
8812            // are important.
8813            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8814                worstType = ProcessList.SERVICE_ADJ;
8815            }
8816
8817            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8818            for (int i=0; i<pids.length; i++) {
8819                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8820                if (proc == null) {
8821                    continue;
8822                }
8823                int adj = proc.setAdj;
8824                if (adj >= worstType && !proc.killedByAm) {
8825                    killUnneededProcessLocked(proc, reason);
8826                    killed = true;
8827                }
8828            }
8829        }
8830        return killed;
8831    }
8832
8833    @Override
8834    public void killUid(int uid, String reason) {
8835        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8836            throw new SecurityException("killUid only available to the system");
8837        }
8838        synchronized (this) {
8839            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8840                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8841                    reason != null ? reason : "kill uid");
8842        }
8843    }
8844
8845    @Override
8846    public boolean killProcessesBelowForeground(String reason) {
8847        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8848            throw new SecurityException("killProcessesBelowForeground() only available to system");
8849        }
8850
8851        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8852    }
8853
8854    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8855        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8856            throw new SecurityException("killProcessesBelowAdj() only available to system");
8857        }
8858
8859        boolean killed = false;
8860        synchronized (mPidsSelfLocked) {
8861            final int size = mPidsSelfLocked.size();
8862            for (int i = 0; i < size; i++) {
8863                final int pid = mPidsSelfLocked.keyAt(i);
8864                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8865                if (proc == null) continue;
8866
8867                final int adj = proc.setAdj;
8868                if (adj > belowAdj && !proc.killedByAm) {
8869                    killUnneededProcessLocked(proc, reason);
8870                    killed = true;
8871                }
8872            }
8873        }
8874        return killed;
8875    }
8876
8877    @Override
8878    public void hang(final IBinder who, boolean allowRestart) {
8879        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8880                != PackageManager.PERMISSION_GRANTED) {
8881            throw new SecurityException("Requires permission "
8882                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8883        }
8884
8885        final IBinder.DeathRecipient death = new DeathRecipient() {
8886            @Override
8887            public void binderDied() {
8888                synchronized (this) {
8889                    notifyAll();
8890                }
8891            }
8892        };
8893
8894        try {
8895            who.linkToDeath(death, 0);
8896        } catch (RemoteException e) {
8897            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8898            return;
8899        }
8900
8901        synchronized (this) {
8902            Watchdog.getInstance().setAllowRestart(allowRestart);
8903            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8904            synchronized (death) {
8905                while (who.isBinderAlive()) {
8906                    try {
8907                        death.wait();
8908                    } catch (InterruptedException e) {
8909                    }
8910                }
8911            }
8912            Watchdog.getInstance().setAllowRestart(true);
8913        }
8914    }
8915
8916    @Override
8917    public void restart() {
8918        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8919                != PackageManager.PERMISSION_GRANTED) {
8920            throw new SecurityException("Requires permission "
8921                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8922        }
8923
8924        Log.i(TAG, "Sending shutdown broadcast...");
8925
8926        BroadcastReceiver br = new BroadcastReceiver() {
8927            @Override public void onReceive(Context context, Intent intent) {
8928                // Now the broadcast is done, finish up the low-level shutdown.
8929                Log.i(TAG, "Shutting down activity manager...");
8930                shutdown(10000);
8931                Log.i(TAG, "Shutdown complete, restarting!");
8932                Process.killProcess(Process.myPid());
8933                System.exit(10);
8934            }
8935        };
8936
8937        // First send the high-level shut down broadcast.
8938        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8939        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8940        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8941        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8942        mContext.sendOrderedBroadcastAsUser(intent,
8943                UserHandle.ALL, null, br, mHandler, 0, null, null);
8944        */
8945        br.onReceive(mContext, intent);
8946    }
8947
8948    private long getLowRamTimeSinceIdle(long now) {
8949        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8950    }
8951
8952    @Override
8953    public void performIdleMaintenance() {
8954        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8955                != PackageManager.PERMISSION_GRANTED) {
8956            throw new SecurityException("Requires permission "
8957                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8958        }
8959
8960        synchronized (this) {
8961            final long now = SystemClock.uptimeMillis();
8962            final long timeSinceLastIdle = now - mLastIdleTime;
8963            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
8964            mLastIdleTime = now;
8965            mLowRamTimeSinceLastIdle = 0;
8966            if (mLowRamStartTime != 0) {
8967                mLowRamStartTime = now;
8968            }
8969
8970            StringBuilder sb = new StringBuilder(128);
8971            sb.append("Idle maintenance over ");
8972            TimeUtils.formatDuration(timeSinceLastIdle, sb);
8973            sb.append(" low RAM for ");
8974            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
8975            Slog.i(TAG, sb.toString());
8976
8977            // If at least 1/3 of our time since the last idle period has been spent
8978            // with RAM low, then we want to kill processes.
8979            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
8980
8981            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
8982                ProcessRecord proc = mLruProcesses.get(i);
8983                if (proc.notCachedSinceIdle) {
8984                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
8985                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
8986                        if (doKilling && proc.initialIdlePss != 0
8987                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
8988                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
8989                                    + " from " + proc.initialIdlePss + ")");
8990                        }
8991                    }
8992                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
8993                    proc.notCachedSinceIdle = true;
8994                    proc.initialIdlePss = 0;
8995                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
8996                            mSleeping, now);
8997                }
8998            }
8999
9000            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9001            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9002        }
9003    }
9004
9005    public final void startRunning(String pkg, String cls, String action,
9006            String data) {
9007        synchronized(this) {
9008            if (mStartRunning) {
9009                return;
9010            }
9011            mStartRunning = true;
9012            mTopComponent = pkg != null && cls != null
9013                    ? new ComponentName(pkg, cls) : null;
9014            mTopAction = action != null ? action : Intent.ACTION_MAIN;
9015            mTopData = data;
9016            if (!mSystemReady) {
9017                return;
9018            }
9019        }
9020
9021        systemReady(null);
9022    }
9023
9024    private void retrieveSettings() {
9025        final ContentResolver resolver = mContext.getContentResolver();
9026        String debugApp = Settings.Global.getString(
9027            resolver, Settings.Global.DEBUG_APP);
9028        boolean waitForDebugger = Settings.Global.getInt(
9029            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9030        boolean alwaysFinishActivities = Settings.Global.getInt(
9031            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9032        boolean forceRtl = Settings.Global.getInt(
9033                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9034        // Transfer any global setting for forcing RTL layout, into a System Property
9035        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9036
9037        Configuration configuration = new Configuration();
9038        Settings.System.getConfiguration(resolver, configuration);
9039        if (forceRtl) {
9040            // This will take care of setting the correct layout direction flags
9041            configuration.setLayoutDirection(configuration.locale);
9042        }
9043
9044        synchronized (this) {
9045            mDebugApp = mOrigDebugApp = debugApp;
9046            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9047            mAlwaysFinishActivities = alwaysFinishActivities;
9048            // This happens before any activities are started, so we can
9049            // change mConfiguration in-place.
9050            updateConfigurationLocked(configuration, null, false, true);
9051            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9052        }
9053    }
9054
9055    public boolean testIsSystemReady() {
9056        // no need to synchronize(this) just to read & return the value
9057        return mSystemReady;
9058    }
9059
9060    private static File getCalledPreBootReceiversFile() {
9061        File dataDir = Environment.getDataDirectory();
9062        File systemDir = new File(dataDir, "system");
9063        File fname = new File(systemDir, "called_pre_boots.dat");
9064        return fname;
9065    }
9066
9067    static final int LAST_DONE_VERSION = 10000;
9068
9069    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9070        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9071        File file = getCalledPreBootReceiversFile();
9072        FileInputStream fis = null;
9073        try {
9074            fis = new FileInputStream(file);
9075            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9076            int fvers = dis.readInt();
9077            if (fvers == LAST_DONE_VERSION) {
9078                String vers = dis.readUTF();
9079                String codename = dis.readUTF();
9080                String build = dis.readUTF();
9081                if (android.os.Build.VERSION.RELEASE.equals(vers)
9082                        && android.os.Build.VERSION.CODENAME.equals(codename)
9083                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9084                    int num = dis.readInt();
9085                    while (num > 0) {
9086                        num--;
9087                        String pkg = dis.readUTF();
9088                        String cls = dis.readUTF();
9089                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9090                    }
9091                }
9092            }
9093        } catch (FileNotFoundException e) {
9094        } catch (IOException e) {
9095            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9096        } finally {
9097            if (fis != null) {
9098                try {
9099                    fis.close();
9100                } catch (IOException e) {
9101                }
9102            }
9103        }
9104        return lastDoneReceivers;
9105    }
9106
9107    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9108        File file = getCalledPreBootReceiversFile();
9109        FileOutputStream fos = null;
9110        DataOutputStream dos = null;
9111        try {
9112            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9113            fos = new FileOutputStream(file);
9114            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9115            dos.writeInt(LAST_DONE_VERSION);
9116            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9117            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9118            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9119            dos.writeInt(list.size());
9120            for (int i=0; i<list.size(); i++) {
9121                dos.writeUTF(list.get(i).getPackageName());
9122                dos.writeUTF(list.get(i).getClassName());
9123            }
9124        } catch (IOException e) {
9125            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9126            file.delete();
9127        } finally {
9128            FileUtils.sync(fos);
9129            if (dos != null) {
9130                try {
9131                    dos.close();
9132                } catch (IOException e) {
9133                    // TODO Auto-generated catch block
9134                    e.printStackTrace();
9135                }
9136            }
9137        }
9138    }
9139
9140    public void systemReady(final Runnable goingCallback) {
9141        synchronized(this) {
9142            if (mSystemReady) {
9143                if (goingCallback != null) goingCallback.run();
9144                return;
9145            }
9146
9147            // Check to see if there are any update receivers to run.
9148            if (!mDidUpdate) {
9149                if (mWaitingUpdate) {
9150                    return;
9151                }
9152                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9153                List<ResolveInfo> ris = null;
9154                try {
9155                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9156                            intent, null, 0, 0);
9157                } catch (RemoteException e) {
9158                }
9159                if (ris != null) {
9160                    for (int i=ris.size()-1; i>=0; i--) {
9161                        if ((ris.get(i).activityInfo.applicationInfo.flags
9162                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9163                            ris.remove(i);
9164                        }
9165                    }
9166                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9167
9168                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9169
9170                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
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                        if (lastDoneReceivers.contains(comp)) {
9175                            ris.remove(i);
9176                            i--;
9177                        }
9178                    }
9179
9180                    final int[] users = getUsersLocked();
9181                    for (int i=0; i<ris.size(); i++) {
9182                        ActivityInfo ai = ris.get(i).activityInfo;
9183                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9184                        doneReceivers.add(comp);
9185                        intent.setComponent(comp);
9186                        for (int j=0; j<users.length; j++) {
9187                            IIntentReceiver finisher = null;
9188                            if (i == ris.size()-1 && j == users.length-1) {
9189                                finisher = new IIntentReceiver.Stub() {
9190                                    public void performReceive(Intent intent, int resultCode,
9191                                            String data, Bundle extras, boolean ordered,
9192                                            boolean sticky, int sendingUser) {
9193                                        // The raw IIntentReceiver interface is called
9194                                        // with the AM lock held, so redispatch to
9195                                        // execute our code without the lock.
9196                                        mHandler.post(new Runnable() {
9197                                            public void run() {
9198                                                synchronized (ActivityManagerService.this) {
9199                                                    mDidUpdate = true;
9200                                                }
9201                                                writeLastDonePreBootReceivers(doneReceivers);
9202                                                showBootMessage(mContext.getText(
9203                                                        R.string.android_upgrading_complete),
9204                                                        false);
9205                                                systemReady(goingCallback);
9206                                            }
9207                                        });
9208                                    }
9209                                };
9210                            }
9211                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9212                                    + " for user " + users[j]);
9213                            broadcastIntentLocked(null, null, intent, null, finisher,
9214                                    0, null, null, null, AppOpsManager.OP_NONE,
9215                                    true, false, MY_PID, Process.SYSTEM_UID,
9216                                    users[j]);
9217                            if (finisher != null) {
9218                                mWaitingUpdate = true;
9219                            }
9220                        }
9221                    }
9222                }
9223                if (mWaitingUpdate) {
9224                    return;
9225                }
9226                mDidUpdate = true;
9227            }
9228
9229            mAppOpsService.systemReady();
9230            mSystemReady = true;
9231            if (!mStartRunning) {
9232                return;
9233            }
9234        }
9235
9236        ArrayList<ProcessRecord> procsToKill = null;
9237        synchronized(mPidsSelfLocked) {
9238            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9239                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9240                if (!isAllowedWhileBooting(proc.info)){
9241                    if (procsToKill == null) {
9242                        procsToKill = new ArrayList<ProcessRecord>();
9243                    }
9244                    procsToKill.add(proc);
9245                }
9246            }
9247        }
9248
9249        synchronized(this) {
9250            if (procsToKill != null) {
9251                for (int i=procsToKill.size()-1; i>=0; i--) {
9252                    ProcessRecord proc = procsToKill.get(i);
9253                    Slog.i(TAG, "Removing system update proc: " + proc);
9254                    removeProcessLocked(proc, true, false, "system update done");
9255                }
9256            }
9257
9258            // Now that we have cleaned up any update processes, we
9259            // are ready to start launching real processes and know that
9260            // we won't trample on them any more.
9261            mProcessesReady = true;
9262        }
9263
9264        Slog.i(TAG, "System now ready");
9265        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9266            SystemClock.uptimeMillis());
9267
9268        synchronized(this) {
9269            // Make sure we have no pre-ready processes sitting around.
9270
9271            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
9272                ResolveInfo ri = mContext.getPackageManager()
9273                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9274                                STOCK_PM_FLAGS);
9275                CharSequence errorMsg = null;
9276                if (ri != null) {
9277                    ActivityInfo ai = ri.activityInfo;
9278                    ApplicationInfo app = ai.applicationInfo;
9279                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9280                        mTopAction = Intent.ACTION_FACTORY_TEST;
9281                        mTopData = null;
9282                        mTopComponent = new ComponentName(app.packageName,
9283                                ai.name);
9284                    } else {
9285                        errorMsg = mContext.getResources().getText(
9286                                com.android.internal.R.string.factorytest_not_system);
9287                    }
9288                } else {
9289                    errorMsg = mContext.getResources().getText(
9290                            com.android.internal.R.string.factorytest_no_action);
9291                }
9292                if (errorMsg != null) {
9293                    mTopAction = null;
9294                    mTopData = null;
9295                    mTopComponent = null;
9296                    Message msg = Message.obtain();
9297                    msg.what = SHOW_FACTORY_ERROR_MSG;
9298                    msg.getData().putCharSequence("msg", errorMsg);
9299                    mHandler.sendMessage(msg);
9300                }
9301            }
9302        }
9303
9304        retrieveSettings();
9305
9306        synchronized (this) {
9307            readGrantedUriPermissionsLocked();
9308        }
9309
9310        if (goingCallback != null) goingCallback.run();
9311
9312        synchronized (this) {
9313            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
9314                try {
9315                    List apps = AppGlobals.getPackageManager().
9316                        getPersistentApplications(STOCK_PM_FLAGS);
9317                    if (apps != null) {
9318                        int N = apps.size();
9319                        int i;
9320                        for (i=0; i<N; i++) {
9321                            ApplicationInfo info
9322                                = (ApplicationInfo)apps.get(i);
9323                            if (info != null &&
9324                                    !info.packageName.equals("android")) {
9325                                addAppLocked(info, false);
9326                            }
9327                        }
9328                    }
9329                } catch (RemoteException ex) {
9330                    // pm is in same process, this will never happen.
9331                }
9332            }
9333
9334            // Start up initial activity.
9335            mBooting = true;
9336
9337            try {
9338                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9339                    Message msg = Message.obtain();
9340                    msg.what = SHOW_UID_ERROR_MSG;
9341                    mHandler.sendMessage(msg);
9342                }
9343            } catch (RemoteException e) {
9344            }
9345
9346            long ident = Binder.clearCallingIdentity();
9347            try {
9348                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9349                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9350                        | Intent.FLAG_RECEIVER_FOREGROUND);
9351                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9352                broadcastIntentLocked(null, null, intent,
9353                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9354                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9355                intent = new Intent(Intent.ACTION_USER_STARTING);
9356                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9357                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9358                broadcastIntentLocked(null, null, intent,
9359                        null, new IIntentReceiver.Stub() {
9360                            @Override
9361                            public void performReceive(Intent intent, int resultCode, String data,
9362                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9363                                    throws RemoteException {
9364                            }
9365                        }, 0, null, null,
9366                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9367                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9368            } finally {
9369                Binder.restoreCallingIdentity(ident);
9370            }
9371            mStackSupervisor.resumeTopActivitiesLocked();
9372            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9373        }
9374    }
9375
9376    private boolean makeAppCrashingLocked(ProcessRecord app,
9377            String shortMsg, String longMsg, String stackTrace) {
9378        app.crashing = true;
9379        app.crashingReport = generateProcessError(app,
9380                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9381        startAppProblemLocked(app);
9382        app.stopFreezingAllLocked();
9383        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9384    }
9385
9386    private void makeAppNotRespondingLocked(ProcessRecord app,
9387            String activity, String shortMsg, String longMsg) {
9388        app.notResponding = true;
9389        app.notRespondingReport = generateProcessError(app,
9390                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9391                activity, shortMsg, longMsg, null);
9392        startAppProblemLocked(app);
9393        app.stopFreezingAllLocked();
9394    }
9395
9396    /**
9397     * Generate a process error record, suitable for attachment to a ProcessRecord.
9398     *
9399     * @param app The ProcessRecord in which the error occurred.
9400     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9401     *                      ActivityManager.AppErrorStateInfo
9402     * @param activity The activity associated with the crash, if known.
9403     * @param shortMsg Short message describing the crash.
9404     * @param longMsg Long message describing the crash.
9405     * @param stackTrace Full crash stack trace, may be null.
9406     *
9407     * @return Returns a fully-formed AppErrorStateInfo record.
9408     */
9409    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9410            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9411        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9412
9413        report.condition = condition;
9414        report.processName = app.processName;
9415        report.pid = app.pid;
9416        report.uid = app.info.uid;
9417        report.tag = activity;
9418        report.shortMsg = shortMsg;
9419        report.longMsg = longMsg;
9420        report.stackTrace = stackTrace;
9421
9422        return report;
9423    }
9424
9425    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9426        synchronized (this) {
9427            app.crashing = false;
9428            app.crashingReport = null;
9429            app.notResponding = false;
9430            app.notRespondingReport = null;
9431            if (app.anrDialog == fromDialog) {
9432                app.anrDialog = null;
9433            }
9434            if (app.waitDialog == fromDialog) {
9435                app.waitDialog = null;
9436            }
9437            if (app.pid > 0 && app.pid != MY_PID) {
9438                handleAppCrashLocked(app, null, null, null);
9439                killUnneededProcessLocked(app, "user request after error");
9440            }
9441        }
9442    }
9443
9444    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9445            String stackTrace) {
9446        long now = SystemClock.uptimeMillis();
9447
9448        Long crashTime;
9449        if (!app.isolated) {
9450            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9451        } else {
9452            crashTime = null;
9453        }
9454        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9455            // This process loses!
9456            Slog.w(TAG, "Process " + app.info.processName
9457                    + " has crashed too many times: killing!");
9458            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9459                    app.userId, app.info.processName, app.uid);
9460            mStackSupervisor.handleAppCrashLocked(app);
9461            if (!app.persistent) {
9462                // We don't want to start this process again until the user
9463                // explicitly does so...  but for persistent process, we really
9464                // need to keep it running.  If a persistent process is actually
9465                // repeatedly crashing, then badness for everyone.
9466                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9467                        app.info.processName);
9468                if (!app.isolated) {
9469                    // XXX We don't have a way to mark isolated processes
9470                    // as bad, since they don't have a peristent identity.
9471                    mBadProcesses.put(app.info.processName, app.uid,
9472                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9473                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9474                }
9475                app.bad = true;
9476                app.removed = true;
9477                // Don't let services in this process be restarted and potentially
9478                // annoy the user repeatedly.  Unless it is persistent, since those
9479                // processes run critical code.
9480                removeProcessLocked(app, false, false, "crash");
9481                mStackSupervisor.resumeTopActivitiesLocked();
9482                return false;
9483            }
9484            mStackSupervisor.resumeTopActivitiesLocked();
9485        } else {
9486            mStackSupervisor.finishTopRunningActivityLocked(app);
9487        }
9488
9489        // Bump up the crash count of any services currently running in the proc.
9490        for (int i=app.services.size()-1; i>=0; i--) {
9491            // Any services running in the application need to be placed
9492            // back in the pending list.
9493            ServiceRecord sr = app.services.valueAt(i);
9494            sr.crashCount++;
9495        }
9496
9497        // If the crashing process is what we consider to be the "home process" and it has been
9498        // replaced by a third-party app, clear the package preferred activities from packages
9499        // with a home activity running in the process to prevent a repeatedly crashing app
9500        // from blocking the user to manually clear the list.
9501        final ArrayList<ActivityRecord> activities = app.activities;
9502        if (app == mHomeProcess && activities.size() > 0
9503                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9504            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9505                final ActivityRecord r = activities.get(activityNdx);
9506                if (r.isHomeActivity()) {
9507                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9508                    try {
9509                        ActivityThread.getPackageManager()
9510                                .clearPackagePreferredActivities(r.packageName);
9511                    } catch (RemoteException c) {
9512                        // pm is in same process, this will never happen.
9513                    }
9514                }
9515            }
9516        }
9517
9518        if (!app.isolated) {
9519            // XXX Can't keep track of crash times for isolated processes,
9520            // because they don't have a perisistent identity.
9521            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9522        }
9523
9524        return true;
9525    }
9526
9527    void startAppProblemLocked(ProcessRecord app) {
9528        if (app.userId == mCurrentUserId) {
9529            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9530                    mContext, app.info.packageName, app.info.flags);
9531        } else {
9532            // If this app is not running under the current user, then we
9533            // can't give it a report button because that would require
9534            // launching the report UI under a different user.
9535            app.errorReportReceiver = null;
9536        }
9537        skipCurrentReceiverLocked(app);
9538    }
9539
9540    void skipCurrentReceiverLocked(ProcessRecord app) {
9541        for (BroadcastQueue queue : mBroadcastQueues) {
9542            queue.skipCurrentReceiverLocked(app);
9543        }
9544    }
9545
9546    /**
9547     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9548     * The application process will exit immediately after this call returns.
9549     * @param app object of the crashing app, null for the system server
9550     * @param crashInfo describing the exception
9551     */
9552    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9553        ProcessRecord r = findAppProcess(app, "Crash");
9554        final String processName = app == null ? "system_server"
9555                : (r == null ? "unknown" : r.processName);
9556
9557        handleApplicationCrashInner("crash", r, processName, crashInfo);
9558    }
9559
9560    /* Native crash reporting uses this inner version because it needs to be somewhat
9561     * decoupled from the AM-managed cleanup lifecycle
9562     */
9563    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9564            ApplicationErrorReport.CrashInfo crashInfo) {
9565        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9566                UserHandle.getUserId(Binder.getCallingUid()), processName,
9567                r == null ? -1 : r.info.flags,
9568                crashInfo.exceptionClassName,
9569                crashInfo.exceptionMessage,
9570                crashInfo.throwFileName,
9571                crashInfo.throwLineNumber);
9572
9573        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9574
9575        crashApplication(r, crashInfo);
9576    }
9577
9578    public void handleApplicationStrictModeViolation(
9579            IBinder app,
9580            int violationMask,
9581            StrictMode.ViolationInfo info) {
9582        ProcessRecord r = findAppProcess(app, "StrictMode");
9583        if (r == null) {
9584            return;
9585        }
9586
9587        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9588            Integer stackFingerprint = info.hashCode();
9589            boolean logIt = true;
9590            synchronized (mAlreadyLoggedViolatedStacks) {
9591                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9592                    logIt = false;
9593                    // TODO: sub-sample into EventLog for these, with
9594                    // the info.durationMillis?  Then we'd get
9595                    // the relative pain numbers, without logging all
9596                    // the stack traces repeatedly.  We'd want to do
9597                    // likewise in the client code, which also does
9598                    // dup suppression, before the Binder call.
9599                } else {
9600                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9601                        mAlreadyLoggedViolatedStacks.clear();
9602                    }
9603                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9604                }
9605            }
9606            if (logIt) {
9607                logStrictModeViolationToDropBox(r, info);
9608            }
9609        }
9610
9611        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9612            AppErrorResult result = new AppErrorResult();
9613            synchronized (this) {
9614                final long origId = Binder.clearCallingIdentity();
9615
9616                Message msg = Message.obtain();
9617                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9618                HashMap<String, Object> data = new HashMap<String, Object>();
9619                data.put("result", result);
9620                data.put("app", r);
9621                data.put("violationMask", violationMask);
9622                data.put("info", info);
9623                msg.obj = data;
9624                mHandler.sendMessage(msg);
9625
9626                Binder.restoreCallingIdentity(origId);
9627            }
9628            int res = result.get();
9629            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9630        }
9631    }
9632
9633    // Depending on the policy in effect, there could be a bunch of
9634    // these in quick succession so we try to batch these together to
9635    // minimize disk writes, number of dropbox entries, and maximize
9636    // compression, by having more fewer, larger records.
9637    private void logStrictModeViolationToDropBox(
9638            ProcessRecord process,
9639            StrictMode.ViolationInfo info) {
9640        if (info == null) {
9641            return;
9642        }
9643        final boolean isSystemApp = process == null ||
9644                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9645                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9646        final String processName = process == null ? "unknown" : process.processName;
9647        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9648        final DropBoxManager dbox = (DropBoxManager)
9649                mContext.getSystemService(Context.DROPBOX_SERVICE);
9650
9651        // Exit early if the dropbox isn't configured to accept this report type.
9652        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9653
9654        boolean bufferWasEmpty;
9655        boolean needsFlush;
9656        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9657        synchronized (sb) {
9658            bufferWasEmpty = sb.length() == 0;
9659            appendDropBoxProcessHeaders(process, processName, sb);
9660            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9661            sb.append("System-App: ").append(isSystemApp).append("\n");
9662            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9663            if (info.violationNumThisLoop != 0) {
9664                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9665            }
9666            if (info.numAnimationsRunning != 0) {
9667                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9668            }
9669            if (info.broadcastIntentAction != null) {
9670                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9671            }
9672            if (info.durationMillis != -1) {
9673                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9674            }
9675            if (info.numInstances != -1) {
9676                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9677            }
9678            if (info.tags != null) {
9679                for (String tag : info.tags) {
9680                    sb.append("Span-Tag: ").append(tag).append("\n");
9681                }
9682            }
9683            sb.append("\n");
9684            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9685                sb.append(info.crashInfo.stackTrace);
9686            }
9687            sb.append("\n");
9688
9689            // Only buffer up to ~64k.  Various logging bits truncate
9690            // things at 128k.
9691            needsFlush = (sb.length() > 64 * 1024);
9692        }
9693
9694        // Flush immediately if the buffer's grown too large, or this
9695        // is a non-system app.  Non-system apps are isolated with a
9696        // different tag & policy and not batched.
9697        //
9698        // Batching is useful during internal testing with
9699        // StrictMode settings turned up high.  Without batching,
9700        // thousands of separate files could be created on boot.
9701        if (!isSystemApp || needsFlush) {
9702            new Thread("Error dump: " + dropboxTag) {
9703                @Override
9704                public void run() {
9705                    String report;
9706                    synchronized (sb) {
9707                        report = sb.toString();
9708                        sb.delete(0, sb.length());
9709                        sb.trimToSize();
9710                    }
9711                    if (report.length() != 0) {
9712                        dbox.addText(dropboxTag, report);
9713                    }
9714                }
9715            }.start();
9716            return;
9717        }
9718
9719        // System app batching:
9720        if (!bufferWasEmpty) {
9721            // An existing dropbox-writing thread is outstanding, so
9722            // we don't need to start it up.  The existing thread will
9723            // catch the buffer appends we just did.
9724            return;
9725        }
9726
9727        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9728        // (After this point, we shouldn't access AMS internal data structures.)
9729        new Thread("Error dump: " + dropboxTag) {
9730            @Override
9731            public void run() {
9732                // 5 second sleep to let stacks arrive and be batched together
9733                try {
9734                    Thread.sleep(5000);  // 5 seconds
9735                } catch (InterruptedException e) {}
9736
9737                String errorReport;
9738                synchronized (mStrictModeBuffer) {
9739                    errorReport = mStrictModeBuffer.toString();
9740                    if (errorReport.length() == 0) {
9741                        return;
9742                    }
9743                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9744                    mStrictModeBuffer.trimToSize();
9745                }
9746                dbox.addText(dropboxTag, errorReport);
9747            }
9748        }.start();
9749    }
9750
9751    /**
9752     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9753     * @param app object of the crashing app, null for the system server
9754     * @param tag reported by the caller
9755     * @param crashInfo describing the context of the error
9756     * @return true if the process should exit immediately (WTF is fatal)
9757     */
9758    public boolean handleApplicationWtf(IBinder app, String tag,
9759            ApplicationErrorReport.CrashInfo crashInfo) {
9760        ProcessRecord r = findAppProcess(app, "WTF");
9761        final String processName = app == null ? "system_server"
9762                : (r == null ? "unknown" : r.processName);
9763
9764        EventLog.writeEvent(EventLogTags.AM_WTF,
9765                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9766                processName,
9767                r == null ? -1 : r.info.flags,
9768                tag, crashInfo.exceptionMessage);
9769
9770        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9771
9772        if (r != null && r.pid != Process.myPid() &&
9773                Settings.Global.getInt(mContext.getContentResolver(),
9774                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9775            crashApplication(r, crashInfo);
9776            return true;
9777        } else {
9778            return false;
9779        }
9780    }
9781
9782    /**
9783     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9784     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9785     */
9786    private ProcessRecord findAppProcess(IBinder app, String reason) {
9787        if (app == null) {
9788            return null;
9789        }
9790
9791        synchronized (this) {
9792            final int NP = mProcessNames.getMap().size();
9793            for (int ip=0; ip<NP; ip++) {
9794                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9795                final int NA = apps.size();
9796                for (int ia=0; ia<NA; ia++) {
9797                    ProcessRecord p = apps.valueAt(ia);
9798                    if (p.thread != null && p.thread.asBinder() == app) {
9799                        return p;
9800                    }
9801                }
9802            }
9803
9804            Slog.w(TAG, "Can't find mystery application for " + reason
9805                    + " from pid=" + Binder.getCallingPid()
9806                    + " uid=" + Binder.getCallingUid() + ": " + app);
9807            return null;
9808        }
9809    }
9810
9811    /**
9812     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9813     * to append various headers to the dropbox log text.
9814     */
9815    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9816            StringBuilder sb) {
9817        // Watchdog thread ends up invoking this function (with
9818        // a null ProcessRecord) to add the stack file to dropbox.
9819        // Do not acquire a lock on this (am) in such cases, as it
9820        // could cause a potential deadlock, if and when watchdog
9821        // is invoked due to unavailability of lock on am and it
9822        // would prevent watchdog from killing system_server.
9823        if (process == null) {
9824            sb.append("Process: ").append(processName).append("\n");
9825            return;
9826        }
9827        // Note: ProcessRecord 'process' is guarded by the service
9828        // instance.  (notably process.pkgList, which could otherwise change
9829        // concurrently during execution of this method)
9830        synchronized (this) {
9831            sb.append("Process: ").append(processName).append("\n");
9832            int flags = process.info.flags;
9833            IPackageManager pm = AppGlobals.getPackageManager();
9834            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9835            for (int ip=0; ip<process.pkgList.size(); ip++) {
9836                String pkg = process.pkgList.keyAt(ip);
9837                sb.append("Package: ").append(pkg);
9838                try {
9839                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9840                    if (pi != null) {
9841                        sb.append(" v").append(pi.versionCode);
9842                        if (pi.versionName != null) {
9843                            sb.append(" (").append(pi.versionName).append(")");
9844                        }
9845                    }
9846                } catch (RemoteException e) {
9847                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9848                }
9849                sb.append("\n");
9850            }
9851        }
9852    }
9853
9854    private static String processClass(ProcessRecord process) {
9855        if (process == null || process.pid == MY_PID) {
9856            return "system_server";
9857        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9858            return "system_app";
9859        } else {
9860            return "data_app";
9861        }
9862    }
9863
9864    /**
9865     * Write a description of an error (crash, WTF, ANR) to the drop box.
9866     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9867     * @param process which caused the error, null means the system server
9868     * @param activity which triggered the error, null if unknown
9869     * @param parent activity related to the error, null if unknown
9870     * @param subject line related to the error, null if absent
9871     * @param report in long form describing the error, null if absent
9872     * @param logFile to include in the report, null if none
9873     * @param crashInfo giving an application stack trace, null if absent
9874     */
9875    public void addErrorToDropBox(String eventType,
9876            ProcessRecord process, String processName, ActivityRecord activity,
9877            ActivityRecord parent, String subject,
9878            final String report, final File logFile,
9879            final ApplicationErrorReport.CrashInfo crashInfo) {
9880        // NOTE -- this must never acquire the ActivityManagerService lock,
9881        // otherwise the watchdog may be prevented from resetting the system.
9882
9883        final String dropboxTag = processClass(process) + "_" + eventType;
9884        final DropBoxManager dbox = (DropBoxManager)
9885                mContext.getSystemService(Context.DROPBOX_SERVICE);
9886
9887        // Exit early if the dropbox isn't configured to accept this report type.
9888        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9889
9890        final StringBuilder sb = new StringBuilder(1024);
9891        appendDropBoxProcessHeaders(process, processName, sb);
9892        if (activity != null) {
9893            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9894        }
9895        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9896            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9897        }
9898        if (parent != null && parent != activity) {
9899            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9900        }
9901        if (subject != null) {
9902            sb.append("Subject: ").append(subject).append("\n");
9903        }
9904        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9905        if (Debug.isDebuggerConnected()) {
9906            sb.append("Debugger: Connected\n");
9907        }
9908        sb.append("\n");
9909
9910        // Do the rest in a worker thread to avoid blocking the caller on I/O
9911        // (After this point, we shouldn't access AMS internal data structures.)
9912        Thread worker = new Thread("Error dump: " + dropboxTag) {
9913            @Override
9914            public void run() {
9915                if (report != null) {
9916                    sb.append(report);
9917                }
9918                if (logFile != null) {
9919                    try {
9920                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9921                                    "\n\n[[TRUNCATED]]"));
9922                    } catch (IOException e) {
9923                        Slog.e(TAG, "Error reading " + logFile, e);
9924                    }
9925                }
9926                if (crashInfo != null && crashInfo.stackTrace != null) {
9927                    sb.append(crashInfo.stackTrace);
9928                }
9929
9930                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9931                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9932                if (lines > 0) {
9933                    sb.append("\n");
9934
9935                    // Merge several logcat streams, and take the last N lines
9936                    InputStreamReader input = null;
9937                    try {
9938                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9939                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9940                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9941
9942                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9943                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9944                        input = new InputStreamReader(logcat.getInputStream());
9945
9946                        int num;
9947                        char[] buf = new char[8192];
9948                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9949                    } catch (IOException e) {
9950                        Slog.e(TAG, "Error running logcat", e);
9951                    } finally {
9952                        if (input != null) try { input.close(); } catch (IOException e) {}
9953                    }
9954                }
9955
9956                dbox.addText(dropboxTag, sb.toString());
9957            }
9958        };
9959
9960        if (process == null) {
9961            // If process is null, we are being called from some internal code
9962            // and may be about to die -- run this synchronously.
9963            worker.run();
9964        } else {
9965            worker.start();
9966        }
9967    }
9968
9969    /**
9970     * Bring up the "unexpected error" dialog box for a crashing app.
9971     * Deal with edge cases (intercepts from instrumented applications,
9972     * ActivityController, error intent receivers, that sort of thing).
9973     * @param r the application crashing
9974     * @param crashInfo describing the failure
9975     */
9976    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
9977        long timeMillis = System.currentTimeMillis();
9978        String shortMsg = crashInfo.exceptionClassName;
9979        String longMsg = crashInfo.exceptionMessage;
9980        String stackTrace = crashInfo.stackTrace;
9981        if (shortMsg != null && longMsg != null) {
9982            longMsg = shortMsg + ": " + longMsg;
9983        } else if (shortMsg != null) {
9984            longMsg = shortMsg;
9985        }
9986
9987        AppErrorResult result = new AppErrorResult();
9988        synchronized (this) {
9989            if (mController != null) {
9990                try {
9991                    String name = r != null ? r.processName : null;
9992                    int pid = r != null ? r.pid : Binder.getCallingPid();
9993                    if (!mController.appCrashed(name, pid,
9994                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
9995                        Slog.w(TAG, "Force-killing crashed app " + name
9996                                + " at watcher's request");
9997                        Process.killProcess(pid);
9998                        return;
9999                    }
10000                } catch (RemoteException e) {
10001                    mController = null;
10002                    Watchdog.getInstance().setActivityController(null);
10003                }
10004            }
10005
10006            final long origId = Binder.clearCallingIdentity();
10007
10008            // If this process is running instrumentation, finish it.
10009            if (r != null && r.instrumentationClass != null) {
10010                Slog.w(TAG, "Error in app " + r.processName
10011                      + " running instrumentation " + r.instrumentationClass + ":");
10012                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10013                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10014                Bundle info = new Bundle();
10015                info.putString("shortMsg", shortMsg);
10016                info.putString("longMsg", longMsg);
10017                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10018                Binder.restoreCallingIdentity(origId);
10019                return;
10020            }
10021
10022            // If we can't identify the process or it's already exceeded its crash quota,
10023            // quit right away without showing a crash dialog.
10024            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10025                Binder.restoreCallingIdentity(origId);
10026                return;
10027            }
10028
10029            Message msg = Message.obtain();
10030            msg.what = SHOW_ERROR_MSG;
10031            HashMap data = new HashMap();
10032            data.put("result", result);
10033            data.put("app", r);
10034            msg.obj = data;
10035            mHandler.sendMessage(msg);
10036
10037            Binder.restoreCallingIdentity(origId);
10038        }
10039
10040        int res = result.get();
10041
10042        Intent appErrorIntent = null;
10043        synchronized (this) {
10044            if (r != null && !r.isolated) {
10045                // XXX Can't keep track of crash time for isolated processes,
10046                // since they don't have a persistent identity.
10047                mProcessCrashTimes.put(r.info.processName, r.uid,
10048                        SystemClock.uptimeMillis());
10049            }
10050            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10051                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10052            }
10053        }
10054
10055        if (appErrorIntent != null) {
10056            try {
10057                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10058            } catch (ActivityNotFoundException e) {
10059                Slog.w(TAG, "bug report receiver dissappeared", e);
10060            }
10061        }
10062    }
10063
10064    Intent createAppErrorIntentLocked(ProcessRecord r,
10065            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10066        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10067        if (report == null) {
10068            return null;
10069        }
10070        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10071        result.setComponent(r.errorReportReceiver);
10072        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10073        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10074        return result;
10075    }
10076
10077    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10078            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10079        if (r.errorReportReceiver == null) {
10080            return null;
10081        }
10082
10083        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10084            return null;
10085        }
10086
10087        ApplicationErrorReport report = new ApplicationErrorReport();
10088        report.packageName = r.info.packageName;
10089        report.installerPackageName = r.errorReportReceiver.getPackageName();
10090        report.processName = r.processName;
10091        report.time = timeMillis;
10092        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10093
10094        if (r.crashing || r.forceCrashReport) {
10095            report.type = ApplicationErrorReport.TYPE_CRASH;
10096            report.crashInfo = crashInfo;
10097        } else if (r.notResponding) {
10098            report.type = ApplicationErrorReport.TYPE_ANR;
10099            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10100
10101            report.anrInfo.activity = r.notRespondingReport.tag;
10102            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10103            report.anrInfo.info = r.notRespondingReport.longMsg;
10104        }
10105
10106        return report;
10107    }
10108
10109    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10110        enforceNotIsolatedCaller("getProcessesInErrorState");
10111        // assume our apps are happy - lazy create the list
10112        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10113
10114        final boolean allUsers = ActivityManager.checkUidPermission(
10115                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10116                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10117        int userId = UserHandle.getUserId(Binder.getCallingUid());
10118
10119        synchronized (this) {
10120
10121            // iterate across all processes
10122            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10123                ProcessRecord app = mLruProcesses.get(i);
10124                if (!allUsers && app.userId != userId) {
10125                    continue;
10126                }
10127                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10128                    // This one's in trouble, so we'll generate a report for it
10129                    // crashes are higher priority (in case there's a crash *and* an anr)
10130                    ActivityManager.ProcessErrorStateInfo report = null;
10131                    if (app.crashing) {
10132                        report = app.crashingReport;
10133                    } else if (app.notResponding) {
10134                        report = app.notRespondingReport;
10135                    }
10136
10137                    if (report != null) {
10138                        if (errList == null) {
10139                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10140                        }
10141                        errList.add(report);
10142                    } else {
10143                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10144                                " crashing = " + app.crashing +
10145                                " notResponding = " + app.notResponding);
10146                    }
10147                }
10148            }
10149        }
10150
10151        return errList;
10152    }
10153
10154    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10155        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10156            if (currApp != null) {
10157                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10158            }
10159            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10160        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10161            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10162        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10163            if (currApp != null) {
10164                currApp.lru = 0;
10165            }
10166            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10167        } else if (adj >= ProcessList.SERVICE_ADJ) {
10168            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10169        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10170            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10171        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10172            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10173        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10174            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10175        } else {
10176            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10177        }
10178    }
10179
10180    private void fillInProcMemInfo(ProcessRecord app,
10181            ActivityManager.RunningAppProcessInfo outInfo) {
10182        outInfo.pid = app.pid;
10183        outInfo.uid = app.info.uid;
10184        if (mHeavyWeightProcess == app) {
10185            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10186        }
10187        if (app.persistent) {
10188            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10189        }
10190        if (app.activities.size() > 0) {
10191            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10192        }
10193        outInfo.lastTrimLevel = app.trimMemoryLevel;
10194        int adj = app.curAdj;
10195        outInfo.importance = oomAdjToImportance(adj, outInfo);
10196        outInfo.importanceReasonCode = app.adjTypeCode;
10197    }
10198
10199    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10200        enforceNotIsolatedCaller("getRunningAppProcesses");
10201        // Lazy instantiation of list
10202        List<ActivityManager.RunningAppProcessInfo> runList = null;
10203        final boolean allUsers = ActivityManager.checkUidPermission(
10204                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10205                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10206        int userId = UserHandle.getUserId(Binder.getCallingUid());
10207        synchronized (this) {
10208            // Iterate across all processes
10209            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10210                ProcessRecord app = mLruProcesses.get(i);
10211                if (!allUsers && app.userId != userId) {
10212                    continue;
10213                }
10214                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10215                    // Generate process state info for running application
10216                    ActivityManager.RunningAppProcessInfo currApp =
10217                        new ActivityManager.RunningAppProcessInfo(app.processName,
10218                                app.pid, app.getPackageList());
10219                    fillInProcMemInfo(app, currApp);
10220                    if (app.adjSource instanceof ProcessRecord) {
10221                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10222                        currApp.importanceReasonImportance = oomAdjToImportance(
10223                                app.adjSourceOom, null);
10224                    } else if (app.adjSource instanceof ActivityRecord) {
10225                        ActivityRecord r = (ActivityRecord)app.adjSource;
10226                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10227                    }
10228                    if (app.adjTarget instanceof ComponentName) {
10229                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10230                    }
10231                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10232                    //        + " lru=" + currApp.lru);
10233                    if (runList == null) {
10234                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10235                    }
10236                    runList.add(currApp);
10237                }
10238            }
10239        }
10240        return runList;
10241    }
10242
10243    public List<ApplicationInfo> getRunningExternalApplications() {
10244        enforceNotIsolatedCaller("getRunningExternalApplications");
10245        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10246        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10247        if (runningApps != null && runningApps.size() > 0) {
10248            Set<String> extList = new HashSet<String>();
10249            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10250                if (app.pkgList != null) {
10251                    for (String pkg : app.pkgList) {
10252                        extList.add(pkg);
10253                    }
10254                }
10255            }
10256            IPackageManager pm = AppGlobals.getPackageManager();
10257            for (String pkg : extList) {
10258                try {
10259                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10260                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10261                        retList.add(info);
10262                    }
10263                } catch (RemoteException e) {
10264                }
10265            }
10266        }
10267        return retList;
10268    }
10269
10270    @Override
10271    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10272        enforceNotIsolatedCaller("getMyMemoryState");
10273        synchronized (this) {
10274            ProcessRecord proc;
10275            synchronized (mPidsSelfLocked) {
10276                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10277            }
10278            fillInProcMemInfo(proc, outInfo);
10279        }
10280    }
10281
10282    @Override
10283    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10284        if (checkCallingPermission(android.Manifest.permission.DUMP)
10285                != PackageManager.PERMISSION_GRANTED) {
10286            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10287                    + Binder.getCallingPid()
10288                    + ", uid=" + Binder.getCallingUid()
10289                    + " without permission "
10290                    + android.Manifest.permission.DUMP);
10291            return;
10292        }
10293
10294        boolean dumpAll = false;
10295        boolean dumpClient = false;
10296        String dumpPackage = null;
10297
10298        int opti = 0;
10299        while (opti < args.length) {
10300            String opt = args[opti];
10301            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10302                break;
10303            }
10304            opti++;
10305            if ("-a".equals(opt)) {
10306                dumpAll = true;
10307            } else if ("-c".equals(opt)) {
10308                dumpClient = true;
10309            } else if ("-h".equals(opt)) {
10310                pw.println("Activity manager dump options:");
10311                pw.println("  [-a] [-c] [-h] [cmd] ...");
10312                pw.println("  cmd may be one of:");
10313                pw.println("    a[ctivities]: activity stack state");
10314                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10315                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10316                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10317                pw.println("    o[om]: out of memory management");
10318                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10319                pw.println("    provider [COMP_SPEC]: provider client-side state");
10320                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10321                pw.println("    service [COMP_SPEC]: service client-side state");
10322                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10323                pw.println("    all: dump all activities");
10324                pw.println("    top: dump the top activity");
10325                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10326                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10327                pw.println("    a partial substring in a component name, a");
10328                pw.println("    hex object identifier.");
10329                pw.println("  -a: include all available server state.");
10330                pw.println("  -c: include client state.");
10331                return;
10332            } else {
10333                pw.println("Unknown argument: " + opt + "; use -h for help");
10334            }
10335        }
10336
10337        long origId = Binder.clearCallingIdentity();
10338        boolean more = false;
10339        // Is the caller requesting to dump a particular piece of data?
10340        if (opti < args.length) {
10341            String cmd = args[opti];
10342            opti++;
10343            if ("activities".equals(cmd) || "a".equals(cmd)) {
10344                synchronized (this) {
10345                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10346                }
10347            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10348                String[] newArgs;
10349                String name;
10350                if (opti >= args.length) {
10351                    name = null;
10352                    newArgs = EMPTY_STRING_ARRAY;
10353                } else {
10354                    name = args[opti];
10355                    opti++;
10356                    newArgs = new String[args.length - opti];
10357                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10358                            args.length - opti);
10359                }
10360                synchronized (this) {
10361                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10362                }
10363            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10364                String[] newArgs;
10365                String name;
10366                if (opti >= args.length) {
10367                    name = null;
10368                    newArgs = EMPTY_STRING_ARRAY;
10369                } else {
10370                    name = args[opti];
10371                    opti++;
10372                    newArgs = new String[args.length - opti];
10373                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10374                            args.length - opti);
10375                }
10376                synchronized (this) {
10377                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10378                }
10379            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10380                String[] newArgs;
10381                String name;
10382                if (opti >= args.length) {
10383                    name = null;
10384                    newArgs = EMPTY_STRING_ARRAY;
10385                } else {
10386                    name = args[opti];
10387                    opti++;
10388                    newArgs = new String[args.length - opti];
10389                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10390                            args.length - opti);
10391                }
10392                synchronized (this) {
10393                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10394                }
10395            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10396                synchronized (this) {
10397                    dumpOomLocked(fd, pw, args, opti, true);
10398                }
10399            } else if ("provider".equals(cmd)) {
10400                String[] newArgs;
10401                String name;
10402                if (opti >= args.length) {
10403                    name = null;
10404                    newArgs = EMPTY_STRING_ARRAY;
10405                } else {
10406                    name = args[opti];
10407                    opti++;
10408                    newArgs = new String[args.length - opti];
10409                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10410                }
10411                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10412                    pw.println("No providers match: " + name);
10413                    pw.println("Use -h for help.");
10414                }
10415            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10416                synchronized (this) {
10417                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10418                }
10419            } else if ("service".equals(cmd)) {
10420                String[] newArgs;
10421                String name;
10422                if (opti >= args.length) {
10423                    name = null;
10424                    newArgs = EMPTY_STRING_ARRAY;
10425                } else {
10426                    name = args[opti];
10427                    opti++;
10428                    newArgs = new String[args.length - opti];
10429                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10430                            args.length - opti);
10431                }
10432                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10433                    pw.println("No services match: " + name);
10434                    pw.println("Use -h for help.");
10435                }
10436            } else if ("package".equals(cmd)) {
10437                String[] newArgs;
10438                if (opti >= args.length) {
10439                    pw.println("package: no package name specified");
10440                    pw.println("Use -h for help.");
10441                } else {
10442                    dumpPackage = args[opti];
10443                    opti++;
10444                    newArgs = new String[args.length - opti];
10445                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10446                            args.length - opti);
10447                    args = newArgs;
10448                    opti = 0;
10449                    more = true;
10450                }
10451            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10452                synchronized (this) {
10453                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10454                }
10455            } else {
10456                // Dumping a single activity?
10457                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10458                    pw.println("Bad activity command, or no activities match: " + cmd);
10459                    pw.println("Use -h for help.");
10460                }
10461            }
10462            if (!more) {
10463                Binder.restoreCallingIdentity(origId);
10464                return;
10465            }
10466        }
10467
10468        // No piece of data specified, dump everything.
10469        synchronized (this) {
10470            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10471            pw.println();
10472            if (dumpAll) {
10473                pw.println("-------------------------------------------------------------------------------");
10474            }
10475            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10476            pw.println();
10477            if (dumpAll) {
10478                pw.println("-------------------------------------------------------------------------------");
10479            }
10480            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10481            pw.println();
10482            if (dumpAll) {
10483                pw.println("-------------------------------------------------------------------------------");
10484            }
10485            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10486            pw.println();
10487            if (dumpAll) {
10488                pw.println("-------------------------------------------------------------------------------");
10489            }
10490            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10491            pw.println();
10492            if (dumpAll) {
10493                pw.println("-------------------------------------------------------------------------------");
10494            }
10495            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10496        }
10497        Binder.restoreCallingIdentity(origId);
10498    }
10499
10500    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10501            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10502        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10503
10504        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10505                dumpPackage);
10506        boolean needSep = printedAnything;
10507
10508        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10509                dumpPackage, needSep, "  mFocusedActivity: ");
10510        if (printed) {
10511            printedAnything = true;
10512            needSep = false;
10513        }
10514
10515        if (dumpPackage == null) {
10516            if (needSep) {
10517                pw.println();
10518            }
10519            needSep = true;
10520            printedAnything = true;
10521            mStackSupervisor.dump(pw, "  ");
10522        }
10523
10524        if (mRecentTasks.size() > 0) {
10525            boolean printedHeader = false;
10526
10527            final int N = mRecentTasks.size();
10528            for (int i=0; i<N; i++) {
10529                TaskRecord tr = mRecentTasks.get(i);
10530                if (dumpPackage != null) {
10531                    if (tr.realActivity == null ||
10532                            !dumpPackage.equals(tr.realActivity)) {
10533                        continue;
10534                    }
10535                }
10536                if (!printedHeader) {
10537                    if (needSep) {
10538                        pw.println();
10539                    }
10540                    pw.println("  Recent tasks:");
10541                    printedHeader = true;
10542                    printedAnything = true;
10543                }
10544                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10545                        pw.println(tr);
10546                if (dumpAll) {
10547                    mRecentTasks.get(i).dump(pw, "    ");
10548                }
10549            }
10550        }
10551
10552        if (!printedAnything) {
10553            pw.println("  (nothing)");
10554        }
10555    }
10556
10557    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10558            int opti, boolean dumpAll, String dumpPackage) {
10559        boolean needSep = false;
10560        boolean printedAnything = false;
10561        int numPers = 0;
10562
10563        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10564
10565        if (dumpAll) {
10566            final int NP = mProcessNames.getMap().size();
10567            for (int ip=0; ip<NP; ip++) {
10568                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10569                final int NA = procs.size();
10570                for (int ia=0; ia<NA; ia++) {
10571                    ProcessRecord r = procs.valueAt(ia);
10572                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10573                        continue;
10574                    }
10575                    if (!needSep) {
10576                        pw.println("  All known processes:");
10577                        needSep = true;
10578                        printedAnything = true;
10579                    }
10580                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10581                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10582                        pw.print(" "); pw.println(r);
10583                    r.dump(pw, "    ");
10584                    if (r.persistent) {
10585                        numPers++;
10586                    }
10587                }
10588            }
10589        }
10590
10591        if (mIsolatedProcesses.size() > 0) {
10592            boolean printed = false;
10593            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10594                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10595                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10596                    continue;
10597                }
10598                if (!printed) {
10599                    if (needSep) {
10600                        pw.println();
10601                    }
10602                    pw.println("  Isolated process list (sorted by uid):");
10603                    printedAnything = true;
10604                    printed = true;
10605                    needSep = true;
10606                }
10607                pw.println(String.format("%sIsolated #%2d: %s",
10608                        "    ", i, r.toString()));
10609            }
10610        }
10611
10612        if (mLruProcesses.size() > 0) {
10613            if (needSep) {
10614                pw.println();
10615            }
10616            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10617                    pw.print(" total, non-act at ");
10618                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10619                    pw.print(", non-svc at ");
10620                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10621                    pw.println("):");
10622            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10623            needSep = true;
10624            printedAnything = true;
10625        }
10626
10627        if (dumpAll || dumpPackage != null) {
10628            synchronized (mPidsSelfLocked) {
10629                boolean printed = false;
10630                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10631                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10632                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10633                        continue;
10634                    }
10635                    if (!printed) {
10636                        if (needSep) pw.println();
10637                        needSep = true;
10638                        pw.println("  PID mappings:");
10639                        printed = true;
10640                        printedAnything = true;
10641                    }
10642                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10643                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10644                }
10645            }
10646        }
10647
10648        if (mForegroundProcesses.size() > 0) {
10649            synchronized (mPidsSelfLocked) {
10650                boolean printed = false;
10651                for (int i=0; i<mForegroundProcesses.size(); i++) {
10652                    ProcessRecord r = mPidsSelfLocked.get(
10653                            mForegroundProcesses.valueAt(i).pid);
10654                    if (dumpPackage != null && (r == null
10655                            || !r.pkgList.containsKey(dumpPackage))) {
10656                        continue;
10657                    }
10658                    if (!printed) {
10659                        if (needSep) pw.println();
10660                        needSep = true;
10661                        pw.println("  Foreground Processes:");
10662                        printed = true;
10663                        printedAnything = true;
10664                    }
10665                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10666                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10667                }
10668            }
10669        }
10670
10671        if (mPersistentStartingProcesses.size() > 0) {
10672            if (needSep) pw.println();
10673            needSep = true;
10674            printedAnything = true;
10675            pw.println("  Persisent processes that are starting:");
10676            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10677                    "Starting Norm", "Restarting PERS", dumpPackage);
10678        }
10679
10680        if (mRemovedProcesses.size() > 0) {
10681            if (needSep) pw.println();
10682            needSep = true;
10683            printedAnything = true;
10684            pw.println("  Processes that are being removed:");
10685            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10686                    "Removed Norm", "Removed PERS", dumpPackage);
10687        }
10688
10689        if (mProcessesOnHold.size() > 0) {
10690            if (needSep) pw.println();
10691            needSep = true;
10692            printedAnything = true;
10693            pw.println("  Processes that are on old until the system is ready:");
10694            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10695                    "OnHold Norm", "OnHold PERS", dumpPackage);
10696        }
10697
10698        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10699
10700        if (mProcessCrashTimes.getMap().size() > 0) {
10701            boolean printed = false;
10702            long now = SystemClock.uptimeMillis();
10703            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10704            final int NP = pmap.size();
10705            for (int ip=0; ip<NP; ip++) {
10706                String pname = pmap.keyAt(ip);
10707                SparseArray<Long> uids = pmap.valueAt(ip);
10708                final int N = uids.size();
10709                for (int i=0; i<N; i++) {
10710                    int puid = uids.keyAt(i);
10711                    ProcessRecord r = mProcessNames.get(pname, puid);
10712                    if (dumpPackage != null && (r == null
10713                            || !r.pkgList.containsKey(dumpPackage))) {
10714                        continue;
10715                    }
10716                    if (!printed) {
10717                        if (needSep) pw.println();
10718                        needSep = true;
10719                        pw.println("  Time since processes crashed:");
10720                        printed = true;
10721                        printedAnything = true;
10722                    }
10723                    pw.print("    Process "); pw.print(pname);
10724                            pw.print(" uid "); pw.print(puid);
10725                            pw.print(": last crashed ");
10726                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10727                            pw.println(" ago");
10728                }
10729            }
10730        }
10731
10732        if (mBadProcesses.getMap().size() > 0) {
10733            boolean printed = false;
10734            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10735            final int NP = pmap.size();
10736            for (int ip=0; ip<NP; ip++) {
10737                String pname = pmap.keyAt(ip);
10738                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10739                final int N = uids.size();
10740                for (int i=0; i<N; i++) {
10741                    int puid = uids.keyAt(i);
10742                    ProcessRecord r = mProcessNames.get(pname, puid);
10743                    if (dumpPackage != null && (r == null
10744                            || !r.pkgList.containsKey(dumpPackage))) {
10745                        continue;
10746                    }
10747                    if (!printed) {
10748                        if (needSep) pw.println();
10749                        needSep = true;
10750                        pw.println("  Bad processes:");
10751                        printedAnything = true;
10752                    }
10753                    BadProcessInfo info = uids.valueAt(i);
10754                    pw.print("    Bad process "); pw.print(pname);
10755                            pw.print(" uid "); pw.print(puid);
10756                            pw.print(": crashed at time "); pw.println(info.time);
10757                    if (info.shortMsg != null) {
10758                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10759                    }
10760                    if (info.longMsg != null) {
10761                        pw.print("      Long msg: "); pw.println(info.longMsg);
10762                    }
10763                    if (info.stack != null) {
10764                        pw.println("      Stack:");
10765                        int lastPos = 0;
10766                        for (int pos=0; pos<info.stack.length(); pos++) {
10767                            if (info.stack.charAt(pos) == '\n') {
10768                                pw.print("        ");
10769                                pw.write(info.stack, lastPos, pos-lastPos);
10770                                pw.println();
10771                                lastPos = pos+1;
10772                            }
10773                        }
10774                        if (lastPos < info.stack.length()) {
10775                            pw.print("        ");
10776                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10777                            pw.println();
10778                        }
10779                    }
10780                }
10781            }
10782        }
10783
10784        if (dumpPackage == null) {
10785            pw.println();
10786            needSep = false;
10787            pw.println("  mStartedUsers:");
10788            for (int i=0; i<mStartedUsers.size(); i++) {
10789                UserStartedState uss = mStartedUsers.valueAt(i);
10790                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10791                        pw.print(": "); uss.dump("", pw);
10792            }
10793            pw.print("  mStartedUserArray: [");
10794            for (int i=0; i<mStartedUserArray.length; i++) {
10795                if (i > 0) pw.print(", ");
10796                pw.print(mStartedUserArray[i]);
10797            }
10798            pw.println("]");
10799            pw.print("  mUserLru: [");
10800            for (int i=0; i<mUserLru.size(); i++) {
10801                if (i > 0) pw.print(", ");
10802                pw.print(mUserLru.get(i));
10803            }
10804            pw.println("]");
10805            if (dumpAll) {
10806                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10807            }
10808        }
10809        if (mHomeProcess != null && (dumpPackage == null
10810                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10811            if (needSep) {
10812                pw.println();
10813                needSep = false;
10814            }
10815            pw.println("  mHomeProcess: " + mHomeProcess);
10816        }
10817        if (mPreviousProcess != null && (dumpPackage == null
10818                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10819            if (needSep) {
10820                pw.println();
10821                needSep = false;
10822            }
10823            pw.println("  mPreviousProcess: " + mPreviousProcess);
10824        }
10825        if (dumpAll) {
10826            StringBuilder sb = new StringBuilder(128);
10827            sb.append("  mPreviousProcessVisibleTime: ");
10828            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10829            pw.println(sb);
10830        }
10831        if (mHeavyWeightProcess != null && (dumpPackage == null
10832                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10833            if (needSep) {
10834                pw.println();
10835                needSep = false;
10836            }
10837            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10838        }
10839        if (dumpPackage == null) {
10840            pw.println("  mConfiguration: " + mConfiguration);
10841        }
10842        if (dumpAll) {
10843            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10844            if (mCompatModePackages.getPackages().size() > 0) {
10845                boolean printed = false;
10846                for (Map.Entry<String, Integer> entry
10847                        : mCompatModePackages.getPackages().entrySet()) {
10848                    String pkg = entry.getKey();
10849                    int mode = entry.getValue();
10850                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10851                        continue;
10852                    }
10853                    if (!printed) {
10854                        pw.println("  mScreenCompatPackages:");
10855                        printed = true;
10856                    }
10857                    pw.print("    "); pw.print(pkg); pw.print(": ");
10858                            pw.print(mode); pw.println();
10859                }
10860            }
10861        }
10862        if (dumpPackage == null) {
10863            if (mSleeping || mWentToSleep || mLockScreenShown) {
10864                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10865                        + " mLockScreenShown " + mLockScreenShown);
10866            }
10867            if (mShuttingDown) {
10868                pw.println("  mShuttingDown=" + mShuttingDown);
10869            }
10870        }
10871        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10872                || mOrigWaitForDebugger) {
10873            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10874                    || dumpPackage.equals(mOrigDebugApp)) {
10875                if (needSep) {
10876                    pw.println();
10877                    needSep = false;
10878                }
10879                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10880                        + " mDebugTransient=" + mDebugTransient
10881                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10882            }
10883        }
10884        if (mOpenGlTraceApp != null) {
10885            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10886                if (needSep) {
10887                    pw.println();
10888                    needSep = false;
10889                }
10890                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10891            }
10892        }
10893        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10894                || mProfileFd != null) {
10895            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10896                if (needSep) {
10897                    pw.println();
10898                    needSep = false;
10899                }
10900                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10901                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10902                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10903                        + mAutoStopProfiler);
10904            }
10905        }
10906        if (dumpPackage == null) {
10907            if (mAlwaysFinishActivities || mController != null) {
10908                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10909                        + " mController=" + mController);
10910            }
10911            if (dumpAll) {
10912                pw.println("  Total persistent processes: " + numPers);
10913                pw.println("  mStartRunning=" + mStartRunning
10914                        + " mProcessesReady=" + mProcessesReady
10915                        + " mSystemReady=" + mSystemReady);
10916                pw.println("  mBooting=" + mBooting
10917                        + " mBooted=" + mBooted
10918                        + " mFactoryTest=" + mFactoryTest);
10919                pw.print("  mLastPowerCheckRealtime=");
10920                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10921                        pw.println("");
10922                pw.print("  mLastPowerCheckUptime=");
10923                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10924                        pw.println("");
10925                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10926                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10927                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10928                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10929                        + " (" + mLruProcesses.size() + " total)"
10930                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10931                        + " mNumServiceProcs=" + mNumServiceProcs
10932                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10933                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10934                        + " mLastMemoryLevel" + mLastMemoryLevel
10935                        + " mLastNumProcesses" + mLastNumProcesses);
10936                long now = SystemClock.uptimeMillis();
10937                pw.print("  mLastIdleTime=");
10938                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10939                        pw.print(" mLowRamSinceLastIdle=");
10940                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10941                        pw.println();
10942            }
10943        }
10944
10945        if (!printedAnything) {
10946            pw.println("  (nothing)");
10947        }
10948    }
10949
10950    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10951            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10952        if (mProcessesToGc.size() > 0) {
10953            boolean printed = false;
10954            long now = SystemClock.uptimeMillis();
10955            for (int i=0; i<mProcessesToGc.size(); i++) {
10956                ProcessRecord proc = mProcessesToGc.get(i);
10957                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10958                    continue;
10959                }
10960                if (!printed) {
10961                    if (needSep) pw.println();
10962                    needSep = true;
10963                    pw.println("  Processes that are waiting to GC:");
10964                    printed = true;
10965                }
10966                pw.print("    Process "); pw.println(proc);
10967                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
10968                        pw.print(", last gced=");
10969                        pw.print(now-proc.lastRequestedGc);
10970                        pw.print(" ms ago, last lowMem=");
10971                        pw.print(now-proc.lastLowMemory);
10972                        pw.println(" ms ago");
10973
10974            }
10975        }
10976        return needSep;
10977    }
10978
10979    void printOomLevel(PrintWriter pw, String name, int adj) {
10980        pw.print("    ");
10981        if (adj >= 0) {
10982            pw.print(' ');
10983            if (adj < 10) pw.print(' ');
10984        } else {
10985            if (adj > -10) pw.print(' ');
10986        }
10987        pw.print(adj);
10988        pw.print(": ");
10989        pw.print(name);
10990        pw.print(" (");
10991        pw.print(mProcessList.getMemLevel(adj)/1024);
10992        pw.println(" kB)");
10993    }
10994
10995    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10996            int opti, boolean dumpAll) {
10997        boolean needSep = false;
10998
10999        if (mLruProcesses.size() > 0) {
11000            if (needSep) pw.println();
11001            needSep = true;
11002            pw.println("  OOM levels:");
11003            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11004            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11005            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11006            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11007            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11008            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11009            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11010            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11011            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11012            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11013            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11014            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11015            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11016
11017            if (needSep) pw.println();
11018            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11019                    pw.print(" total, non-act at ");
11020                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11021                    pw.print(", non-svc at ");
11022                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11023                    pw.println("):");
11024            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11025            needSep = true;
11026        }
11027
11028        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11029
11030        pw.println();
11031        pw.println("  mHomeProcess: " + mHomeProcess);
11032        pw.println("  mPreviousProcess: " + mPreviousProcess);
11033        if (mHeavyWeightProcess != null) {
11034            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11035        }
11036
11037        return true;
11038    }
11039
11040    /**
11041     * There are three ways to call this:
11042     *  - no provider specified: dump all the providers
11043     *  - a flattened component name that matched an existing provider was specified as the
11044     *    first arg: dump that one provider
11045     *  - the first arg isn't the flattened component name of an existing provider:
11046     *    dump all providers whose component contains the first arg as a substring
11047     */
11048    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11049            int opti, boolean dumpAll) {
11050        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11051    }
11052
11053    static class ItemMatcher {
11054        ArrayList<ComponentName> components;
11055        ArrayList<String> strings;
11056        ArrayList<Integer> objects;
11057        boolean all;
11058
11059        ItemMatcher() {
11060            all = true;
11061        }
11062
11063        void build(String name) {
11064            ComponentName componentName = ComponentName.unflattenFromString(name);
11065            if (componentName != null) {
11066                if (components == null) {
11067                    components = new ArrayList<ComponentName>();
11068                }
11069                components.add(componentName);
11070                all = false;
11071            } else {
11072                int objectId = 0;
11073                // Not a '/' separated full component name; maybe an object ID?
11074                try {
11075                    objectId = Integer.parseInt(name, 16);
11076                    if (objects == null) {
11077                        objects = new ArrayList<Integer>();
11078                    }
11079                    objects.add(objectId);
11080                    all = false;
11081                } catch (RuntimeException e) {
11082                    // Not an integer; just do string match.
11083                    if (strings == null) {
11084                        strings = new ArrayList<String>();
11085                    }
11086                    strings.add(name);
11087                    all = false;
11088                }
11089            }
11090        }
11091
11092        int build(String[] args, int opti) {
11093            for (; opti<args.length; opti++) {
11094                String name = args[opti];
11095                if ("--".equals(name)) {
11096                    return opti+1;
11097                }
11098                build(name);
11099            }
11100            return opti;
11101        }
11102
11103        boolean match(Object object, ComponentName comp) {
11104            if (all) {
11105                return true;
11106            }
11107            if (components != null) {
11108                for (int i=0; i<components.size(); i++) {
11109                    if (components.get(i).equals(comp)) {
11110                        return true;
11111                    }
11112                }
11113            }
11114            if (objects != null) {
11115                for (int i=0; i<objects.size(); i++) {
11116                    if (System.identityHashCode(object) == objects.get(i)) {
11117                        return true;
11118                    }
11119                }
11120            }
11121            if (strings != null) {
11122                String flat = comp.flattenToString();
11123                for (int i=0; i<strings.size(); i++) {
11124                    if (flat.contains(strings.get(i))) {
11125                        return true;
11126                    }
11127                }
11128            }
11129            return false;
11130        }
11131    }
11132
11133    /**
11134     * There are three things that cmd can be:
11135     *  - a flattened component name that matches an existing activity
11136     *  - the cmd arg isn't the flattened component name of an existing activity:
11137     *    dump all activity whose component contains the cmd as a substring
11138     *  - A hex number of the ActivityRecord object instance.
11139     */
11140    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11141            int opti, boolean dumpAll) {
11142        ArrayList<ActivityRecord> activities;
11143
11144        synchronized (this) {
11145            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11146        }
11147
11148        if (activities.size() <= 0) {
11149            return false;
11150        }
11151
11152        String[] newArgs = new String[args.length - opti];
11153        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11154
11155        TaskRecord lastTask = null;
11156        boolean needSep = false;
11157        for (int i=activities.size()-1; i>=0; i--) {
11158            ActivityRecord r = activities.get(i);
11159            if (needSep) {
11160                pw.println();
11161            }
11162            needSep = true;
11163            synchronized (this) {
11164                if (lastTask != r.task) {
11165                    lastTask = r.task;
11166                    pw.print("TASK "); pw.print(lastTask.affinity);
11167                            pw.print(" id="); pw.println(lastTask.taskId);
11168                    if (dumpAll) {
11169                        lastTask.dump(pw, "  ");
11170                    }
11171                }
11172            }
11173            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11174        }
11175        return true;
11176    }
11177
11178    /**
11179     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11180     * there is a thread associated with the activity.
11181     */
11182    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11183            final ActivityRecord r, String[] args, boolean dumpAll) {
11184        String innerPrefix = prefix + "  ";
11185        synchronized (this) {
11186            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11187                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11188                    pw.print(" pid=");
11189                    if (r.app != null) pw.println(r.app.pid);
11190                    else pw.println("(not running)");
11191            if (dumpAll) {
11192                r.dump(pw, innerPrefix);
11193            }
11194        }
11195        if (r.app != null && r.app.thread != null) {
11196            // flush anything that is already in the PrintWriter since the thread is going
11197            // to write to the file descriptor directly
11198            pw.flush();
11199            try {
11200                TransferPipe tp = new TransferPipe();
11201                try {
11202                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11203                            r.appToken, innerPrefix, args);
11204                    tp.go(fd);
11205                } finally {
11206                    tp.kill();
11207                }
11208            } catch (IOException e) {
11209                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11210            } catch (RemoteException e) {
11211                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11212            }
11213        }
11214    }
11215
11216    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11217            int opti, boolean dumpAll, String dumpPackage) {
11218        boolean needSep = false;
11219        boolean onlyHistory = false;
11220        boolean printedAnything = false;
11221
11222        if ("history".equals(dumpPackage)) {
11223            if (opti < args.length && "-s".equals(args[opti])) {
11224                dumpAll = false;
11225            }
11226            onlyHistory = true;
11227            dumpPackage = null;
11228        }
11229
11230        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11231        if (!onlyHistory && dumpAll) {
11232            if (mRegisteredReceivers.size() > 0) {
11233                boolean printed = false;
11234                Iterator it = mRegisteredReceivers.values().iterator();
11235                while (it.hasNext()) {
11236                    ReceiverList r = (ReceiverList)it.next();
11237                    if (dumpPackage != null && (r.app == null ||
11238                            !dumpPackage.equals(r.app.info.packageName))) {
11239                        continue;
11240                    }
11241                    if (!printed) {
11242                        pw.println("  Registered Receivers:");
11243                        needSep = true;
11244                        printed = true;
11245                        printedAnything = true;
11246                    }
11247                    pw.print("  * "); pw.println(r);
11248                    r.dump(pw, "    ");
11249                }
11250            }
11251
11252            if (mReceiverResolver.dump(pw, needSep ?
11253                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11254                    "    ", dumpPackage, false)) {
11255                needSep = true;
11256                printedAnything = true;
11257            }
11258        }
11259
11260        for (BroadcastQueue q : mBroadcastQueues) {
11261            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11262            printedAnything |= needSep;
11263        }
11264
11265        needSep = true;
11266
11267        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11268            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11269                if (needSep) {
11270                    pw.println();
11271                }
11272                needSep = true;
11273                printedAnything = true;
11274                pw.print("  Sticky broadcasts for user ");
11275                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11276                StringBuilder sb = new StringBuilder(128);
11277                for (Map.Entry<String, ArrayList<Intent>> ent
11278                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11279                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11280                    if (dumpAll) {
11281                        pw.println(":");
11282                        ArrayList<Intent> intents = ent.getValue();
11283                        final int N = intents.size();
11284                        for (int i=0; i<N; i++) {
11285                            sb.setLength(0);
11286                            sb.append("    Intent: ");
11287                            intents.get(i).toShortString(sb, false, true, false, false);
11288                            pw.println(sb.toString());
11289                            Bundle bundle = intents.get(i).getExtras();
11290                            if (bundle != null) {
11291                                pw.print("      ");
11292                                pw.println(bundle.toString());
11293                            }
11294                        }
11295                    } else {
11296                        pw.println("");
11297                    }
11298                }
11299            }
11300        }
11301
11302        if (!onlyHistory && dumpAll) {
11303            pw.println();
11304            for (BroadcastQueue queue : mBroadcastQueues) {
11305                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11306                        + queue.mBroadcastsScheduled);
11307            }
11308            pw.println("  mHandler:");
11309            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11310            needSep = true;
11311            printedAnything = true;
11312        }
11313
11314        if (!printedAnything) {
11315            pw.println("  (nothing)");
11316        }
11317    }
11318
11319    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11320            int opti, boolean dumpAll, String dumpPackage) {
11321        boolean needSep;
11322        boolean printedAnything = false;
11323
11324        ItemMatcher matcher = new ItemMatcher();
11325        matcher.build(args, opti);
11326
11327        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11328
11329        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11330        printedAnything |= needSep;
11331
11332        if (mLaunchingProviders.size() > 0) {
11333            boolean printed = false;
11334            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11335                ContentProviderRecord r = mLaunchingProviders.get(i);
11336                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11337                    continue;
11338                }
11339                if (!printed) {
11340                    if (needSep) pw.println();
11341                    needSep = true;
11342                    pw.println("  Launching content providers:");
11343                    printed = true;
11344                    printedAnything = true;
11345                }
11346                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11347                        pw.println(r);
11348            }
11349        }
11350
11351        if (mGrantedUriPermissions.size() > 0) {
11352            boolean printed = false;
11353            int dumpUid = -2;
11354            if (dumpPackage != null) {
11355                try {
11356                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11357                } catch (NameNotFoundException e) {
11358                    dumpUid = -1;
11359                }
11360            }
11361            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11362                int uid = mGrantedUriPermissions.keyAt(i);
11363                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11364                    continue;
11365                }
11366                ArrayMap<Uri, UriPermission> perms
11367                        = mGrantedUriPermissions.valueAt(i);
11368                if (!printed) {
11369                    if (needSep) pw.println();
11370                    needSep = true;
11371                    pw.println("  Granted Uri Permissions:");
11372                    printed = true;
11373                    printedAnything = true;
11374                }
11375                pw.print("  * UID "); pw.print(uid);
11376                        pw.println(" holds:");
11377                for (UriPermission perm : perms.values()) {
11378                    pw.print("    "); pw.println(perm);
11379                    if (dumpAll) {
11380                        perm.dump(pw, "      ");
11381                    }
11382                }
11383            }
11384        }
11385
11386        if (!printedAnything) {
11387            pw.println("  (nothing)");
11388        }
11389    }
11390
11391    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11392            int opti, boolean dumpAll, String dumpPackage) {
11393        boolean printed = false;
11394
11395        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11396
11397        if (mIntentSenderRecords.size() > 0) {
11398            Iterator<WeakReference<PendingIntentRecord>> it
11399                    = mIntentSenderRecords.values().iterator();
11400            while (it.hasNext()) {
11401                WeakReference<PendingIntentRecord> ref = it.next();
11402                PendingIntentRecord rec = ref != null ? ref.get(): null;
11403                if (dumpPackage != null && (rec == null
11404                        || !dumpPackage.equals(rec.key.packageName))) {
11405                    continue;
11406                }
11407                printed = true;
11408                if (rec != null) {
11409                    pw.print("  * "); pw.println(rec);
11410                    if (dumpAll) {
11411                        rec.dump(pw, "    ");
11412                    }
11413                } else {
11414                    pw.print("  * "); pw.println(ref);
11415                }
11416            }
11417        }
11418
11419        if (!printed) {
11420            pw.println("  (nothing)");
11421        }
11422    }
11423
11424    private static final int dumpProcessList(PrintWriter pw,
11425            ActivityManagerService service, List list,
11426            String prefix, String normalLabel, String persistentLabel,
11427            String dumpPackage) {
11428        int numPers = 0;
11429        final int N = list.size()-1;
11430        for (int i=N; i>=0; i--) {
11431            ProcessRecord r = (ProcessRecord)list.get(i);
11432            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11433                continue;
11434            }
11435            pw.println(String.format("%s%s #%2d: %s",
11436                    prefix, (r.persistent ? persistentLabel : normalLabel),
11437                    i, r.toString()));
11438            if (r.persistent) {
11439                numPers++;
11440            }
11441        }
11442        return numPers;
11443    }
11444
11445    private static final boolean dumpProcessOomList(PrintWriter pw,
11446            ActivityManagerService service, List<ProcessRecord> origList,
11447            String prefix, String normalLabel, String persistentLabel,
11448            boolean inclDetails, String dumpPackage) {
11449
11450        ArrayList<Pair<ProcessRecord, Integer>> list
11451                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11452        for (int i=0; i<origList.size(); i++) {
11453            ProcessRecord r = origList.get(i);
11454            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11455                continue;
11456            }
11457            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11458        }
11459
11460        if (list.size() <= 0) {
11461            return false;
11462        }
11463
11464        Comparator<Pair<ProcessRecord, Integer>> comparator
11465                = new Comparator<Pair<ProcessRecord, Integer>>() {
11466            @Override
11467            public int compare(Pair<ProcessRecord, Integer> object1,
11468                    Pair<ProcessRecord, Integer> object2) {
11469                if (object1.first.setAdj != object2.first.setAdj) {
11470                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11471                }
11472                if (object1.second.intValue() != object2.second.intValue()) {
11473                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11474                }
11475                return 0;
11476            }
11477        };
11478
11479        Collections.sort(list, comparator);
11480
11481        final long curRealtime = SystemClock.elapsedRealtime();
11482        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11483        final long curUptime = SystemClock.uptimeMillis();
11484        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11485
11486        for (int i=list.size()-1; i>=0; i--) {
11487            ProcessRecord r = list.get(i).first;
11488            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11489            char schedGroup;
11490            switch (r.setSchedGroup) {
11491                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11492                    schedGroup = 'B';
11493                    break;
11494                case Process.THREAD_GROUP_DEFAULT:
11495                    schedGroup = 'F';
11496                    break;
11497                default:
11498                    schedGroup = '?';
11499                    break;
11500            }
11501            char foreground;
11502            if (r.foregroundActivities) {
11503                foreground = 'A';
11504            } else if (r.foregroundServices) {
11505                foreground = 'S';
11506            } else {
11507                foreground = ' ';
11508            }
11509            String procState = ProcessList.makeProcStateString(r.curProcState);
11510            pw.print(prefix);
11511            pw.print(r.persistent ? persistentLabel : normalLabel);
11512            pw.print(" #");
11513            int num = (origList.size()-1)-list.get(i).second;
11514            if (num < 10) pw.print(' ');
11515            pw.print(num);
11516            pw.print(": ");
11517            pw.print(oomAdj);
11518            pw.print(' ');
11519            pw.print(schedGroup);
11520            pw.print('/');
11521            pw.print(foreground);
11522            pw.print('/');
11523            pw.print(procState);
11524            pw.print(" trm:");
11525            if (r.trimMemoryLevel < 10) pw.print(' ');
11526            pw.print(r.trimMemoryLevel);
11527            pw.print(' ');
11528            pw.print(r.toShortString());
11529            pw.print(" (");
11530            pw.print(r.adjType);
11531            pw.println(')');
11532            if (r.adjSource != null || r.adjTarget != null) {
11533                pw.print(prefix);
11534                pw.print("    ");
11535                if (r.adjTarget instanceof ComponentName) {
11536                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11537                } else if (r.adjTarget != null) {
11538                    pw.print(r.adjTarget.toString());
11539                } else {
11540                    pw.print("{null}");
11541                }
11542                pw.print("<=");
11543                if (r.adjSource instanceof ProcessRecord) {
11544                    pw.print("Proc{");
11545                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11546                    pw.println("}");
11547                } else if (r.adjSource != null) {
11548                    pw.println(r.adjSource.toString());
11549                } else {
11550                    pw.println("{null}");
11551                }
11552            }
11553            if (inclDetails) {
11554                pw.print(prefix);
11555                pw.print("    ");
11556                pw.print("oom: max="); pw.print(r.maxAdj);
11557                pw.print(" curRaw="); pw.print(r.curRawAdj);
11558                pw.print(" setRaw="); pw.print(r.setRawAdj);
11559                pw.print(" cur="); pw.print(r.curAdj);
11560                pw.print(" set="); pw.println(r.setAdj);
11561                pw.print(prefix);
11562                pw.print("    ");
11563                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11564                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11565                pw.print(" lastPss="); pw.print(r.lastPss);
11566                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11567                pw.print(prefix);
11568                pw.print("    ");
11569                pw.print("keeping="); pw.print(r.keeping);
11570                pw.print(" cached="); pw.print(r.cached);
11571                pw.print(" empty="); pw.print(r.empty);
11572                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11573
11574                if (!r.keeping) {
11575                    if (r.lastWakeTime != 0) {
11576                        long wtime;
11577                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11578                        synchronized (stats) {
11579                            wtime = stats.getProcessWakeTime(r.info.uid,
11580                                    r.pid, curRealtime);
11581                        }
11582                        long timeUsed = wtime - r.lastWakeTime;
11583                        pw.print(prefix);
11584                        pw.print("    ");
11585                        pw.print("keep awake over ");
11586                        TimeUtils.formatDuration(realtimeSince, pw);
11587                        pw.print(" used ");
11588                        TimeUtils.formatDuration(timeUsed, pw);
11589                        pw.print(" (");
11590                        pw.print((timeUsed*100)/realtimeSince);
11591                        pw.println("%)");
11592                    }
11593                    if (r.lastCpuTime != 0) {
11594                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11595                        pw.print(prefix);
11596                        pw.print("    ");
11597                        pw.print("run cpu over ");
11598                        TimeUtils.formatDuration(uptimeSince, pw);
11599                        pw.print(" used ");
11600                        TimeUtils.formatDuration(timeUsed, pw);
11601                        pw.print(" (");
11602                        pw.print((timeUsed*100)/uptimeSince);
11603                        pw.println("%)");
11604                    }
11605                }
11606            }
11607        }
11608        return true;
11609    }
11610
11611    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11612        ArrayList<ProcessRecord> procs;
11613        synchronized (this) {
11614            if (args != null && args.length > start
11615                    && args[start].charAt(0) != '-') {
11616                procs = new ArrayList<ProcessRecord>();
11617                int pid = -1;
11618                try {
11619                    pid = Integer.parseInt(args[start]);
11620                } catch (NumberFormatException e) {
11621                }
11622                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11623                    ProcessRecord proc = mLruProcesses.get(i);
11624                    if (proc.pid == pid) {
11625                        procs.add(proc);
11626                    } else if (proc.processName.equals(args[start])) {
11627                        procs.add(proc);
11628                    }
11629                }
11630                if (procs.size() <= 0) {
11631                    return null;
11632                }
11633            } else {
11634                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11635            }
11636        }
11637        return procs;
11638    }
11639
11640    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11641            PrintWriter pw, String[] args) {
11642        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11643        if (procs == null) {
11644            pw.println("No process found for: " + args[0]);
11645            return;
11646        }
11647
11648        long uptime = SystemClock.uptimeMillis();
11649        long realtime = SystemClock.elapsedRealtime();
11650        pw.println("Applications Graphics Acceleration Info:");
11651        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11652
11653        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11654            ProcessRecord r = procs.get(i);
11655            if (r.thread != null) {
11656                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11657                pw.flush();
11658                try {
11659                    TransferPipe tp = new TransferPipe();
11660                    try {
11661                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11662                        tp.go(fd);
11663                    } finally {
11664                        tp.kill();
11665                    }
11666                } catch (IOException e) {
11667                    pw.println("Failure while dumping the app: " + r);
11668                    pw.flush();
11669                } catch (RemoteException e) {
11670                    pw.println("Got a RemoteException while dumping the app " + r);
11671                    pw.flush();
11672                }
11673            }
11674        }
11675    }
11676
11677    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11678        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11679        if (procs == null) {
11680            pw.println("No process found for: " + args[0]);
11681            return;
11682        }
11683
11684        pw.println("Applications Database Info:");
11685
11686        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11687            ProcessRecord r = procs.get(i);
11688            if (r.thread != null) {
11689                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11690                pw.flush();
11691                try {
11692                    TransferPipe tp = new TransferPipe();
11693                    try {
11694                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11695                        tp.go(fd);
11696                    } finally {
11697                        tp.kill();
11698                    }
11699                } catch (IOException e) {
11700                    pw.println("Failure while dumping the app: " + r);
11701                    pw.flush();
11702                } catch (RemoteException e) {
11703                    pw.println("Got a RemoteException while dumping the app " + r);
11704                    pw.flush();
11705                }
11706            }
11707        }
11708    }
11709
11710    final static class MemItem {
11711        final boolean isProc;
11712        final String label;
11713        final String shortLabel;
11714        final long pss;
11715        final int id;
11716        final boolean hasActivities;
11717        ArrayList<MemItem> subitems;
11718
11719        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11720                boolean _hasActivities) {
11721            isProc = true;
11722            label = _label;
11723            shortLabel = _shortLabel;
11724            pss = _pss;
11725            id = _id;
11726            hasActivities = _hasActivities;
11727        }
11728
11729        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11730            isProc = false;
11731            label = _label;
11732            shortLabel = _shortLabel;
11733            pss = _pss;
11734            id = _id;
11735            hasActivities = false;
11736        }
11737    }
11738
11739    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11740            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11741        if (sort && !isCompact) {
11742            Collections.sort(items, new Comparator<MemItem>() {
11743                @Override
11744                public int compare(MemItem lhs, MemItem rhs) {
11745                    if (lhs.pss < rhs.pss) {
11746                        return 1;
11747                    } else if (lhs.pss > rhs.pss) {
11748                        return -1;
11749                    }
11750                    return 0;
11751                }
11752            });
11753        }
11754
11755        for (int i=0; i<items.size(); i++) {
11756            MemItem mi = items.get(i);
11757            if (!isCompact) {
11758                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11759            } else if (mi.isProc) {
11760                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11761                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11762                pw.println(mi.hasActivities ? ",a" : ",e");
11763            } else {
11764                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11765                pw.println(mi.pss);
11766            }
11767            if (mi.subitems != null) {
11768                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11769                        true, isCompact);
11770            }
11771        }
11772    }
11773
11774    // These are in KB.
11775    static final long[] DUMP_MEM_BUCKETS = new long[] {
11776        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11777        120*1024, 160*1024, 200*1024,
11778        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11779        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11780    };
11781
11782    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11783            boolean stackLike) {
11784        int start = label.lastIndexOf('.');
11785        if (start >= 0) start++;
11786        else start = 0;
11787        int end = label.length();
11788        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11789            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11790                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11791                out.append(bucket);
11792                out.append(stackLike ? "MB." : "MB ");
11793                out.append(label, start, end);
11794                return;
11795            }
11796        }
11797        out.append(memKB/1024);
11798        out.append(stackLike ? "MB." : "MB ");
11799        out.append(label, start, end);
11800    }
11801
11802    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11803            ProcessList.NATIVE_ADJ,
11804            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11805            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11806            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11807            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11808            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11809    };
11810    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11811            "Native",
11812            "System", "Persistent", "Foreground",
11813            "Visible", "Perceptible",
11814            "Heavy Weight", "Backup",
11815            "A Services", "Home",
11816            "Previous", "B Services", "Cached"
11817    };
11818    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11819            "native",
11820            "sys", "pers", "fore",
11821            "vis", "percept",
11822            "heavy", "backup",
11823            "servicea", "home",
11824            "prev", "serviceb", "cached"
11825    };
11826
11827    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11828            long realtime, boolean isCheckinRequest, boolean isCompact) {
11829        if (isCheckinRequest || isCompact) {
11830            // short checkin version
11831            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11832        } else {
11833            pw.println("Applications Memory Usage (kB):");
11834            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11835        }
11836    }
11837
11838    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11839            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11840        boolean dumpDetails = false;
11841        boolean dumpFullDetails = false;
11842        boolean dumpDalvik = false;
11843        boolean oomOnly = false;
11844        boolean isCompact = false;
11845        boolean localOnly = false;
11846
11847        int opti = 0;
11848        while (opti < args.length) {
11849            String opt = args[opti];
11850            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11851                break;
11852            }
11853            opti++;
11854            if ("-a".equals(opt)) {
11855                dumpDetails = true;
11856                dumpFullDetails = true;
11857                dumpDalvik = true;
11858            } else if ("-d".equals(opt)) {
11859                dumpDalvik = true;
11860            } else if ("-c".equals(opt)) {
11861                isCompact = true;
11862            } else if ("--oom".equals(opt)) {
11863                oomOnly = true;
11864            } else if ("--local".equals(opt)) {
11865                localOnly = true;
11866            } else if ("-h".equals(opt)) {
11867                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11868                pw.println("  -a: include all available information for each process.");
11869                pw.println("  -d: include dalvik details when dumping process details.");
11870                pw.println("  -c: dump in a compact machine-parseable representation.");
11871                pw.println("  --oom: only show processes organized by oom adj.");
11872                pw.println("  --local: only collect details locally, don't call process.");
11873                pw.println("If [process] is specified it can be the name or ");
11874                pw.println("pid of a specific process to dump.");
11875                return;
11876            } else {
11877                pw.println("Unknown argument: " + opt + "; use -h for help");
11878            }
11879        }
11880
11881        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11882        long uptime = SystemClock.uptimeMillis();
11883        long realtime = SystemClock.elapsedRealtime();
11884        final long[] tmpLong = new long[1];
11885
11886        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11887        if (procs == null) {
11888            // No Java processes.  Maybe they want to print a native process.
11889            if (args != null && args.length > opti
11890                    && args[opti].charAt(0) != '-') {
11891                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11892                        = new ArrayList<ProcessCpuTracker.Stats>();
11893                updateCpuStatsNow();
11894                int findPid = -1;
11895                try {
11896                    findPid = Integer.parseInt(args[opti]);
11897                } catch (NumberFormatException e) {
11898                }
11899                synchronized (mProcessCpuThread) {
11900                    final int N = mProcessCpuTracker.countStats();
11901                    for (int i=0; i<N; i++) {
11902                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11903                        if (st.pid == findPid || (st.baseName != null
11904                                && st.baseName.equals(args[opti]))) {
11905                            nativeProcs.add(st);
11906                        }
11907                    }
11908                }
11909                if (nativeProcs.size() > 0) {
11910                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11911                            isCompact);
11912                    Debug.MemoryInfo mi = null;
11913                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11914                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11915                        final int pid = r.pid;
11916                        if (!isCheckinRequest && dumpDetails) {
11917                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11918                        }
11919                        if (mi == null) {
11920                            mi = new Debug.MemoryInfo();
11921                        }
11922                        if (dumpDetails || (!brief && !oomOnly)) {
11923                            Debug.getMemoryInfo(pid, mi);
11924                        } else {
11925                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11926                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11927                        }
11928                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11929                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11930                        if (isCheckinRequest) {
11931                            pw.println();
11932                        }
11933                    }
11934                    return;
11935                }
11936            }
11937            pw.println("No process found for: " + args[opti]);
11938            return;
11939        }
11940
11941        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11942            dumpDetails = true;
11943        }
11944
11945        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11946
11947        String[] innerArgs = new String[args.length-opti];
11948        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11949
11950        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11951        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11952        long nativePss=0, dalvikPss=0, otherPss=0;
11953        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11954
11955        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11956        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11957                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11958
11959        long totalPss = 0;
11960        long cachedPss = 0;
11961
11962        Debug.MemoryInfo mi = null;
11963        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11964            final ProcessRecord r = procs.get(i);
11965            final IApplicationThread thread;
11966            final int pid;
11967            final int oomAdj;
11968            final boolean hasActivities;
11969            synchronized (this) {
11970                thread = r.thread;
11971                pid = r.pid;
11972                oomAdj = r.getSetAdjWithServices();
11973                hasActivities = r.activities.size() > 0;
11974            }
11975            if (thread != null) {
11976                if (!isCheckinRequest && dumpDetails) {
11977                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
11978                }
11979                if (mi == null) {
11980                    mi = new Debug.MemoryInfo();
11981                }
11982                if (dumpDetails || (!brief && !oomOnly)) {
11983                    Debug.getMemoryInfo(pid, mi);
11984                } else {
11985                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11986                    mi.dalvikPrivateDirty = (int)tmpLong[0];
11987                }
11988                if (dumpDetails) {
11989                    if (localOnly) {
11990                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11991                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
11992                        if (isCheckinRequest) {
11993                            pw.println();
11994                        }
11995                    } else {
11996                        try {
11997                            pw.flush();
11998                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
11999                                    dumpDalvik, innerArgs);
12000                        } catch (RemoteException e) {
12001                            if (!isCheckinRequest) {
12002                                pw.println("Got RemoteException!");
12003                                pw.flush();
12004                            }
12005                        }
12006                    }
12007                }
12008
12009                final long myTotalPss = mi.getTotalPss();
12010                final long myTotalUss = mi.getTotalUss();
12011
12012                synchronized (this) {
12013                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12014                        // Record this for posterity if the process has been stable.
12015                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12016                    }
12017                }
12018
12019                if (!isCheckinRequest && mi != null) {
12020                    totalPss += myTotalPss;
12021                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12022                            (hasActivities ? " / activities)" : ")"),
12023                            r.processName, myTotalPss, pid, hasActivities);
12024                    procMems.add(pssItem);
12025                    procMemsMap.put(pid, pssItem);
12026
12027                    nativePss += mi.nativePss;
12028                    dalvikPss += mi.dalvikPss;
12029                    otherPss += mi.otherPss;
12030                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12031                        long mem = mi.getOtherPss(j);
12032                        miscPss[j] += mem;
12033                        otherPss -= mem;
12034                    }
12035
12036                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12037                        cachedPss += myTotalPss;
12038                    }
12039
12040                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12041                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12042                                || oomIndex == (oomPss.length-1)) {
12043                            oomPss[oomIndex] += myTotalPss;
12044                            if (oomProcs[oomIndex] == null) {
12045                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12046                            }
12047                            oomProcs[oomIndex].add(pssItem);
12048                            break;
12049                        }
12050                    }
12051                }
12052            }
12053        }
12054
12055        if (!isCheckinRequest && procs.size() > 1) {
12056            // If we are showing aggregations, also look for native processes to
12057            // include so that our aggregations are more accurate.
12058            updateCpuStatsNow();
12059            synchronized (mProcessCpuThread) {
12060                final int N = mProcessCpuTracker.countStats();
12061                for (int i=0; i<N; i++) {
12062                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12063                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12064                        if (mi == null) {
12065                            mi = new Debug.MemoryInfo();
12066                        }
12067                        if (!brief && !oomOnly) {
12068                            Debug.getMemoryInfo(st.pid, mi);
12069                        } else {
12070                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12071                            mi.nativePrivateDirty = (int)tmpLong[0];
12072                        }
12073
12074                        final long myTotalPss = mi.getTotalPss();
12075                        totalPss += myTotalPss;
12076
12077                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12078                                st.name, myTotalPss, st.pid, false);
12079                        procMems.add(pssItem);
12080
12081                        nativePss += mi.nativePss;
12082                        dalvikPss += mi.dalvikPss;
12083                        otherPss += mi.otherPss;
12084                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12085                            long mem = mi.getOtherPss(j);
12086                            miscPss[j] += mem;
12087                            otherPss -= mem;
12088                        }
12089                        oomPss[0] += myTotalPss;
12090                        if (oomProcs[0] == null) {
12091                            oomProcs[0] = new ArrayList<MemItem>();
12092                        }
12093                        oomProcs[0].add(pssItem);
12094                    }
12095                }
12096            }
12097
12098            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12099
12100            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12101            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12102            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12103            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12104                String label = Debug.MemoryInfo.getOtherLabel(j);
12105                catMems.add(new MemItem(label, label, miscPss[j], j));
12106            }
12107
12108            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12109            for (int j=0; j<oomPss.length; j++) {
12110                if (oomPss[j] != 0) {
12111                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12112                            : DUMP_MEM_OOM_LABEL[j];
12113                    MemItem item = new MemItem(label, label, oomPss[j],
12114                            DUMP_MEM_OOM_ADJ[j]);
12115                    item.subitems = oomProcs[j];
12116                    oomMems.add(item);
12117                }
12118            }
12119
12120            if (!brief && !oomOnly && !isCompact) {
12121                pw.println();
12122                pw.println("Total PSS by process:");
12123                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12124                pw.println();
12125            }
12126            if (!isCompact) {
12127                pw.println("Total PSS by OOM adjustment:");
12128            }
12129            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12130            if (!brief && !oomOnly) {
12131                PrintWriter out = categoryPw != null ? categoryPw : pw;
12132                if (!isCompact) {
12133                    out.println();
12134                    out.println("Total PSS by category:");
12135                }
12136                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12137            }
12138            if (!isCompact) {
12139                pw.println();
12140            }
12141            MemInfoReader memInfo = new MemInfoReader();
12142            memInfo.readMemInfo();
12143            if (!brief) {
12144                if (!isCompact) {
12145                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12146                    pw.println(" kB");
12147                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12148                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12149                            pw.print(cachedPss); pw.print(" cached pss + ");
12150                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12151                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12152                } else {
12153                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12154                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12155                            + memInfo.getFreeSizeKb()); pw.print(",");
12156                    pw.println(totalPss - cachedPss);
12157                }
12158            }
12159            if (!isCompact) {
12160                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12161                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12162                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12163                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12164                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12165                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12166                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12167                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12168                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12169                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12170                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12171            }
12172            if (!brief) {
12173                if (memInfo.getZramTotalSizeKb() != 0) {
12174                    if (!isCompact) {
12175                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12176                                pw.print(" kB physical used for ");
12177                                pw.print(memInfo.getSwapTotalSizeKb()
12178                                        - memInfo.getSwapFreeSizeKb());
12179                                pw.print(" kB in swap (");
12180                                pw.print(memInfo.getSwapTotalSizeKb());
12181                                pw.println(" kB total swap)");
12182                    } else {
12183                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12184                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12185                                pw.println(memInfo.getSwapFreeSizeKb());
12186                    }
12187                }
12188                final int[] SINGLE_LONG_FORMAT = new int[] {
12189                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12190                };
12191                long[] longOut = new long[1];
12192                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12193                        SINGLE_LONG_FORMAT, null, longOut, null);
12194                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12195                longOut[0] = 0;
12196                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12197                        SINGLE_LONG_FORMAT, null, longOut, null);
12198                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12199                longOut[0] = 0;
12200                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12201                        SINGLE_LONG_FORMAT, null, longOut, null);
12202                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12203                longOut[0] = 0;
12204                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12205                        SINGLE_LONG_FORMAT, null, longOut, null);
12206                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12207                if (!isCompact) {
12208                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12209                        pw.print("      KSM: "); pw.print(sharing);
12210                                pw.print(" kB saved from shared ");
12211                                pw.print(shared); pw.println(" kB");
12212                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12213                                pw.print(voltile); pw.println(" kB volatile");
12214                    }
12215                    pw.print("   Tuning: ");
12216                    pw.print(ActivityManager.staticGetMemoryClass());
12217                    pw.print(" (large ");
12218                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12219                    pw.print("), oom ");
12220                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12221                    pw.print(" kB");
12222                    pw.print(", restore limit ");
12223                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12224                    pw.print(" kB");
12225                    if (ActivityManager.isLowRamDeviceStatic()) {
12226                        pw.print(" (low-ram)");
12227                    }
12228                    if (ActivityManager.isHighEndGfx()) {
12229                        pw.print(" (high-end-gfx)");
12230                    }
12231                    pw.println();
12232                } else {
12233                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12234                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12235                    pw.println(voltile);
12236                    pw.print("tuning,");
12237                    pw.print(ActivityManager.staticGetMemoryClass());
12238                    pw.print(',');
12239                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12240                    pw.print(',');
12241                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12242                    if (ActivityManager.isLowRamDeviceStatic()) {
12243                        pw.print(",low-ram");
12244                    }
12245                    if (ActivityManager.isHighEndGfx()) {
12246                        pw.print(",high-end-gfx");
12247                    }
12248                    pw.println();
12249                }
12250            }
12251        }
12252    }
12253
12254    /**
12255     * Searches array of arguments for the specified string
12256     * @param args array of argument strings
12257     * @param value value to search for
12258     * @return true if the value is contained in the array
12259     */
12260    private static boolean scanArgs(String[] args, String value) {
12261        if (args != null) {
12262            for (String arg : args) {
12263                if (value.equals(arg)) {
12264                    return true;
12265                }
12266            }
12267        }
12268        return false;
12269    }
12270
12271    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12272            ContentProviderRecord cpr, boolean always) {
12273        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12274
12275        if (!inLaunching || always) {
12276            synchronized (cpr) {
12277                cpr.launchingApp = null;
12278                cpr.notifyAll();
12279            }
12280            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12281            String names[] = cpr.info.authority.split(";");
12282            for (int j = 0; j < names.length; j++) {
12283                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12284            }
12285        }
12286
12287        for (int i=0; i<cpr.connections.size(); i++) {
12288            ContentProviderConnection conn = cpr.connections.get(i);
12289            if (conn.waiting) {
12290                // If this connection is waiting for the provider, then we don't
12291                // need to mess with its process unless we are always removing
12292                // or for some reason the provider is not currently launching.
12293                if (inLaunching && !always) {
12294                    continue;
12295                }
12296            }
12297            ProcessRecord capp = conn.client;
12298            conn.dead = true;
12299            if (conn.stableCount > 0) {
12300                if (!capp.persistent && capp.thread != null
12301                        && capp.pid != 0
12302                        && capp.pid != MY_PID) {
12303                    killUnneededProcessLocked(capp, "depends on provider "
12304                            + cpr.name.flattenToShortString()
12305                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12306                }
12307            } else if (capp.thread != null && conn.provider.provider != null) {
12308                try {
12309                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12310                } catch (RemoteException e) {
12311                }
12312                // In the protocol here, we don't expect the client to correctly
12313                // clean up this connection, we'll just remove it.
12314                cpr.connections.remove(i);
12315                conn.client.conProviders.remove(conn);
12316            }
12317        }
12318
12319        if (inLaunching && always) {
12320            mLaunchingProviders.remove(cpr);
12321        }
12322        return inLaunching;
12323    }
12324
12325    /**
12326     * Main code for cleaning up a process when it has gone away.  This is
12327     * called both as a result of the process dying, or directly when stopping
12328     * a process when running in single process mode.
12329     */
12330    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12331            boolean restarting, boolean allowRestart, int index) {
12332        if (index >= 0) {
12333            removeLruProcessLocked(app);
12334        }
12335
12336        mProcessesToGc.remove(app);
12337        mPendingPssProcesses.remove(app);
12338
12339        // Dismiss any open dialogs.
12340        if (app.crashDialog != null && !app.forceCrashReport) {
12341            app.crashDialog.dismiss();
12342            app.crashDialog = null;
12343        }
12344        if (app.anrDialog != null) {
12345            app.anrDialog.dismiss();
12346            app.anrDialog = null;
12347        }
12348        if (app.waitDialog != null) {
12349            app.waitDialog.dismiss();
12350            app.waitDialog = null;
12351        }
12352
12353        app.crashing = false;
12354        app.notResponding = false;
12355
12356        app.resetPackageList(mProcessStats);
12357        app.unlinkDeathRecipient();
12358        app.makeInactive(mProcessStats);
12359        app.forcingToForeground = null;
12360        app.foregroundServices = false;
12361        app.foregroundActivities = false;
12362        app.hasShownUi = false;
12363        app.hasAboveClient = false;
12364
12365        mServices.killServicesLocked(app, allowRestart);
12366
12367        boolean restart = false;
12368
12369        // Remove published content providers.
12370        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12371            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12372            final boolean always = app.bad || !allowRestart;
12373            if (removeDyingProviderLocked(app, cpr, always) || always) {
12374                // We left the provider in the launching list, need to
12375                // restart it.
12376                restart = true;
12377            }
12378
12379            cpr.provider = null;
12380            cpr.proc = null;
12381        }
12382        app.pubProviders.clear();
12383
12384        // Take care of any launching providers waiting for this process.
12385        if (checkAppInLaunchingProvidersLocked(app, false)) {
12386            restart = true;
12387        }
12388
12389        // Unregister from connected content providers.
12390        if (!app.conProviders.isEmpty()) {
12391            for (int i=0; i<app.conProviders.size(); i++) {
12392                ContentProviderConnection conn = app.conProviders.get(i);
12393                conn.provider.connections.remove(conn);
12394            }
12395            app.conProviders.clear();
12396        }
12397
12398        // At this point there may be remaining entries in mLaunchingProviders
12399        // where we were the only one waiting, so they are no longer of use.
12400        // Look for these and clean up if found.
12401        // XXX Commented out for now.  Trying to figure out a way to reproduce
12402        // the actual situation to identify what is actually going on.
12403        if (false) {
12404            for (int i=0; i<mLaunchingProviders.size(); i++) {
12405                ContentProviderRecord cpr = (ContentProviderRecord)
12406                        mLaunchingProviders.get(i);
12407                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12408                    synchronized (cpr) {
12409                        cpr.launchingApp = null;
12410                        cpr.notifyAll();
12411                    }
12412                }
12413            }
12414        }
12415
12416        skipCurrentReceiverLocked(app);
12417
12418        // Unregister any receivers.
12419        for (int i=app.receivers.size()-1; i>=0; i--) {
12420            removeReceiverLocked(app.receivers.valueAt(i));
12421        }
12422        app.receivers.clear();
12423
12424        // If the app is undergoing backup, tell the backup manager about it
12425        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12426            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12427                    + mBackupTarget.appInfo + " died during backup");
12428            try {
12429                IBackupManager bm = IBackupManager.Stub.asInterface(
12430                        ServiceManager.getService(Context.BACKUP_SERVICE));
12431                bm.agentDisconnected(app.info.packageName);
12432            } catch (RemoteException e) {
12433                // can't happen; backup manager is local
12434            }
12435        }
12436
12437        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12438            ProcessChangeItem item = mPendingProcessChanges.get(i);
12439            if (item.pid == app.pid) {
12440                mPendingProcessChanges.remove(i);
12441                mAvailProcessChanges.add(item);
12442            }
12443        }
12444        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12445
12446        // If the caller is restarting this app, then leave it in its
12447        // current lists and let the caller take care of it.
12448        if (restarting) {
12449            return;
12450        }
12451
12452        if (!app.persistent || app.isolated) {
12453            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12454                    "Removing non-persistent process during cleanup: " + app);
12455            mProcessNames.remove(app.processName, app.uid);
12456            mIsolatedProcesses.remove(app.uid);
12457            if (mHeavyWeightProcess == app) {
12458                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12459                        mHeavyWeightProcess.userId, 0));
12460                mHeavyWeightProcess = null;
12461            }
12462        } else if (!app.removed) {
12463            // This app is persistent, so we need to keep its record around.
12464            // If it is not already on the pending app list, add it there
12465            // and start a new process for it.
12466            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12467                mPersistentStartingProcesses.add(app);
12468                restart = true;
12469            }
12470        }
12471        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12472                "Clean-up removing on hold: " + app);
12473        mProcessesOnHold.remove(app);
12474
12475        if (app == mHomeProcess) {
12476            mHomeProcess = null;
12477        }
12478        if (app == mPreviousProcess) {
12479            mPreviousProcess = null;
12480        }
12481
12482        if (restart && !app.isolated) {
12483            // We have components that still need to be running in the
12484            // process, so re-launch it.
12485            mProcessNames.put(app.processName, app.uid, app);
12486            startProcessLocked(app, "restart", app.processName);
12487        } else if (app.pid > 0 && app.pid != MY_PID) {
12488            // Goodbye!
12489            synchronized (mPidsSelfLocked) {
12490                mPidsSelfLocked.remove(app.pid);
12491                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12492            }
12493            app.setPid(0);
12494        }
12495    }
12496
12497    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12498        // Look through the content providers we are waiting to have launched,
12499        // and if any run in this process then either schedule a restart of
12500        // the process or kill the client waiting for it if this process has
12501        // gone bad.
12502        int NL = mLaunchingProviders.size();
12503        boolean restart = false;
12504        for (int i=0; i<NL; i++) {
12505            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12506            if (cpr.launchingApp == app) {
12507                if (!alwaysBad && !app.bad) {
12508                    restart = true;
12509                } else {
12510                    removeDyingProviderLocked(app, cpr, true);
12511                    // cpr should have been removed from mLaunchingProviders
12512                    NL = mLaunchingProviders.size();
12513                    i--;
12514                }
12515            }
12516        }
12517        return restart;
12518    }
12519
12520    // =========================================================
12521    // SERVICES
12522    // =========================================================
12523
12524    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12525            int flags) {
12526        enforceNotIsolatedCaller("getServices");
12527        synchronized (this) {
12528            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12529        }
12530    }
12531
12532    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12533        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12534        synchronized (this) {
12535            return mServices.getRunningServiceControlPanelLocked(name);
12536        }
12537    }
12538
12539    public ComponentName startService(IApplicationThread caller, Intent service,
12540            String resolvedType, int userId) {
12541        enforceNotIsolatedCaller("startService");
12542        // Refuse possible leaked file descriptors
12543        if (service != null && service.hasFileDescriptors() == true) {
12544            throw new IllegalArgumentException("File descriptors passed in Intent");
12545        }
12546
12547        if (DEBUG_SERVICE)
12548            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12549        synchronized(this) {
12550            final int callingPid = Binder.getCallingPid();
12551            final int callingUid = Binder.getCallingUid();
12552            final long origId = Binder.clearCallingIdentity();
12553            ComponentName res = mServices.startServiceLocked(caller, service,
12554                    resolvedType, callingPid, callingUid, userId);
12555            Binder.restoreCallingIdentity(origId);
12556            return res;
12557        }
12558    }
12559
12560    ComponentName startServiceInPackage(int uid,
12561            Intent service, String resolvedType, int userId) {
12562        synchronized(this) {
12563            if (DEBUG_SERVICE)
12564                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12565            final long origId = Binder.clearCallingIdentity();
12566            ComponentName res = mServices.startServiceLocked(null, service,
12567                    resolvedType, -1, uid, userId);
12568            Binder.restoreCallingIdentity(origId);
12569            return res;
12570        }
12571    }
12572
12573    public int stopService(IApplicationThread caller, Intent service,
12574            String resolvedType, int userId) {
12575        enforceNotIsolatedCaller("stopService");
12576        // Refuse possible leaked file descriptors
12577        if (service != null && service.hasFileDescriptors() == true) {
12578            throw new IllegalArgumentException("File descriptors passed in Intent");
12579        }
12580
12581        synchronized(this) {
12582            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12583        }
12584    }
12585
12586    public IBinder peekService(Intent service, String resolvedType) {
12587        enforceNotIsolatedCaller("peekService");
12588        // Refuse possible leaked file descriptors
12589        if (service != null && service.hasFileDescriptors() == true) {
12590            throw new IllegalArgumentException("File descriptors passed in Intent");
12591        }
12592        synchronized(this) {
12593            return mServices.peekServiceLocked(service, resolvedType);
12594        }
12595    }
12596
12597    public boolean stopServiceToken(ComponentName className, IBinder token,
12598            int startId) {
12599        synchronized(this) {
12600            return mServices.stopServiceTokenLocked(className, token, startId);
12601        }
12602    }
12603
12604    public void setServiceForeground(ComponentName className, IBinder token,
12605            int id, Notification notification, boolean removeNotification) {
12606        synchronized(this) {
12607            mServices.setServiceForegroundLocked(className, token, id, notification,
12608                    removeNotification);
12609        }
12610    }
12611
12612    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12613            boolean requireFull, String name, String callerPackage) {
12614        final int callingUserId = UserHandle.getUserId(callingUid);
12615        if (callingUserId != userId) {
12616            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12617                if ((requireFull || checkComponentPermission(
12618                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12619                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12620                        && checkComponentPermission(
12621                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12622                                callingPid, callingUid, -1, true)
12623                                != PackageManager.PERMISSION_GRANTED) {
12624                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12625                        // In this case, they would like to just execute as their
12626                        // owner user instead of failing.
12627                        userId = callingUserId;
12628                    } else {
12629                        StringBuilder builder = new StringBuilder(128);
12630                        builder.append("Permission Denial: ");
12631                        builder.append(name);
12632                        if (callerPackage != null) {
12633                            builder.append(" from ");
12634                            builder.append(callerPackage);
12635                        }
12636                        builder.append(" asks to run as user ");
12637                        builder.append(userId);
12638                        builder.append(" but is calling from user ");
12639                        builder.append(UserHandle.getUserId(callingUid));
12640                        builder.append("; this requires ");
12641                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12642                        if (!requireFull) {
12643                            builder.append(" or ");
12644                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12645                        }
12646                        String msg = builder.toString();
12647                        Slog.w(TAG, msg);
12648                        throw new SecurityException(msg);
12649                    }
12650                }
12651            }
12652            if (userId == UserHandle.USER_CURRENT
12653                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12654                // Note that we may be accessing this outside of a lock...
12655                // shouldn't be a big deal, if this is being called outside
12656                // of a locked context there is intrinsically a race with
12657                // the value the caller will receive and someone else changing it.
12658                userId = mCurrentUserId;
12659            }
12660            if (!allowAll && userId < 0) {
12661                throw new IllegalArgumentException(
12662                        "Call does not support special user #" + userId);
12663            }
12664        }
12665        return userId;
12666    }
12667
12668    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12669            String className, int flags) {
12670        boolean result = false;
12671        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12672            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12673                if (ActivityManager.checkUidPermission(
12674                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12675                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12676                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12677                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12678                            + " requests FLAG_SINGLE_USER, but app does not hold "
12679                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12680                    Slog.w(TAG, msg);
12681                    throw new SecurityException(msg);
12682                }
12683                result = true;
12684            }
12685        } else if (componentProcessName == aInfo.packageName) {
12686            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12687        } else if ("system".equals(componentProcessName)) {
12688            result = true;
12689        }
12690        if (DEBUG_MU) {
12691            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12692                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12693        }
12694        return result;
12695    }
12696
12697    public int bindService(IApplicationThread caller, IBinder token,
12698            Intent service, String resolvedType,
12699            IServiceConnection connection, int flags, int userId) {
12700        enforceNotIsolatedCaller("bindService");
12701        // Refuse possible leaked file descriptors
12702        if (service != null && service.hasFileDescriptors() == true) {
12703            throw new IllegalArgumentException("File descriptors passed in Intent");
12704        }
12705
12706        synchronized(this) {
12707            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12708                    connection, flags, userId);
12709        }
12710    }
12711
12712    public boolean unbindService(IServiceConnection connection) {
12713        synchronized (this) {
12714            return mServices.unbindServiceLocked(connection);
12715        }
12716    }
12717
12718    public void publishService(IBinder token, Intent intent, IBinder service) {
12719        // Refuse possible leaked file descriptors
12720        if (intent != null && intent.hasFileDescriptors() == true) {
12721            throw new IllegalArgumentException("File descriptors passed in Intent");
12722        }
12723
12724        synchronized(this) {
12725            if (!(token instanceof ServiceRecord)) {
12726                throw new IllegalArgumentException("Invalid service token");
12727            }
12728            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12729        }
12730    }
12731
12732    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12733        // Refuse possible leaked file descriptors
12734        if (intent != null && intent.hasFileDescriptors() == true) {
12735            throw new IllegalArgumentException("File descriptors passed in Intent");
12736        }
12737
12738        synchronized(this) {
12739            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12740        }
12741    }
12742
12743    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12744        synchronized(this) {
12745            if (!(token instanceof ServiceRecord)) {
12746                throw new IllegalArgumentException("Invalid service token");
12747            }
12748            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12749        }
12750    }
12751
12752    // =========================================================
12753    // BACKUP AND RESTORE
12754    // =========================================================
12755
12756    // Cause the target app to be launched if necessary and its backup agent
12757    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12758    // activity manager to announce its creation.
12759    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12760        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12761        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12762
12763        synchronized(this) {
12764            // !!! TODO: currently no check here that we're already bound
12765            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12766            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12767            synchronized (stats) {
12768                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12769            }
12770
12771            // Backup agent is now in use, its package can't be stopped.
12772            try {
12773                AppGlobals.getPackageManager().setPackageStoppedState(
12774                        app.packageName, false, UserHandle.getUserId(app.uid));
12775            } catch (RemoteException e) {
12776            } catch (IllegalArgumentException e) {
12777                Slog.w(TAG, "Failed trying to unstop package "
12778                        + app.packageName + ": " + e);
12779            }
12780
12781            BackupRecord r = new BackupRecord(ss, app, backupMode);
12782            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12783                    ? new ComponentName(app.packageName, app.backupAgentName)
12784                    : new ComponentName("android", "FullBackupAgent");
12785            // startProcessLocked() returns existing proc's record if it's already running
12786            ProcessRecord proc = startProcessLocked(app.processName, app,
12787                    false, 0, "backup", hostingName, false, false, false);
12788            if (proc == null) {
12789                Slog.e(TAG, "Unable to start backup agent process " + r);
12790                return false;
12791            }
12792
12793            r.app = proc;
12794            mBackupTarget = r;
12795            mBackupAppName = app.packageName;
12796
12797            // Try not to kill the process during backup
12798            updateOomAdjLocked(proc);
12799
12800            // If the process is already attached, schedule the creation of the backup agent now.
12801            // If it is not yet live, this will be done when it attaches to the framework.
12802            if (proc.thread != null) {
12803                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12804                try {
12805                    proc.thread.scheduleCreateBackupAgent(app,
12806                            compatibilityInfoForPackageLocked(app), backupMode);
12807                } catch (RemoteException e) {
12808                    // Will time out on the backup manager side
12809                }
12810            } else {
12811                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12812            }
12813            // Invariants: at this point, the target app process exists and the application
12814            // is either already running or in the process of coming up.  mBackupTarget and
12815            // mBackupAppName describe the app, so that when it binds back to the AM we
12816            // know that it's scheduled for a backup-agent operation.
12817        }
12818
12819        return true;
12820    }
12821
12822    @Override
12823    public void clearPendingBackup() {
12824        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12825        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12826
12827        synchronized (this) {
12828            mBackupTarget = null;
12829            mBackupAppName = null;
12830        }
12831    }
12832
12833    // A backup agent has just come up
12834    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12835        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12836                + " = " + agent);
12837
12838        synchronized(this) {
12839            if (!agentPackageName.equals(mBackupAppName)) {
12840                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12841                return;
12842            }
12843        }
12844
12845        long oldIdent = Binder.clearCallingIdentity();
12846        try {
12847            IBackupManager bm = IBackupManager.Stub.asInterface(
12848                    ServiceManager.getService(Context.BACKUP_SERVICE));
12849            bm.agentConnected(agentPackageName, agent);
12850        } catch (RemoteException e) {
12851            // can't happen; the backup manager service is local
12852        } catch (Exception e) {
12853            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12854            e.printStackTrace();
12855        } finally {
12856            Binder.restoreCallingIdentity(oldIdent);
12857        }
12858    }
12859
12860    // done with this agent
12861    public void unbindBackupAgent(ApplicationInfo appInfo) {
12862        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12863        if (appInfo == null) {
12864            Slog.w(TAG, "unbind backup agent for null app");
12865            return;
12866        }
12867
12868        synchronized(this) {
12869            try {
12870                if (mBackupAppName == null) {
12871                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12872                    return;
12873                }
12874
12875                if (!mBackupAppName.equals(appInfo.packageName)) {
12876                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12877                    return;
12878                }
12879
12880                // Not backing this app up any more; reset its OOM adjustment
12881                final ProcessRecord proc = mBackupTarget.app;
12882                updateOomAdjLocked(proc);
12883
12884                // If the app crashed during backup, 'thread' will be null here
12885                if (proc.thread != null) {
12886                    try {
12887                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12888                                compatibilityInfoForPackageLocked(appInfo));
12889                    } catch (Exception e) {
12890                        Slog.e(TAG, "Exception when unbinding backup agent:");
12891                        e.printStackTrace();
12892                    }
12893                }
12894            } finally {
12895                mBackupTarget = null;
12896                mBackupAppName = null;
12897            }
12898        }
12899    }
12900    // =========================================================
12901    // BROADCASTS
12902    // =========================================================
12903
12904    private final List getStickiesLocked(String action, IntentFilter filter,
12905            List cur, int userId) {
12906        final ContentResolver resolver = mContext.getContentResolver();
12907        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12908        if (stickies == null) {
12909            return cur;
12910        }
12911        final ArrayList<Intent> list = stickies.get(action);
12912        if (list == null) {
12913            return cur;
12914        }
12915        int N = list.size();
12916        for (int i=0; i<N; i++) {
12917            Intent intent = list.get(i);
12918            if (filter.match(resolver, intent, true, TAG) >= 0) {
12919                if (cur == null) {
12920                    cur = new ArrayList<Intent>();
12921                }
12922                cur.add(intent);
12923            }
12924        }
12925        return cur;
12926    }
12927
12928    boolean isPendingBroadcastProcessLocked(int pid) {
12929        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12930                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12931    }
12932
12933    void skipPendingBroadcastLocked(int pid) {
12934            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12935            for (BroadcastQueue queue : mBroadcastQueues) {
12936                queue.skipPendingBroadcastLocked(pid);
12937            }
12938    }
12939
12940    // The app just attached; send any pending broadcasts that it should receive
12941    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12942        boolean didSomething = false;
12943        for (BroadcastQueue queue : mBroadcastQueues) {
12944            didSomething |= queue.sendPendingBroadcastsLocked(app);
12945        }
12946        return didSomething;
12947    }
12948
12949    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12950            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
12951        enforceNotIsolatedCaller("registerReceiver");
12952        int callingUid;
12953        int callingPid;
12954        synchronized(this) {
12955            ProcessRecord callerApp = null;
12956            if (caller != null) {
12957                callerApp = getRecordForAppLocked(caller);
12958                if (callerApp == null) {
12959                    throw new SecurityException(
12960                            "Unable to find app for caller " + caller
12961                            + " (pid=" + Binder.getCallingPid()
12962                            + ") when registering receiver " + receiver);
12963                }
12964                if (callerApp.info.uid != Process.SYSTEM_UID &&
12965                        !callerApp.pkgList.containsKey(callerPackage) &&
12966                        !"android".equals(callerPackage)) {
12967                    throw new SecurityException("Given caller package " + callerPackage
12968                            + " is not running in process " + callerApp);
12969                }
12970                callingUid = callerApp.info.uid;
12971                callingPid = callerApp.pid;
12972            } else {
12973                callerPackage = null;
12974                callingUid = Binder.getCallingUid();
12975                callingPid = Binder.getCallingPid();
12976            }
12977
12978            userId = this.handleIncomingUser(callingPid, callingUid, userId,
12979                    true, true, "registerReceiver", callerPackage);
12980
12981            List allSticky = null;
12982
12983            // Look for any matching sticky broadcasts...
12984            Iterator actions = filter.actionsIterator();
12985            if (actions != null) {
12986                while (actions.hasNext()) {
12987                    String action = (String)actions.next();
12988                    allSticky = getStickiesLocked(action, filter, allSticky,
12989                            UserHandle.USER_ALL);
12990                    allSticky = getStickiesLocked(action, filter, allSticky,
12991                            UserHandle.getUserId(callingUid));
12992                }
12993            } else {
12994                allSticky = getStickiesLocked(null, filter, allSticky,
12995                        UserHandle.USER_ALL);
12996                allSticky = getStickiesLocked(null, filter, allSticky,
12997                        UserHandle.getUserId(callingUid));
12998            }
12999
13000            // The first sticky in the list is returned directly back to
13001            // the client.
13002            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13003
13004            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13005                    + ": " + sticky);
13006
13007            if (receiver == null) {
13008                return sticky;
13009            }
13010
13011            ReceiverList rl
13012                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13013            if (rl == null) {
13014                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13015                        userId, receiver);
13016                if (rl.app != null) {
13017                    rl.app.receivers.add(rl);
13018                } else {
13019                    try {
13020                        receiver.asBinder().linkToDeath(rl, 0);
13021                    } catch (RemoteException e) {
13022                        return sticky;
13023                    }
13024                    rl.linkedToDeath = true;
13025                }
13026                mRegisteredReceivers.put(receiver.asBinder(), rl);
13027            } else if (rl.uid != callingUid) {
13028                throw new IllegalArgumentException(
13029                        "Receiver requested to register for uid " + callingUid
13030                        + " was previously registered for uid " + rl.uid);
13031            } else if (rl.pid != callingPid) {
13032                throw new IllegalArgumentException(
13033                        "Receiver requested to register for pid " + callingPid
13034                        + " was previously registered for pid " + rl.pid);
13035            } else if (rl.userId != userId) {
13036                throw new IllegalArgumentException(
13037                        "Receiver requested to register for user " + userId
13038                        + " was previously registered for user " + rl.userId);
13039            }
13040            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13041                    permission, callingUid, userId);
13042            rl.add(bf);
13043            if (!bf.debugCheck()) {
13044                Slog.w(TAG, "==> For Dynamic broadast");
13045            }
13046            mReceiverResolver.addFilter(bf);
13047
13048            // Enqueue broadcasts for all existing stickies that match
13049            // this filter.
13050            if (allSticky != null) {
13051                ArrayList receivers = new ArrayList();
13052                receivers.add(bf);
13053
13054                int N = allSticky.size();
13055                for (int i=0; i<N; i++) {
13056                    Intent intent = (Intent)allSticky.get(i);
13057                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13058                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13059                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13060                            null, null, false, true, true, -1);
13061                    queue.enqueueParallelBroadcastLocked(r);
13062                    queue.scheduleBroadcastsLocked();
13063                }
13064            }
13065
13066            return sticky;
13067        }
13068    }
13069
13070    public void unregisterReceiver(IIntentReceiver receiver) {
13071        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13072
13073        final long origId = Binder.clearCallingIdentity();
13074        try {
13075            boolean doTrim = false;
13076
13077            synchronized(this) {
13078                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13079                if (rl != null) {
13080                    if (rl.curBroadcast != null) {
13081                        BroadcastRecord r = rl.curBroadcast;
13082                        final boolean doNext = finishReceiverLocked(
13083                                receiver.asBinder(), r.resultCode, r.resultData,
13084                                r.resultExtras, r.resultAbort);
13085                        if (doNext) {
13086                            doTrim = true;
13087                            r.queue.processNextBroadcast(false);
13088                        }
13089                    }
13090
13091                    if (rl.app != null) {
13092                        rl.app.receivers.remove(rl);
13093                    }
13094                    removeReceiverLocked(rl);
13095                    if (rl.linkedToDeath) {
13096                        rl.linkedToDeath = false;
13097                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13098                    }
13099                }
13100            }
13101
13102            // If we actually concluded any broadcasts, we might now be able
13103            // to trim the recipients' apps from our working set
13104            if (doTrim) {
13105                trimApplications();
13106                return;
13107            }
13108
13109        } finally {
13110            Binder.restoreCallingIdentity(origId);
13111        }
13112    }
13113
13114    void removeReceiverLocked(ReceiverList rl) {
13115        mRegisteredReceivers.remove(rl.receiver.asBinder());
13116        int N = rl.size();
13117        for (int i=0; i<N; i++) {
13118            mReceiverResolver.removeFilter(rl.get(i));
13119        }
13120    }
13121
13122    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13123        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13124            ProcessRecord r = mLruProcesses.get(i);
13125            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13126                try {
13127                    r.thread.dispatchPackageBroadcast(cmd, packages);
13128                } catch (RemoteException ex) {
13129                }
13130            }
13131        }
13132    }
13133
13134    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13135            int[] users) {
13136        List<ResolveInfo> receivers = null;
13137        try {
13138            HashSet<ComponentName> singleUserReceivers = null;
13139            boolean scannedFirstReceivers = false;
13140            for (int user : users) {
13141                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13142                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13143                if (user != 0 && newReceivers != null) {
13144                    // If this is not the primary user, we need to check for
13145                    // any receivers that should be filtered out.
13146                    for (int i=0; i<newReceivers.size(); i++) {
13147                        ResolveInfo ri = newReceivers.get(i);
13148                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13149                            newReceivers.remove(i);
13150                            i--;
13151                        }
13152                    }
13153                }
13154                if (newReceivers != null && newReceivers.size() == 0) {
13155                    newReceivers = null;
13156                }
13157                if (receivers == null) {
13158                    receivers = newReceivers;
13159                } else if (newReceivers != null) {
13160                    // We need to concatenate the additional receivers
13161                    // found with what we have do far.  This would be easy,
13162                    // but we also need to de-dup any receivers that are
13163                    // singleUser.
13164                    if (!scannedFirstReceivers) {
13165                        // Collect any single user receivers we had already retrieved.
13166                        scannedFirstReceivers = true;
13167                        for (int i=0; i<receivers.size(); i++) {
13168                            ResolveInfo ri = receivers.get(i);
13169                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13170                                ComponentName cn = new ComponentName(
13171                                        ri.activityInfo.packageName, ri.activityInfo.name);
13172                                if (singleUserReceivers == null) {
13173                                    singleUserReceivers = new HashSet<ComponentName>();
13174                                }
13175                                singleUserReceivers.add(cn);
13176                            }
13177                        }
13178                    }
13179                    // Add the new results to the existing results, tracking
13180                    // and de-dupping single user receivers.
13181                    for (int i=0; i<newReceivers.size(); i++) {
13182                        ResolveInfo ri = newReceivers.get(i);
13183                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13184                            ComponentName cn = new ComponentName(
13185                                    ri.activityInfo.packageName, ri.activityInfo.name);
13186                            if (singleUserReceivers == null) {
13187                                singleUserReceivers = new HashSet<ComponentName>();
13188                            }
13189                            if (!singleUserReceivers.contains(cn)) {
13190                                singleUserReceivers.add(cn);
13191                                receivers.add(ri);
13192                            }
13193                        } else {
13194                            receivers.add(ri);
13195                        }
13196                    }
13197                }
13198            }
13199        } catch (RemoteException ex) {
13200            // pm is in same process, this will never happen.
13201        }
13202        return receivers;
13203    }
13204
13205    private final int broadcastIntentLocked(ProcessRecord callerApp,
13206            String callerPackage, Intent intent, String resolvedType,
13207            IIntentReceiver resultTo, int resultCode, String resultData,
13208            Bundle map, String requiredPermission, int appOp,
13209            boolean ordered, boolean sticky, int callingPid, int callingUid,
13210            int userId) {
13211        intent = new Intent(intent);
13212
13213        // By default broadcasts do not go to stopped apps.
13214        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13215
13216        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13217            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13218            + " ordered=" + ordered + " userid=" + userId);
13219        if ((resultTo != null) && !ordered) {
13220            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13221        }
13222
13223        userId = handleIncomingUser(callingPid, callingUid, userId,
13224                true, false, "broadcast", callerPackage);
13225
13226        // Make sure that the user who is receiving this broadcast is started.
13227        // If not, we will just skip it.
13228        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13229            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13230                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13231                Slog.w(TAG, "Skipping broadcast of " + intent
13232                        + ": user " + userId + " is stopped");
13233                return ActivityManager.BROADCAST_SUCCESS;
13234            }
13235        }
13236
13237        /*
13238         * Prevent non-system code (defined here to be non-persistent
13239         * processes) from sending protected broadcasts.
13240         */
13241        int callingAppId = UserHandle.getAppId(callingUid);
13242        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13243            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13244            callingUid == 0) {
13245            // Always okay.
13246        } else if (callerApp == null || !callerApp.persistent) {
13247            try {
13248                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13249                        intent.getAction())) {
13250                    String msg = "Permission Denial: not allowed to send broadcast "
13251                            + intent.getAction() + " from pid="
13252                            + callingPid + ", uid=" + callingUid;
13253                    Slog.w(TAG, msg);
13254                    throw new SecurityException(msg);
13255                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13256                    // Special case for compatibility: we don't want apps to send this,
13257                    // but historically it has not been protected and apps may be using it
13258                    // to poke their own app widget.  So, instead of making it protected,
13259                    // just limit it to the caller.
13260                    if (callerApp == null) {
13261                        String msg = "Permission Denial: not allowed to send broadcast "
13262                                + intent.getAction() + " from unknown caller.";
13263                        Slog.w(TAG, msg);
13264                        throw new SecurityException(msg);
13265                    } else if (intent.getComponent() != null) {
13266                        // They are good enough to send to an explicit component...  verify
13267                        // it is being sent to the calling app.
13268                        if (!intent.getComponent().getPackageName().equals(
13269                                callerApp.info.packageName)) {
13270                            String msg = "Permission Denial: not allowed to send broadcast "
13271                                    + intent.getAction() + " to "
13272                                    + intent.getComponent().getPackageName() + " from "
13273                                    + callerApp.info.packageName;
13274                            Slog.w(TAG, msg);
13275                            throw new SecurityException(msg);
13276                        }
13277                    } else {
13278                        // Limit broadcast to their own package.
13279                        intent.setPackage(callerApp.info.packageName);
13280                    }
13281                }
13282            } catch (RemoteException e) {
13283                Slog.w(TAG, "Remote exception", e);
13284                return ActivityManager.BROADCAST_SUCCESS;
13285            }
13286        }
13287
13288        // Handle special intents: if this broadcast is from the package
13289        // manager about a package being removed, we need to remove all of
13290        // its activities from the history stack.
13291        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13292                intent.getAction());
13293        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13294                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13295                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13296                || uidRemoved) {
13297            if (checkComponentPermission(
13298                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13299                    callingPid, callingUid, -1, true)
13300                    == PackageManager.PERMISSION_GRANTED) {
13301                if (uidRemoved) {
13302                    final Bundle intentExtras = intent.getExtras();
13303                    final int uid = intentExtras != null
13304                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13305                    if (uid >= 0) {
13306                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13307                        synchronized (bs) {
13308                            bs.removeUidStatsLocked(uid);
13309                        }
13310                        mAppOpsService.uidRemoved(uid);
13311                    }
13312                } else {
13313                    // If resources are unavailable just force stop all
13314                    // those packages and flush the attribute cache as well.
13315                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13316                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13317                        if (list != null && (list.length > 0)) {
13318                            for (String pkg : list) {
13319                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
13320                                        "storage unmount");
13321                            }
13322                            sendPackageBroadcastLocked(
13323                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13324                        }
13325                    } else {
13326                        Uri data = intent.getData();
13327                        String ssp;
13328                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13329                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13330                                    intent.getAction());
13331                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13332                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13333                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13334                                        false, userId, removed ? "pkg removed" : "pkg changed");
13335                            }
13336                            if (removed) {
13337                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13338                                        new String[] {ssp}, userId);
13339                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13340                                    mAppOpsService.packageRemoved(
13341                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13342
13343                                    // Remove all permissions granted from/to this package
13344                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13345                                }
13346                            }
13347                        }
13348                    }
13349                }
13350            } else {
13351                String msg = "Permission Denial: " + intent.getAction()
13352                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13353                        + ", uid=" + callingUid + ")"
13354                        + " requires "
13355                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13356                Slog.w(TAG, msg);
13357                throw new SecurityException(msg);
13358            }
13359
13360        // Special case for adding a package: by default turn on compatibility
13361        // mode.
13362        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13363            Uri data = intent.getData();
13364            String ssp;
13365            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13366                mCompatModePackages.handlePackageAddedLocked(ssp,
13367                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13368            }
13369        }
13370
13371        /*
13372         * If this is the time zone changed action, queue up a message that will reset the timezone
13373         * of all currently running processes. This message will get queued up before the broadcast
13374         * happens.
13375         */
13376        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13377            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13378        }
13379
13380        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13381            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13382        }
13383
13384        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13385            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13386            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13387        }
13388
13389        // Add to the sticky list if requested.
13390        if (sticky) {
13391            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13392                    callingPid, callingUid)
13393                    != PackageManager.PERMISSION_GRANTED) {
13394                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13395                        + callingPid + ", uid=" + callingUid
13396                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13397                Slog.w(TAG, msg);
13398                throw new SecurityException(msg);
13399            }
13400            if (requiredPermission != null) {
13401                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13402                        + " and enforce permission " + requiredPermission);
13403                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13404            }
13405            if (intent.getComponent() != null) {
13406                throw new SecurityException(
13407                        "Sticky broadcasts can't target a specific component");
13408            }
13409            // We use userId directly here, since the "all" target is maintained
13410            // as a separate set of sticky broadcasts.
13411            if (userId != UserHandle.USER_ALL) {
13412                // But first, if this is not a broadcast to all users, then
13413                // make sure it doesn't conflict with an existing broadcast to
13414                // all users.
13415                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13416                        UserHandle.USER_ALL);
13417                if (stickies != null) {
13418                    ArrayList<Intent> list = stickies.get(intent.getAction());
13419                    if (list != null) {
13420                        int N = list.size();
13421                        int i;
13422                        for (i=0; i<N; i++) {
13423                            if (intent.filterEquals(list.get(i))) {
13424                                throw new IllegalArgumentException(
13425                                        "Sticky broadcast " + intent + " for user "
13426                                        + userId + " conflicts with existing global broadcast");
13427                            }
13428                        }
13429                    }
13430                }
13431            }
13432            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13433            if (stickies == null) {
13434                stickies = new ArrayMap<String, ArrayList<Intent>>();
13435                mStickyBroadcasts.put(userId, stickies);
13436            }
13437            ArrayList<Intent> list = stickies.get(intent.getAction());
13438            if (list == null) {
13439                list = new ArrayList<Intent>();
13440                stickies.put(intent.getAction(), list);
13441            }
13442            int N = list.size();
13443            int i;
13444            for (i=0; i<N; i++) {
13445                if (intent.filterEquals(list.get(i))) {
13446                    // This sticky already exists, replace it.
13447                    list.set(i, new Intent(intent));
13448                    break;
13449                }
13450            }
13451            if (i >= N) {
13452                list.add(new Intent(intent));
13453            }
13454        }
13455
13456        int[] users;
13457        if (userId == UserHandle.USER_ALL) {
13458            // Caller wants broadcast to go to all started users.
13459            users = mStartedUserArray;
13460        } else {
13461            // Caller wants broadcast to go to one specific user.
13462            users = new int[] {userId};
13463        }
13464
13465        // Figure out who all will receive this broadcast.
13466        List receivers = null;
13467        List<BroadcastFilter> registeredReceivers = null;
13468        // Need to resolve the intent to interested receivers...
13469        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13470                 == 0) {
13471            receivers = collectReceiverComponents(intent, resolvedType, users);
13472        }
13473        if (intent.getComponent() == null) {
13474            registeredReceivers = mReceiverResolver.queryIntent(intent,
13475                    resolvedType, false, userId);
13476        }
13477
13478        final boolean replacePending =
13479                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13480
13481        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13482                + " replacePending=" + replacePending);
13483
13484        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13485        if (!ordered && NR > 0) {
13486            // If we are not serializing this broadcast, then send the
13487            // registered receivers separately so they don't wait for the
13488            // components to be launched.
13489            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13490            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13491                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13492                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13493                    ordered, sticky, false, userId);
13494            if (DEBUG_BROADCAST) Slog.v(
13495                    TAG, "Enqueueing parallel broadcast " + r);
13496            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13497            if (!replaced) {
13498                queue.enqueueParallelBroadcastLocked(r);
13499                queue.scheduleBroadcastsLocked();
13500            }
13501            registeredReceivers = null;
13502            NR = 0;
13503        }
13504
13505        // Merge into one list.
13506        int ir = 0;
13507        if (receivers != null) {
13508            // A special case for PACKAGE_ADDED: do not allow the package
13509            // being added to see this broadcast.  This prevents them from
13510            // using this as a back door to get run as soon as they are
13511            // installed.  Maybe in the future we want to have a special install
13512            // broadcast or such for apps, but we'd like to deliberately make
13513            // this decision.
13514            String skipPackages[] = null;
13515            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13516                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13517                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13518                Uri data = intent.getData();
13519                if (data != null) {
13520                    String pkgName = data.getSchemeSpecificPart();
13521                    if (pkgName != null) {
13522                        skipPackages = new String[] { pkgName };
13523                    }
13524                }
13525            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13526                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13527            }
13528            if (skipPackages != null && (skipPackages.length > 0)) {
13529                for (String skipPackage : skipPackages) {
13530                    if (skipPackage != null) {
13531                        int NT = receivers.size();
13532                        for (int it=0; it<NT; it++) {
13533                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13534                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13535                                receivers.remove(it);
13536                                it--;
13537                                NT--;
13538                            }
13539                        }
13540                    }
13541                }
13542            }
13543
13544            int NT = receivers != null ? receivers.size() : 0;
13545            int it = 0;
13546            ResolveInfo curt = null;
13547            BroadcastFilter curr = null;
13548            while (it < NT && ir < NR) {
13549                if (curt == null) {
13550                    curt = (ResolveInfo)receivers.get(it);
13551                }
13552                if (curr == null) {
13553                    curr = registeredReceivers.get(ir);
13554                }
13555                if (curr.getPriority() >= curt.priority) {
13556                    // Insert this broadcast record into the final list.
13557                    receivers.add(it, curr);
13558                    ir++;
13559                    curr = null;
13560                    it++;
13561                    NT++;
13562                } else {
13563                    // Skip to the next ResolveInfo in the final list.
13564                    it++;
13565                    curt = null;
13566                }
13567            }
13568        }
13569        while (ir < NR) {
13570            if (receivers == null) {
13571                receivers = new ArrayList();
13572            }
13573            receivers.add(registeredReceivers.get(ir));
13574            ir++;
13575        }
13576
13577        if ((receivers != null && receivers.size() > 0)
13578                || resultTo != null) {
13579            BroadcastQueue queue = broadcastQueueForIntent(intent);
13580            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13581                    callerPackage, callingPid, callingUid, resolvedType,
13582                    requiredPermission, appOp, receivers, resultTo, resultCode,
13583                    resultData, map, ordered, sticky, false, userId);
13584            if (DEBUG_BROADCAST) Slog.v(
13585                    TAG, "Enqueueing ordered broadcast " + r
13586                    + ": prev had " + queue.mOrderedBroadcasts.size());
13587            if (DEBUG_BROADCAST) {
13588                int seq = r.intent.getIntExtra("seq", -1);
13589                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13590            }
13591            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13592            if (!replaced) {
13593                queue.enqueueOrderedBroadcastLocked(r);
13594                queue.scheduleBroadcastsLocked();
13595            }
13596        }
13597
13598        return ActivityManager.BROADCAST_SUCCESS;
13599    }
13600
13601    final Intent verifyBroadcastLocked(Intent intent) {
13602        // Refuse possible leaked file descriptors
13603        if (intent != null && intent.hasFileDescriptors() == true) {
13604            throw new IllegalArgumentException("File descriptors passed in Intent");
13605        }
13606
13607        int flags = intent.getFlags();
13608
13609        if (!mProcessesReady) {
13610            // if the caller really truly claims to know what they're doing, go
13611            // ahead and allow the broadcast without launching any receivers
13612            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13613                intent = new Intent(intent);
13614                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13615            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13616                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13617                        + " before boot completion");
13618                throw new IllegalStateException("Cannot broadcast before boot completed");
13619            }
13620        }
13621
13622        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13623            throw new IllegalArgumentException(
13624                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13625        }
13626
13627        return intent;
13628    }
13629
13630    public final int broadcastIntent(IApplicationThread caller,
13631            Intent intent, String resolvedType, IIntentReceiver resultTo,
13632            int resultCode, String resultData, Bundle map,
13633            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13634        enforceNotIsolatedCaller("broadcastIntent");
13635        synchronized(this) {
13636            intent = verifyBroadcastLocked(intent);
13637
13638            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13639            final int callingPid = Binder.getCallingPid();
13640            final int callingUid = Binder.getCallingUid();
13641            final long origId = Binder.clearCallingIdentity();
13642            int res = broadcastIntentLocked(callerApp,
13643                    callerApp != null ? callerApp.info.packageName : null,
13644                    intent, resolvedType, resultTo,
13645                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13646                    callingPid, callingUid, userId);
13647            Binder.restoreCallingIdentity(origId);
13648            return res;
13649        }
13650    }
13651
13652    int broadcastIntentInPackage(String packageName, int uid,
13653            Intent intent, String resolvedType, IIntentReceiver resultTo,
13654            int resultCode, String resultData, Bundle map,
13655            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13656        synchronized(this) {
13657            intent = verifyBroadcastLocked(intent);
13658
13659            final long origId = Binder.clearCallingIdentity();
13660            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13661                    resultTo, resultCode, resultData, map, requiredPermission,
13662                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13663            Binder.restoreCallingIdentity(origId);
13664            return res;
13665        }
13666    }
13667
13668    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13669        // Refuse possible leaked file descriptors
13670        if (intent != null && intent.hasFileDescriptors() == true) {
13671            throw new IllegalArgumentException("File descriptors passed in Intent");
13672        }
13673
13674        userId = handleIncomingUser(Binder.getCallingPid(),
13675                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13676
13677        synchronized(this) {
13678            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13679                    != PackageManager.PERMISSION_GRANTED) {
13680                String msg = "Permission Denial: unbroadcastIntent() from pid="
13681                        + Binder.getCallingPid()
13682                        + ", uid=" + Binder.getCallingUid()
13683                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13684                Slog.w(TAG, msg);
13685                throw new SecurityException(msg);
13686            }
13687            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13688            if (stickies != null) {
13689                ArrayList<Intent> list = stickies.get(intent.getAction());
13690                if (list != null) {
13691                    int N = list.size();
13692                    int i;
13693                    for (i=0; i<N; i++) {
13694                        if (intent.filterEquals(list.get(i))) {
13695                            list.remove(i);
13696                            break;
13697                        }
13698                    }
13699                    if (list.size() <= 0) {
13700                        stickies.remove(intent.getAction());
13701                    }
13702                }
13703                if (stickies.size() <= 0) {
13704                    mStickyBroadcasts.remove(userId);
13705                }
13706            }
13707        }
13708    }
13709
13710    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13711            String resultData, Bundle resultExtras, boolean resultAbort) {
13712        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13713        if (r == null) {
13714            Slog.w(TAG, "finishReceiver called but not found on queue");
13715            return false;
13716        }
13717
13718        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13719    }
13720
13721    void backgroundServicesFinishedLocked(int userId) {
13722        for (BroadcastQueue queue : mBroadcastQueues) {
13723            queue.backgroundServicesFinishedLocked(userId);
13724        }
13725    }
13726
13727    public void finishReceiver(IBinder who, int resultCode, String resultData,
13728            Bundle resultExtras, boolean resultAbort) {
13729        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13730
13731        // Refuse possible leaked file descriptors
13732        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13733            throw new IllegalArgumentException("File descriptors passed in Bundle");
13734        }
13735
13736        final long origId = Binder.clearCallingIdentity();
13737        try {
13738            boolean doNext = false;
13739            BroadcastRecord r;
13740
13741            synchronized(this) {
13742                r = broadcastRecordForReceiverLocked(who);
13743                if (r != null) {
13744                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13745                        resultData, resultExtras, resultAbort, true);
13746                }
13747            }
13748
13749            if (doNext) {
13750                r.queue.processNextBroadcast(false);
13751            }
13752            trimApplications();
13753        } finally {
13754            Binder.restoreCallingIdentity(origId);
13755        }
13756    }
13757
13758    // =========================================================
13759    // INSTRUMENTATION
13760    // =========================================================
13761
13762    public boolean startInstrumentation(ComponentName className,
13763            String profileFile, int flags, Bundle arguments,
13764            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13765            int userId) {
13766        enforceNotIsolatedCaller("startInstrumentation");
13767        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13768                userId, false, true, "startInstrumentation", null);
13769        // Refuse possible leaked file descriptors
13770        if (arguments != null && arguments.hasFileDescriptors()) {
13771            throw new IllegalArgumentException("File descriptors passed in Bundle");
13772        }
13773
13774        synchronized(this) {
13775            InstrumentationInfo ii = null;
13776            ApplicationInfo ai = null;
13777            try {
13778                ii = mContext.getPackageManager().getInstrumentationInfo(
13779                    className, STOCK_PM_FLAGS);
13780                ai = AppGlobals.getPackageManager().getApplicationInfo(
13781                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13782            } catch (PackageManager.NameNotFoundException e) {
13783            } catch (RemoteException e) {
13784            }
13785            if (ii == null) {
13786                reportStartInstrumentationFailure(watcher, className,
13787                        "Unable to find instrumentation info for: " + className);
13788                return false;
13789            }
13790            if (ai == null) {
13791                reportStartInstrumentationFailure(watcher, className,
13792                        "Unable to find instrumentation target package: " + ii.targetPackage);
13793                return false;
13794            }
13795
13796            int match = mContext.getPackageManager().checkSignatures(
13797                    ii.targetPackage, ii.packageName);
13798            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13799                String msg = "Permission Denial: starting instrumentation "
13800                        + className + " from pid="
13801                        + Binder.getCallingPid()
13802                        + ", uid=" + Binder.getCallingPid()
13803                        + " not allowed because package " + ii.packageName
13804                        + " does not have a signature matching the target "
13805                        + ii.targetPackage;
13806                reportStartInstrumentationFailure(watcher, className, msg);
13807                throw new SecurityException(msg);
13808            }
13809
13810            final long origId = Binder.clearCallingIdentity();
13811            // Instrumentation can kill and relaunch even persistent processes
13812            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId,
13813                    "start instr");
13814            ProcessRecord app = addAppLocked(ai, false);
13815            app.instrumentationClass = className;
13816            app.instrumentationInfo = ai;
13817            app.instrumentationProfileFile = profileFile;
13818            app.instrumentationArguments = arguments;
13819            app.instrumentationWatcher = watcher;
13820            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13821            app.instrumentationResultClass = className;
13822            Binder.restoreCallingIdentity(origId);
13823        }
13824
13825        return true;
13826    }
13827
13828    /**
13829     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13830     * error to the logs, but if somebody is watching, send the report there too.  This enables
13831     * the "am" command to report errors with more information.
13832     *
13833     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13834     * @param cn The component name of the instrumentation.
13835     * @param report The error report.
13836     */
13837    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13838            ComponentName cn, String report) {
13839        Slog.w(TAG, report);
13840        try {
13841            if (watcher != null) {
13842                Bundle results = new Bundle();
13843                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13844                results.putString("Error", report);
13845                watcher.instrumentationStatus(cn, -1, results);
13846            }
13847        } catch (RemoteException e) {
13848            Slog.w(TAG, e);
13849        }
13850    }
13851
13852    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13853        if (app.instrumentationWatcher != null) {
13854            try {
13855                // NOTE:  IInstrumentationWatcher *must* be oneway here
13856                app.instrumentationWatcher.instrumentationFinished(
13857                    app.instrumentationClass,
13858                    resultCode,
13859                    results);
13860            } catch (RemoteException e) {
13861            }
13862        }
13863        if (app.instrumentationUiAutomationConnection != null) {
13864            try {
13865                app.instrumentationUiAutomationConnection.shutdown();
13866            } catch (RemoteException re) {
13867                /* ignore */
13868            }
13869            // Only a UiAutomation can set this flag and now that
13870            // it is finished we make sure it is reset to its default.
13871            mUserIsMonkey = false;
13872        }
13873        app.instrumentationWatcher = null;
13874        app.instrumentationUiAutomationConnection = null;
13875        app.instrumentationClass = null;
13876        app.instrumentationInfo = null;
13877        app.instrumentationProfileFile = null;
13878        app.instrumentationArguments = null;
13879
13880        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId,
13881                "finished inst");
13882    }
13883
13884    public void finishInstrumentation(IApplicationThread target,
13885            int resultCode, Bundle results) {
13886        int userId = UserHandle.getCallingUserId();
13887        // Refuse possible leaked file descriptors
13888        if (results != null && results.hasFileDescriptors()) {
13889            throw new IllegalArgumentException("File descriptors passed in Intent");
13890        }
13891
13892        synchronized(this) {
13893            ProcessRecord app = getRecordForAppLocked(target);
13894            if (app == null) {
13895                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13896                return;
13897            }
13898            final long origId = Binder.clearCallingIdentity();
13899            finishInstrumentationLocked(app, resultCode, results);
13900            Binder.restoreCallingIdentity(origId);
13901        }
13902    }
13903
13904    // =========================================================
13905    // CONFIGURATION
13906    // =========================================================
13907
13908    public ConfigurationInfo getDeviceConfigurationInfo() {
13909        ConfigurationInfo config = new ConfigurationInfo();
13910        synchronized (this) {
13911            config.reqTouchScreen = mConfiguration.touchscreen;
13912            config.reqKeyboardType = mConfiguration.keyboard;
13913            config.reqNavigation = mConfiguration.navigation;
13914            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13915                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13916                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13917            }
13918            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13919                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13920                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13921            }
13922            config.reqGlEsVersion = GL_ES_VERSION;
13923        }
13924        return config;
13925    }
13926
13927    ActivityStack getFocusedStack() {
13928        return mStackSupervisor.getFocusedStack();
13929    }
13930
13931    public Configuration getConfiguration() {
13932        Configuration ci;
13933        synchronized(this) {
13934            ci = new Configuration(mConfiguration);
13935        }
13936        return ci;
13937    }
13938
13939    public void updatePersistentConfiguration(Configuration values) {
13940        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13941                "updateConfiguration()");
13942        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13943                "updateConfiguration()");
13944        if (values == null) {
13945            throw new NullPointerException("Configuration must not be null");
13946        }
13947
13948        synchronized(this) {
13949            final long origId = Binder.clearCallingIdentity();
13950            updateConfigurationLocked(values, null, true, false);
13951            Binder.restoreCallingIdentity(origId);
13952        }
13953    }
13954
13955    public void updateConfiguration(Configuration values) {
13956        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13957                "updateConfiguration()");
13958
13959        synchronized(this) {
13960            if (values == null && mWindowManager != null) {
13961                // sentinel: fetch the current configuration from the window manager
13962                values = mWindowManager.computeNewConfiguration();
13963            }
13964
13965            if (mWindowManager != null) {
13966                mProcessList.applyDisplaySize(mWindowManager);
13967            }
13968
13969            final long origId = Binder.clearCallingIdentity();
13970            if (values != null) {
13971                Settings.System.clearConfiguration(values);
13972            }
13973            updateConfigurationLocked(values, null, false, false);
13974            Binder.restoreCallingIdentity(origId);
13975        }
13976    }
13977
13978    /**
13979     * Do either or both things: (1) change the current configuration, and (2)
13980     * make sure the given activity is running with the (now) current
13981     * configuration.  Returns true if the activity has been left running, or
13982     * false if <var>starting</var> is being destroyed to match the new
13983     * configuration.
13984     * @param persistent TODO
13985     */
13986    boolean updateConfigurationLocked(Configuration values,
13987            ActivityRecord starting, boolean persistent, boolean initLocale) {
13988        int changes = 0;
13989
13990        if (values != null) {
13991            Configuration newConfig = new Configuration(mConfiguration);
13992            changes = newConfig.updateFrom(values);
13993            if (changes != 0) {
13994                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13995                    Slog.i(TAG, "Updating configuration to: " + values);
13996                }
13997
13998                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13999
14000                if (values.locale != null && !initLocale) {
14001                    saveLocaleLocked(values.locale,
14002                                     !values.locale.equals(mConfiguration.locale),
14003                                     values.userSetLocale);
14004                }
14005
14006                mConfigurationSeq++;
14007                if (mConfigurationSeq <= 0) {
14008                    mConfigurationSeq = 1;
14009                }
14010                newConfig.seq = mConfigurationSeq;
14011                mConfiguration = newConfig;
14012                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14013
14014                final Configuration configCopy = new Configuration(mConfiguration);
14015
14016                // TODO: If our config changes, should we auto dismiss any currently
14017                // showing dialogs?
14018                mShowDialogs = shouldShowDialogs(newConfig);
14019
14020                AttributeCache ac = AttributeCache.instance();
14021                if (ac != null) {
14022                    ac.updateConfiguration(configCopy);
14023                }
14024
14025                // Make sure all resources in our process are updated
14026                // right now, so that anyone who is going to retrieve
14027                // resource values after we return will be sure to get
14028                // the new ones.  This is especially important during
14029                // boot, where the first config change needs to guarantee
14030                // all resources have that config before following boot
14031                // code is executed.
14032                mSystemThread.applyConfigurationToResources(configCopy);
14033
14034                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14035                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14036                    msg.obj = new Configuration(configCopy);
14037                    mHandler.sendMessage(msg);
14038                }
14039
14040                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14041                    ProcessRecord app = mLruProcesses.get(i);
14042                    try {
14043                        if (app.thread != null) {
14044                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14045                                    + app.processName + " new config " + mConfiguration);
14046                            app.thread.scheduleConfigurationChanged(configCopy);
14047                        }
14048                    } catch (Exception e) {
14049                    }
14050                }
14051                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14052                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14053                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14054                        | Intent.FLAG_RECEIVER_FOREGROUND);
14055                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14056                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14057                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14058                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14059                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14060                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14061                    broadcastIntentLocked(null, null, intent,
14062                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14063                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14064                }
14065            }
14066        }
14067
14068        boolean kept = true;
14069        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14070        // mainStack is null during startup.
14071        if (mainStack != null) {
14072            if (changes != 0 && starting == null) {
14073                // If the configuration changed, and the caller is not already
14074                // in the process of starting an activity, then find the top
14075                // activity to check if its configuration needs to change.
14076                starting = mainStack.topRunningActivityLocked(null);
14077            }
14078
14079            if (starting != null) {
14080                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14081                // And we need to make sure at this point that all other activities
14082                // are made visible with the correct configuration.
14083                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14084            }
14085        }
14086
14087        if (values != null && mWindowManager != null) {
14088            mWindowManager.setNewConfiguration(mConfiguration);
14089        }
14090
14091        return kept;
14092    }
14093
14094    /**
14095     * Decide based on the configuration whether we should shouw the ANR,
14096     * crash, etc dialogs.  The idea is that if there is no affordnace to
14097     * press the on-screen buttons, we shouldn't show the dialog.
14098     *
14099     * A thought: SystemUI might also want to get told about this, the Power
14100     * dialog / global actions also might want different behaviors.
14101     */
14102    private static final boolean shouldShowDialogs(Configuration config) {
14103        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14104                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14105    }
14106
14107    /**
14108     * Save the locale.  You must be inside a synchronized (this) block.
14109     */
14110    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14111        if(isDiff) {
14112            SystemProperties.set("user.language", l.getLanguage());
14113            SystemProperties.set("user.region", l.getCountry());
14114        }
14115
14116        if(isPersist) {
14117            SystemProperties.set("persist.sys.language", l.getLanguage());
14118            SystemProperties.set("persist.sys.country", l.getCountry());
14119            SystemProperties.set("persist.sys.localevar", l.getVariant());
14120        }
14121    }
14122
14123    @Override
14124    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14125        ActivityRecord srec = ActivityRecord.forToken(token);
14126        return srec != null && srec.task.affinity != null &&
14127                srec.task.affinity.equals(destAffinity);
14128    }
14129
14130    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14131            Intent resultData) {
14132
14133        synchronized (this) {
14134            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14135            if (stack != null) {
14136                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14137            }
14138            return false;
14139        }
14140    }
14141
14142    public int getLaunchedFromUid(IBinder activityToken) {
14143        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14144        if (srec == null) {
14145            return -1;
14146        }
14147        return srec.launchedFromUid;
14148    }
14149
14150    public String getLaunchedFromPackage(IBinder activityToken) {
14151        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14152        if (srec == null) {
14153            return null;
14154        }
14155        return srec.launchedFromPackage;
14156    }
14157
14158    // =========================================================
14159    // LIFETIME MANAGEMENT
14160    // =========================================================
14161
14162    // Returns which broadcast queue the app is the current [or imminent] receiver
14163    // on, or 'null' if the app is not an active broadcast recipient.
14164    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14165        BroadcastRecord r = app.curReceiver;
14166        if (r != null) {
14167            return r.queue;
14168        }
14169
14170        // It's not the current receiver, but it might be starting up to become one
14171        synchronized (this) {
14172            for (BroadcastQueue queue : mBroadcastQueues) {
14173                r = queue.mPendingBroadcast;
14174                if (r != null && r.curApp == app) {
14175                    // found it; report which queue it's in
14176                    return queue;
14177                }
14178            }
14179        }
14180
14181        return null;
14182    }
14183
14184    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14185            boolean doingAll, long now) {
14186        if (mAdjSeq == app.adjSeq) {
14187            // This adjustment has already been computed.
14188            return app.curRawAdj;
14189        }
14190
14191        if (app.thread == null) {
14192            app.adjSeq = mAdjSeq;
14193            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14194            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14195            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14196        }
14197
14198        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14199        app.adjSource = null;
14200        app.adjTarget = null;
14201        app.empty = false;
14202        app.cached = false;
14203
14204        final int activitiesSize = app.activities.size();
14205
14206        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14207            // The max adjustment doesn't allow this app to be anything
14208            // below foreground, so it is not worth doing work for it.
14209            app.adjType = "fixed";
14210            app.adjSeq = mAdjSeq;
14211            app.curRawAdj = app.maxAdj;
14212            app.foregroundActivities = false;
14213            app.keeping = true;
14214            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14215            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14216            // System process can do UI, and when they do we want to have
14217            // them trim their memory after the user leaves the UI.  To
14218            // facilitate this, here we need to determine whether or not it
14219            // is currently showing UI.
14220            app.systemNoUi = true;
14221            if (app == TOP_APP) {
14222                app.systemNoUi = false;
14223            } else if (activitiesSize > 0) {
14224                for (int j = 0; j < activitiesSize; j++) {
14225                    final ActivityRecord r = app.activities.get(j);
14226                    if (r.visible) {
14227                        app.systemNoUi = false;
14228                    }
14229                }
14230            }
14231            if (!app.systemNoUi) {
14232                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14233            }
14234            return (app.curAdj=app.maxAdj);
14235        }
14236
14237        app.keeping = false;
14238        app.systemNoUi = false;
14239
14240        // Determine the importance of the process, starting with most
14241        // important to least, and assign an appropriate OOM adjustment.
14242        int adj;
14243        int schedGroup;
14244        int procState;
14245        boolean foregroundActivities = false;
14246        boolean interesting = false;
14247        BroadcastQueue queue;
14248        if (app == TOP_APP) {
14249            // The last app on the list is the foreground app.
14250            adj = ProcessList.FOREGROUND_APP_ADJ;
14251            schedGroup = Process.THREAD_GROUP_DEFAULT;
14252            app.adjType = "top-activity";
14253            foregroundActivities = true;
14254            interesting = true;
14255            procState = ActivityManager.PROCESS_STATE_TOP;
14256        } else if (app.instrumentationClass != null) {
14257            // Don't want to kill running instrumentation.
14258            adj = ProcessList.FOREGROUND_APP_ADJ;
14259            schedGroup = Process.THREAD_GROUP_DEFAULT;
14260            app.adjType = "instrumentation";
14261            interesting = true;
14262            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14263        } else if ((queue = isReceivingBroadcast(app)) != null) {
14264            // An app that is currently receiving a broadcast also
14265            // counts as being in the foreground for OOM killer purposes.
14266            // It's placed in a sched group based on the nature of the
14267            // broadcast as reflected by which queue it's active in.
14268            adj = ProcessList.FOREGROUND_APP_ADJ;
14269            schedGroup = (queue == mFgBroadcastQueue)
14270                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14271            app.adjType = "broadcast";
14272            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14273        } else if (app.executingServices.size() > 0) {
14274            // An app that is currently executing a service callback also
14275            // counts as being in the foreground.
14276            adj = ProcessList.FOREGROUND_APP_ADJ;
14277            schedGroup = app.execServicesFg ?
14278                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14279            app.adjType = "exec-service";
14280            procState = ActivityManager.PROCESS_STATE_SERVICE;
14281            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14282        } else {
14283            // As far as we know the process is empty.  We may change our mind later.
14284            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14285            // At this point we don't actually know the adjustment.  Use the cached adj
14286            // value that the caller wants us to.
14287            adj = cachedAdj;
14288            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14289            app.cached = true;
14290            app.empty = true;
14291            app.adjType = "cch-empty";
14292        }
14293
14294        // Examine all activities if not already foreground.
14295        if (!foregroundActivities && activitiesSize > 0) {
14296            for (int j = 0; j < activitiesSize; j++) {
14297                final ActivityRecord r = app.activities.get(j);
14298                if (r.app != app) {
14299                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14300                            + app + "?!?");
14301                    continue;
14302                }
14303                if (r.visible) {
14304                    // App has a visible activity; only upgrade adjustment.
14305                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14306                        adj = ProcessList.VISIBLE_APP_ADJ;
14307                        app.adjType = "visible";
14308                    }
14309                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14310                        procState = ActivityManager.PROCESS_STATE_TOP;
14311                    }
14312                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14313                    app.cached = false;
14314                    app.empty = false;
14315                    foregroundActivities = true;
14316                    break;
14317                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14318                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14319                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14320                        app.adjType = "pausing";
14321                    }
14322                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14323                        procState = ActivityManager.PROCESS_STATE_TOP;
14324                    }
14325                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14326                    app.cached = false;
14327                    app.empty = false;
14328                    foregroundActivities = true;
14329                } else if (r.state == ActivityState.STOPPING) {
14330                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14331                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14332                        app.adjType = "stopping";
14333                    }
14334                    // For the process state, we will at this point consider the
14335                    // process to be cached.  It will be cached either as an activity
14336                    // or empty depending on whether the activity is finishing.  We do
14337                    // this so that we can treat the process as cached for purposes of
14338                    // memory trimming (determing current memory level, trim command to
14339                    // send to process) since there can be an arbitrary number of stopping
14340                    // processes and they should soon all go into the cached state.
14341                    if (!r.finishing) {
14342                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14343                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14344                        }
14345                    }
14346                    app.cached = false;
14347                    app.empty = false;
14348                    foregroundActivities = true;
14349                } else {
14350                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14351                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14352                        app.adjType = "cch-act";
14353                    }
14354                }
14355            }
14356        }
14357
14358        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14359            if (app.foregroundServices) {
14360                // The user is aware of this app, so make it visible.
14361                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14362                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14363                app.cached = false;
14364                app.adjType = "fg-service";
14365                schedGroup = Process.THREAD_GROUP_DEFAULT;
14366            } else if (app.forcingToForeground != null) {
14367                // The user is aware of this app, so make it visible.
14368                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14369                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14370                app.cached = false;
14371                app.adjType = "force-fg";
14372                app.adjSource = app.forcingToForeground;
14373                schedGroup = Process.THREAD_GROUP_DEFAULT;
14374            }
14375        }
14376
14377        if (app.foregroundServices) {
14378            interesting = true;
14379        }
14380
14381        if (app == mHeavyWeightProcess) {
14382            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14383                // We don't want to kill the current heavy-weight process.
14384                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14385                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14386                app.cached = false;
14387                app.adjType = "heavy";
14388            }
14389            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14390                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14391            }
14392        }
14393
14394        if (app == mHomeProcess) {
14395            if (adj > ProcessList.HOME_APP_ADJ) {
14396                // This process is hosting what we currently consider to be the
14397                // home app, so we don't want to let it go into the background.
14398                adj = ProcessList.HOME_APP_ADJ;
14399                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14400                app.cached = false;
14401                app.adjType = "home";
14402            }
14403            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14404                procState = ActivityManager.PROCESS_STATE_HOME;
14405            }
14406        }
14407
14408        if (app == mPreviousProcess && app.activities.size() > 0) {
14409            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14410                // This was the previous process that showed UI to the user.
14411                // We want to try to keep it around more aggressively, to give
14412                // a good experience around switching between two apps.
14413                adj = ProcessList.PREVIOUS_APP_ADJ;
14414                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14415                app.cached = false;
14416                app.adjType = "previous";
14417            }
14418            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14419                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14420            }
14421        }
14422
14423        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14424                + " reason=" + app.adjType);
14425
14426        // By default, we use the computed adjustment.  It may be changed if
14427        // there are applications dependent on our services or providers, but
14428        // this gives us a baseline and makes sure we don't get into an
14429        // infinite recursion.
14430        app.adjSeq = mAdjSeq;
14431        app.curRawAdj = adj;
14432        app.hasStartedServices = false;
14433
14434        if (mBackupTarget != null && app == mBackupTarget.app) {
14435            // If possible we want to avoid killing apps while they're being backed up
14436            if (adj > ProcessList.BACKUP_APP_ADJ) {
14437                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14438                adj = ProcessList.BACKUP_APP_ADJ;
14439                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14440                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14441                }
14442                app.adjType = "backup";
14443                app.cached = false;
14444            }
14445            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14446                procState = ActivityManager.PROCESS_STATE_BACKUP;
14447            }
14448        }
14449
14450        boolean mayBeTop = false;
14451
14452        for (int is = app.services.size()-1;
14453                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14454                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14455                        || procState > ActivityManager.PROCESS_STATE_TOP);
14456                is--) {
14457            ServiceRecord s = app.services.valueAt(is);
14458            if (s.startRequested) {
14459                app.hasStartedServices = true;
14460                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14461                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14462                }
14463                if (app.hasShownUi && app != mHomeProcess) {
14464                    // If this process has shown some UI, let it immediately
14465                    // go to the LRU list because it may be pretty heavy with
14466                    // UI stuff.  We'll tag it with a label just to help
14467                    // debug and understand what is going on.
14468                    if (adj > ProcessList.SERVICE_ADJ) {
14469                        app.adjType = "cch-started-ui-services";
14470                    }
14471                } else {
14472                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14473                        // This service has seen some activity within
14474                        // recent memory, so we will keep its process ahead
14475                        // of the background processes.
14476                        if (adj > ProcessList.SERVICE_ADJ) {
14477                            adj = ProcessList.SERVICE_ADJ;
14478                            app.adjType = "started-services";
14479                            app.cached = false;
14480                        }
14481                    }
14482                    // If we have let the service slide into the background
14483                    // state, still have some text describing what it is doing
14484                    // even though the service no longer has an impact.
14485                    if (adj > ProcessList.SERVICE_ADJ) {
14486                        app.adjType = "cch-started-services";
14487                    }
14488                }
14489                // Don't kill this process because it is doing work; it
14490                // has said it is doing work.
14491                app.keeping = true;
14492            }
14493            for (int conni = s.connections.size()-1;
14494                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14495                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14496                            || procState > ActivityManager.PROCESS_STATE_TOP);
14497                    conni--) {
14498                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14499                for (int i = 0;
14500                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14501                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14502                                || procState > ActivityManager.PROCESS_STATE_TOP);
14503                        i++) {
14504                    // XXX should compute this based on the max of
14505                    // all connected clients.
14506                    ConnectionRecord cr = clist.get(i);
14507                    if (cr.binding.client == app) {
14508                        // Binding to ourself is not interesting.
14509                        continue;
14510                    }
14511                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14512                        ProcessRecord client = cr.binding.client;
14513                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14514                                TOP_APP, doingAll, now);
14515                        int clientProcState = client.curProcState;
14516                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14517                            // If the other app is cached for any reason, for purposes here
14518                            // we are going to consider it empty.  The specific cached state
14519                            // doesn't propagate except under certain conditions.
14520                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14521                        }
14522                        String adjType = null;
14523                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14524                            // Not doing bind OOM management, so treat
14525                            // this guy more like a started service.
14526                            if (app.hasShownUi && app != mHomeProcess) {
14527                                // If this process has shown some UI, let it immediately
14528                                // go to the LRU list because it may be pretty heavy with
14529                                // UI stuff.  We'll tag it with a label just to help
14530                                // debug and understand what is going on.
14531                                if (adj > clientAdj) {
14532                                    adjType = "cch-bound-ui-services";
14533                                }
14534                                app.cached = false;
14535                                clientAdj = adj;
14536                                clientProcState = procState;
14537                            } else {
14538                                if (now >= (s.lastActivity
14539                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14540                                    // This service has not seen activity within
14541                                    // recent memory, so allow it to drop to the
14542                                    // LRU list if there is no other reason to keep
14543                                    // it around.  We'll also tag it with a label just
14544                                    // to help debug and undertand what is going on.
14545                                    if (adj > clientAdj) {
14546                                        adjType = "cch-bound-services";
14547                                    }
14548                                    clientAdj = adj;
14549                                }
14550                            }
14551                        }
14552                        if (adj > clientAdj) {
14553                            // If this process has recently shown UI, and
14554                            // the process that is binding to it is less
14555                            // important than being visible, then we don't
14556                            // care about the binding as much as we care
14557                            // about letting this process get into the LRU
14558                            // list to be killed and restarted if needed for
14559                            // memory.
14560                            if (app.hasShownUi && app != mHomeProcess
14561                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14562                                adjType = "cch-bound-ui-services";
14563                            } else {
14564                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14565                                        |Context.BIND_IMPORTANT)) != 0) {
14566                                    adj = clientAdj;
14567                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14568                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14569                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14570                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14571                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14572                                    adj = clientAdj;
14573                                } else {
14574                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14575                                        adj = ProcessList.VISIBLE_APP_ADJ;
14576                                    }
14577                                }
14578                                if (!client.cached) {
14579                                    app.cached = false;
14580                                }
14581                                if (client.keeping) {
14582                                    app.keeping = true;
14583                                }
14584                                adjType = "service";
14585                            }
14586                        }
14587                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14588                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14589                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14590                            }
14591                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14592                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14593                                    // Special handling of clients who are in the top state.
14594                                    // We *may* want to consider this process to be in the
14595                                    // top state as well, but only if there is not another
14596                                    // reason for it to be running.  Being on the top is a
14597                                    // special state, meaning you are specifically running
14598                                    // for the current top app.  If the process is already
14599                                    // running in the background for some other reason, it
14600                                    // is more important to continue considering it to be
14601                                    // in the background state.
14602                                    mayBeTop = true;
14603                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14604                                } else {
14605                                    // Special handling for above-top states (persistent
14606                                    // processes).  These should not bring the current process
14607                                    // into the top state, since they are not on top.  Instead
14608                                    // give them the best state after that.
14609                                    clientProcState =
14610                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14611                                }
14612                            }
14613                        } else {
14614                            if (clientProcState <
14615                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14616                                clientProcState =
14617                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14618                            }
14619                        }
14620                        if (procState > clientProcState) {
14621                            procState = clientProcState;
14622                        }
14623                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14624                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14625                            app.pendingUiClean = true;
14626                        }
14627                        if (adjType != null) {
14628                            app.adjType = adjType;
14629                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14630                                    .REASON_SERVICE_IN_USE;
14631                            app.adjSource = cr.binding.client;
14632                            app.adjSourceOom = clientAdj;
14633                            app.adjTarget = s.name;
14634                        }
14635                    }
14636                    final ActivityRecord a = cr.activity;
14637                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14638                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14639                                (a.visible || a.state == ActivityState.RESUMED
14640                                 || a.state == ActivityState.PAUSING)) {
14641                            adj = ProcessList.FOREGROUND_APP_ADJ;
14642                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14643                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14644                            }
14645                            app.cached = false;
14646                            app.adjType = "service";
14647                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14648                                    .REASON_SERVICE_IN_USE;
14649                            app.adjSource = a;
14650                            app.adjSourceOom = adj;
14651                            app.adjTarget = s.name;
14652                        }
14653                    }
14654                }
14655            }
14656        }
14657
14658        for (int provi = app.pubProviders.size()-1;
14659                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14660                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14661                        || procState > ActivityManager.PROCESS_STATE_TOP);
14662                provi--) {
14663            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14664            for (int i = cpr.connections.size()-1;
14665                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14666                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14667                            || procState > ActivityManager.PROCESS_STATE_TOP);
14668                    i--) {
14669                ContentProviderConnection conn = cpr.connections.get(i);
14670                ProcessRecord client = conn.client;
14671                if (client == app) {
14672                    // Being our own client is not interesting.
14673                    continue;
14674                }
14675                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14676                int clientProcState = client.curProcState;
14677                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14678                    // If the other app is cached for any reason, for purposes here
14679                    // we are going to consider it empty.
14680                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14681                }
14682                if (adj > clientAdj) {
14683                    if (app.hasShownUi && app != mHomeProcess
14684                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14685                        app.adjType = "cch-ui-provider";
14686                    } else {
14687                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14688                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14689                        app.adjType = "provider";
14690                    }
14691                    app.cached &= client.cached;
14692                    app.keeping |= client.keeping;
14693                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14694                            .REASON_PROVIDER_IN_USE;
14695                    app.adjSource = client;
14696                    app.adjSourceOom = clientAdj;
14697                    app.adjTarget = cpr.name;
14698                }
14699                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14700                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14701                        // Special handling of clients who are in the top state.
14702                        // We *may* want to consider this process to be in the
14703                        // top state as well, but only if there is not another
14704                        // reason for it to be running.  Being on the top is a
14705                        // special state, meaning you are specifically running
14706                        // for the current top app.  If the process is already
14707                        // running in the background for some other reason, it
14708                        // is more important to continue considering it to be
14709                        // in the background state.
14710                        mayBeTop = true;
14711                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14712                    } else {
14713                        // Special handling for above-top states (persistent
14714                        // processes).  These should not bring the current process
14715                        // into the top state, since they are not on top.  Instead
14716                        // give them the best state after that.
14717                        clientProcState =
14718                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14719                    }
14720                }
14721                if (procState > clientProcState) {
14722                    procState = clientProcState;
14723                }
14724                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14725                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14726                }
14727            }
14728            // If the provider has external (non-framework) process
14729            // dependencies, ensure that its adjustment is at least
14730            // FOREGROUND_APP_ADJ.
14731            if (cpr.hasExternalProcessHandles()) {
14732                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14733                    adj = ProcessList.FOREGROUND_APP_ADJ;
14734                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14735                    app.cached = false;
14736                    app.keeping = true;
14737                    app.adjType = "provider";
14738                    app.adjTarget = cpr.name;
14739                }
14740                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14741                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14742                }
14743            }
14744        }
14745
14746        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14747            // A client of one of our services or providers is in the top state.  We
14748            // *may* want to be in the top state, but not if we are already running in
14749            // the background for some other reason.  For the decision here, we are going
14750            // to pick out a few specific states that we want to remain in when a client
14751            // is top (states that tend to be longer-term) and otherwise allow it to go
14752            // to the top state.
14753            switch (procState) {
14754                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14755                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14756                case ActivityManager.PROCESS_STATE_SERVICE:
14757                    // These all are longer-term states, so pull them up to the top
14758                    // of the background states, but not all the way to the top state.
14759                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14760                    break;
14761                default:
14762                    // Otherwise, top is a better choice, so take it.
14763                    procState = ActivityManager.PROCESS_STATE_TOP;
14764                    break;
14765            }
14766        }
14767
14768        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14769            // This is a cached process, but with client activities.  Mark it so.
14770            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14771            app.adjType = "cch-client-act";
14772        }
14773
14774        if (adj == ProcessList.SERVICE_ADJ) {
14775            if (doingAll) {
14776                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14777                mNewNumServiceProcs++;
14778                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14779                if (!app.serviceb) {
14780                    // This service isn't far enough down on the LRU list to
14781                    // normally be a B service, but if we are low on RAM and it
14782                    // is large we want to force it down since we would prefer to
14783                    // keep launcher over it.
14784                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14785                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14786                        app.serviceHighRam = true;
14787                        app.serviceb = true;
14788                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14789                    } else {
14790                        mNewNumAServiceProcs++;
14791                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14792                    }
14793                } else {
14794                    app.serviceHighRam = false;
14795                }
14796            }
14797            if (app.serviceb) {
14798                adj = ProcessList.SERVICE_B_ADJ;
14799            }
14800        }
14801
14802        app.curRawAdj = adj;
14803
14804        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14805        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14806        if (adj > app.maxAdj) {
14807            adj = app.maxAdj;
14808            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14809                schedGroup = Process.THREAD_GROUP_DEFAULT;
14810            }
14811        }
14812        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14813            app.keeping = true;
14814        }
14815
14816        // Do final modification to adj.  Everything we do between here and applying
14817        // the final setAdj must be done in this function, because we will also use
14818        // it when computing the final cached adj later.  Note that we don't need to
14819        // worry about this for max adj above, since max adj will always be used to
14820        // keep it out of the cached vaues.
14821        adj = app.modifyRawOomAdj(adj);
14822
14823        app.curProcState = procState;
14824
14825        int importance = app.memImportance;
14826        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14827            app.curAdj = adj;
14828            app.curSchedGroup = schedGroup;
14829            if (!interesting) {
14830                // For this reporting, if there is not something explicitly
14831                // interesting in this process then we will push it to the
14832                // background importance.
14833                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14834            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14835                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14836            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14837                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14838            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14839                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14840            } else if (adj >= ProcessList.SERVICE_ADJ) {
14841                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14842            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14843                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14844            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14845                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14846            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14847                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14848            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14849                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14850            } else {
14851                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14852            }
14853        }
14854
14855        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14856        if (foregroundActivities != app.foregroundActivities) {
14857            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14858        }
14859        if (changes != 0) {
14860            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14861            app.memImportance = importance;
14862            app.foregroundActivities = foregroundActivities;
14863            int i = mPendingProcessChanges.size()-1;
14864            ProcessChangeItem item = null;
14865            while (i >= 0) {
14866                item = mPendingProcessChanges.get(i);
14867                if (item.pid == app.pid) {
14868                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14869                    break;
14870                }
14871                i--;
14872            }
14873            if (i < 0) {
14874                // No existing item in pending changes; need a new one.
14875                final int NA = mAvailProcessChanges.size();
14876                if (NA > 0) {
14877                    item = mAvailProcessChanges.remove(NA-1);
14878                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14879                } else {
14880                    item = new ProcessChangeItem();
14881                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14882                }
14883                item.changes = 0;
14884                item.pid = app.pid;
14885                item.uid = app.info.uid;
14886                if (mPendingProcessChanges.size() == 0) {
14887                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14888                            "*** Enqueueing dispatch processes changed!");
14889                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14890                }
14891                mPendingProcessChanges.add(item);
14892            }
14893            item.changes |= changes;
14894            item.importance = importance;
14895            item.foregroundActivities = foregroundActivities;
14896            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14897                    + Integer.toHexString(System.identityHashCode(item))
14898                    + " " + app.toShortString() + ": changes=" + item.changes
14899                    + " importance=" + item.importance
14900                    + " foreground=" + item.foregroundActivities
14901                    + " type=" + app.adjType + " source=" + app.adjSource
14902                    + " target=" + app.adjTarget);
14903        }
14904
14905        return app.curRawAdj;
14906    }
14907
14908    /**
14909     * Schedule PSS collection of a process.
14910     */
14911    void requestPssLocked(ProcessRecord proc, int procState) {
14912        if (mPendingPssProcesses.contains(proc)) {
14913            return;
14914        }
14915        if (mPendingPssProcesses.size() == 0) {
14916            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14917        }
14918        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
14919        proc.pssProcState = procState;
14920        mPendingPssProcesses.add(proc);
14921    }
14922
14923    /**
14924     * Schedule PSS collection of all processes.
14925     */
14926    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
14927        if (!always) {
14928            if (now < (mLastFullPssTime +
14929                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
14930                return;
14931            }
14932        }
14933        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
14934        mLastFullPssTime = now;
14935        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
14936        mPendingPssProcesses.clear();
14937        for (int i=mLruProcesses.size()-1; i>=0; i--) {
14938            ProcessRecord app = mLruProcesses.get(i);
14939            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
14940                app.pssProcState = app.setProcState;
14941                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
14942                        mSleeping, now);
14943                mPendingPssProcesses.add(app);
14944            }
14945        }
14946        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14947    }
14948
14949    /**
14950     * Ask a given process to GC right now.
14951     */
14952    final void performAppGcLocked(ProcessRecord app) {
14953        try {
14954            app.lastRequestedGc = SystemClock.uptimeMillis();
14955            if (app.thread != null) {
14956                if (app.reportLowMemory) {
14957                    app.reportLowMemory = false;
14958                    app.thread.scheduleLowMemory();
14959                } else {
14960                    app.thread.processInBackground();
14961                }
14962            }
14963        } catch (Exception e) {
14964            // whatever.
14965        }
14966    }
14967
14968    /**
14969     * Returns true if things are idle enough to perform GCs.
14970     */
14971    private final boolean canGcNowLocked() {
14972        boolean processingBroadcasts = false;
14973        for (BroadcastQueue q : mBroadcastQueues) {
14974            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14975                processingBroadcasts = true;
14976            }
14977        }
14978        return !processingBroadcasts
14979                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
14980    }
14981
14982    /**
14983     * Perform GCs on all processes that are waiting for it, but only
14984     * if things are idle.
14985     */
14986    final void performAppGcsLocked() {
14987        final int N = mProcessesToGc.size();
14988        if (N <= 0) {
14989            return;
14990        }
14991        if (canGcNowLocked()) {
14992            while (mProcessesToGc.size() > 0) {
14993                ProcessRecord proc = mProcessesToGc.remove(0);
14994                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
14995                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14996                            <= SystemClock.uptimeMillis()) {
14997                        // To avoid spamming the system, we will GC processes one
14998                        // at a time, waiting a few seconds between each.
14999                        performAppGcLocked(proc);
15000                        scheduleAppGcsLocked();
15001                        return;
15002                    } else {
15003                        // It hasn't been long enough since we last GCed this
15004                        // process...  put it in the list to wait for its time.
15005                        addProcessToGcListLocked(proc);
15006                        break;
15007                    }
15008                }
15009            }
15010
15011            scheduleAppGcsLocked();
15012        }
15013    }
15014
15015    /**
15016     * If all looks good, perform GCs on all processes waiting for them.
15017     */
15018    final void performAppGcsIfAppropriateLocked() {
15019        if (canGcNowLocked()) {
15020            performAppGcsLocked();
15021            return;
15022        }
15023        // Still not idle, wait some more.
15024        scheduleAppGcsLocked();
15025    }
15026
15027    /**
15028     * Schedule the execution of all pending app GCs.
15029     */
15030    final void scheduleAppGcsLocked() {
15031        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15032
15033        if (mProcessesToGc.size() > 0) {
15034            // Schedule a GC for the time to the next process.
15035            ProcessRecord proc = mProcessesToGc.get(0);
15036            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15037
15038            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15039            long now = SystemClock.uptimeMillis();
15040            if (when < (now+GC_TIMEOUT)) {
15041                when = now + GC_TIMEOUT;
15042            }
15043            mHandler.sendMessageAtTime(msg, when);
15044        }
15045    }
15046
15047    /**
15048     * Add a process to the array of processes waiting to be GCed.  Keeps the
15049     * list in sorted order by the last GC time.  The process can't already be
15050     * on the list.
15051     */
15052    final void addProcessToGcListLocked(ProcessRecord proc) {
15053        boolean added = false;
15054        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15055            if (mProcessesToGc.get(i).lastRequestedGc <
15056                    proc.lastRequestedGc) {
15057                added = true;
15058                mProcessesToGc.add(i+1, proc);
15059                break;
15060            }
15061        }
15062        if (!added) {
15063            mProcessesToGc.add(0, proc);
15064        }
15065    }
15066
15067    /**
15068     * Set up to ask a process to GC itself.  This will either do it
15069     * immediately, or put it on the list of processes to gc the next
15070     * time things are idle.
15071     */
15072    final void scheduleAppGcLocked(ProcessRecord app) {
15073        long now = SystemClock.uptimeMillis();
15074        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15075            return;
15076        }
15077        if (!mProcessesToGc.contains(app)) {
15078            addProcessToGcListLocked(app);
15079            scheduleAppGcsLocked();
15080        }
15081    }
15082
15083    final void checkExcessivePowerUsageLocked(boolean doKills) {
15084        updateCpuStatsNow();
15085
15086        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15087        boolean doWakeKills = doKills;
15088        boolean doCpuKills = doKills;
15089        if (mLastPowerCheckRealtime == 0) {
15090            doWakeKills = false;
15091        }
15092        if (mLastPowerCheckUptime == 0) {
15093            doCpuKills = false;
15094        }
15095        if (stats.isScreenOn()) {
15096            doWakeKills = false;
15097        }
15098        final long curRealtime = SystemClock.elapsedRealtime();
15099        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15100        final long curUptime = SystemClock.uptimeMillis();
15101        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15102        mLastPowerCheckRealtime = curRealtime;
15103        mLastPowerCheckUptime = curUptime;
15104        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15105            doWakeKills = false;
15106        }
15107        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15108            doCpuKills = false;
15109        }
15110        int i = mLruProcesses.size();
15111        while (i > 0) {
15112            i--;
15113            ProcessRecord app = mLruProcesses.get(i);
15114            if (!app.keeping) {
15115                long wtime;
15116                synchronized (stats) {
15117                    wtime = stats.getProcessWakeTime(app.info.uid,
15118                            app.pid, curRealtime);
15119                }
15120                long wtimeUsed = wtime - app.lastWakeTime;
15121                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15122                if (DEBUG_POWER) {
15123                    StringBuilder sb = new StringBuilder(128);
15124                    sb.append("Wake for ");
15125                    app.toShortString(sb);
15126                    sb.append(": over ");
15127                    TimeUtils.formatDuration(realtimeSince, sb);
15128                    sb.append(" used ");
15129                    TimeUtils.formatDuration(wtimeUsed, sb);
15130                    sb.append(" (");
15131                    sb.append((wtimeUsed*100)/realtimeSince);
15132                    sb.append("%)");
15133                    Slog.i(TAG, sb.toString());
15134                    sb.setLength(0);
15135                    sb.append("CPU for ");
15136                    app.toShortString(sb);
15137                    sb.append(": over ");
15138                    TimeUtils.formatDuration(uptimeSince, sb);
15139                    sb.append(" used ");
15140                    TimeUtils.formatDuration(cputimeUsed, sb);
15141                    sb.append(" (");
15142                    sb.append((cputimeUsed*100)/uptimeSince);
15143                    sb.append("%)");
15144                    Slog.i(TAG, sb.toString());
15145                }
15146                // If a process has held a wake lock for more
15147                // than 50% of the time during this period,
15148                // that sounds bad.  Kill!
15149                if (doWakeKills && realtimeSince > 0
15150                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15151                    synchronized (stats) {
15152                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15153                                realtimeSince, wtimeUsed);
15154                    }
15155                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15156                            + " during " + realtimeSince);
15157                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15158                } else if (doCpuKills && uptimeSince > 0
15159                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15160                    synchronized (stats) {
15161                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15162                                uptimeSince, cputimeUsed);
15163                    }
15164                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15165                            + " during " + uptimeSince);
15166                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15167                } else {
15168                    app.lastWakeTime = wtime;
15169                    app.lastCpuTime = app.curCpuTime;
15170                }
15171            }
15172        }
15173    }
15174
15175    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15176            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15177        boolean success = true;
15178
15179        if (app.curRawAdj != app.setRawAdj) {
15180            if (wasKeeping && !app.keeping) {
15181                // This app is no longer something we want to keep.  Note
15182                // its current wake lock time to later know to kill it if
15183                // it is not behaving well.
15184                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15185                synchronized (stats) {
15186                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15187                            app.pid, SystemClock.elapsedRealtime());
15188                }
15189                app.lastCpuTime = app.curCpuTime;
15190            }
15191
15192            app.setRawAdj = app.curRawAdj;
15193        }
15194
15195        if (app.curAdj != app.setAdj) {
15196            if (Process.setOomAdj(app.pid, app.curAdj)) {
15197                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15198                    TAG, "Set " + app.pid + " " + app.processName +
15199                    " adj " + app.curAdj + ": " + app.adjType);
15200                app.setAdj = app.curAdj;
15201            } else {
15202                success = false;
15203                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
15204            }
15205        }
15206        if (app.setSchedGroup != app.curSchedGroup) {
15207            app.setSchedGroup = app.curSchedGroup;
15208            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15209                    "Setting process group of " + app.processName
15210                    + " to " + app.curSchedGroup);
15211            if (app.waitingToKill != null &&
15212                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15213                killUnneededProcessLocked(app, app.waitingToKill);
15214                success = false;
15215            } else {
15216                if (true) {
15217                    long oldId = Binder.clearCallingIdentity();
15218                    try {
15219                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15220                    } catch (Exception e) {
15221                        Slog.w(TAG, "Failed setting process group of " + app.pid
15222                                + " to " + app.curSchedGroup);
15223                        e.printStackTrace();
15224                    } finally {
15225                        Binder.restoreCallingIdentity(oldId);
15226                    }
15227                } else {
15228                    if (app.thread != null) {
15229                        try {
15230                            app.thread.setSchedulingGroup(app.curSchedGroup);
15231                        } catch (RemoteException e) {
15232                        }
15233                    }
15234                }
15235                Process.setSwappiness(app.pid,
15236                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15237            }
15238        }
15239        if (app.repProcState != app.curProcState) {
15240            app.repProcState = app.curProcState;
15241            if (!reportingProcessState && app.thread != null) {
15242                try {
15243                    if (false) {
15244                        //RuntimeException h = new RuntimeException("here");
15245                        Slog.i(TAG, "Sending new process state " + app.repProcState
15246                                + " to " + app /*, h*/);
15247                    }
15248                    app.thread.setProcessState(app.repProcState);
15249                } catch (RemoteException e) {
15250                }
15251            }
15252        }
15253        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15254                app.setProcState)) {
15255            app.lastStateTime = now;
15256            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15257                    mSleeping, now);
15258            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15259                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15260                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15261                    + (app.nextPssTime-now) + ": " + app);
15262        } else {
15263            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15264                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15265                requestPssLocked(app, app.setProcState);
15266                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15267                        mSleeping, now);
15268            } else if (false && DEBUG_PSS) {
15269                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15270            }
15271        }
15272        if (app.setProcState != app.curProcState) {
15273            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15274                    "Proc state change of " + app.processName
15275                    + " to " + app.curProcState);
15276            app.setProcState = app.curProcState;
15277            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15278                app.notCachedSinceIdle = false;
15279            }
15280            if (!doingAll) {
15281                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15282            } else {
15283                app.procStateChanged = true;
15284            }
15285        }
15286        return success;
15287    }
15288
15289    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15290        if (proc.thread != null && proc.baseProcessTracker != null) {
15291            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15292        }
15293    }
15294
15295    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15296            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15297        if (app.thread == null) {
15298            return false;
15299        }
15300
15301        final boolean wasKeeping = app.keeping;
15302
15303        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15304
15305        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15306                reportingProcessState, now);
15307    }
15308
15309    private final ActivityRecord resumedAppLocked() {
15310        return mStackSupervisor.resumedAppLocked();
15311    }
15312
15313    final boolean updateOomAdjLocked(ProcessRecord app) {
15314        return updateOomAdjLocked(app, false);
15315    }
15316
15317    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15318        final ActivityRecord TOP_ACT = resumedAppLocked();
15319        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15320        final boolean wasCached = app.cached;
15321
15322        mAdjSeq++;
15323
15324        // This is the desired cached adjusment we want to tell it to use.
15325        // If our app is currently cached, we know it, and that is it.  Otherwise,
15326        // we don't know it yet, and it needs to now be cached we will then
15327        // need to do a complete oom adj.
15328        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15329                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15330        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15331                SystemClock.uptimeMillis());
15332        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15333            // Changed to/from cached state, so apps after it in the LRU
15334            // list may also be changed.
15335            updateOomAdjLocked();
15336        }
15337        return success;
15338    }
15339
15340    final void updateOomAdjLocked() {
15341        final ActivityRecord TOP_ACT = resumedAppLocked();
15342        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15343        final long now = SystemClock.uptimeMillis();
15344        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15345        final int N = mLruProcesses.size();
15346
15347        if (false) {
15348            RuntimeException e = new RuntimeException();
15349            e.fillInStackTrace();
15350            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15351        }
15352
15353        mAdjSeq++;
15354        mNewNumServiceProcs = 0;
15355        mNewNumAServiceProcs = 0;
15356
15357        final int emptyProcessLimit;
15358        final int cachedProcessLimit;
15359        if (mProcessLimit <= 0) {
15360            emptyProcessLimit = cachedProcessLimit = 0;
15361        } else if (mProcessLimit == 1) {
15362            emptyProcessLimit = 1;
15363            cachedProcessLimit = 0;
15364        } else {
15365            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15366            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15367        }
15368
15369        // Let's determine how many processes we have running vs.
15370        // how many slots we have for background processes; we may want
15371        // to put multiple processes in a slot of there are enough of
15372        // them.
15373        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15374                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15375        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15376        if (numEmptyProcs > cachedProcessLimit) {
15377            // If there are more empty processes than our limit on cached
15378            // processes, then use the cached process limit for the factor.
15379            // This ensures that the really old empty processes get pushed
15380            // down to the bottom, so if we are running low on memory we will
15381            // have a better chance at keeping around more cached processes
15382            // instead of a gazillion empty processes.
15383            numEmptyProcs = cachedProcessLimit;
15384        }
15385        int emptyFactor = numEmptyProcs/numSlots;
15386        if (emptyFactor < 1) emptyFactor = 1;
15387        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15388        if (cachedFactor < 1) cachedFactor = 1;
15389        int stepCached = 0;
15390        int stepEmpty = 0;
15391        int numCached = 0;
15392        int numEmpty = 0;
15393        int numTrimming = 0;
15394
15395        mNumNonCachedProcs = 0;
15396        mNumCachedHiddenProcs = 0;
15397
15398        // First update the OOM adjustment for each of the
15399        // application processes based on their current state.
15400        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15401        int nextCachedAdj = curCachedAdj+1;
15402        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15403        int nextEmptyAdj = curEmptyAdj+2;
15404        for (int i=N-1; i>=0; i--) {
15405            ProcessRecord app = mLruProcesses.get(i);
15406            if (!app.killedByAm && app.thread != null) {
15407                app.procStateChanged = false;
15408                final boolean wasKeeping = app.keeping;
15409                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15410
15411                // If we haven't yet assigned the final cached adj
15412                // to the process, do that now.
15413                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15414                    switch (app.curProcState) {
15415                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15416                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15417                            // This process is a cached process holding activities...
15418                            // assign it the next cached value for that type, and then
15419                            // step that cached level.
15420                            app.curRawAdj = curCachedAdj;
15421                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15422                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15423                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15424                                    + ")");
15425                            if (curCachedAdj != nextCachedAdj) {
15426                                stepCached++;
15427                                if (stepCached >= cachedFactor) {
15428                                    stepCached = 0;
15429                                    curCachedAdj = nextCachedAdj;
15430                                    nextCachedAdj += 2;
15431                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15432                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15433                                    }
15434                                }
15435                            }
15436                            break;
15437                        default:
15438                            // For everything else, assign next empty cached process
15439                            // level and bump that up.  Note that this means that
15440                            // long-running services that have dropped down to the
15441                            // cached level will be treated as empty (since their process
15442                            // state is still as a service), which is what we want.
15443                            app.curRawAdj = curEmptyAdj;
15444                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15445                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15446                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15447                                    + ")");
15448                            if (curEmptyAdj != nextEmptyAdj) {
15449                                stepEmpty++;
15450                                if (stepEmpty >= emptyFactor) {
15451                                    stepEmpty = 0;
15452                                    curEmptyAdj = nextEmptyAdj;
15453                                    nextEmptyAdj += 2;
15454                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15455                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15456                                    }
15457                                }
15458                            }
15459                            break;
15460                    }
15461                }
15462
15463                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15464
15465                // Count the number of process types.
15466                switch (app.curProcState) {
15467                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15468                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15469                        mNumCachedHiddenProcs++;
15470                        numCached++;
15471                        if (numCached > cachedProcessLimit) {
15472                            killUnneededProcessLocked(app, "cached #" + numCached);
15473                        }
15474                        break;
15475                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15476                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15477                                && app.lastActivityTime < oldTime) {
15478                            killUnneededProcessLocked(app, "empty for "
15479                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15480                                    / 1000) + "s");
15481                        } else {
15482                            numEmpty++;
15483                            if (numEmpty > emptyProcessLimit) {
15484                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15485                            }
15486                        }
15487                        break;
15488                    default:
15489                        mNumNonCachedProcs++;
15490                        break;
15491                }
15492
15493                if (app.isolated && app.services.size() <= 0) {
15494                    // If this is an isolated process, and there are no
15495                    // services running in it, then the process is no longer
15496                    // needed.  We agressively kill these because we can by
15497                    // definition not re-use the same process again, and it is
15498                    // good to avoid having whatever code was running in them
15499                    // left sitting around after no longer needed.
15500                    killUnneededProcessLocked(app, "isolated not needed");
15501                }
15502
15503                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15504                        && !app.killedByAm) {
15505                    numTrimming++;
15506                }
15507            }
15508        }
15509
15510        mNumServiceProcs = mNewNumServiceProcs;
15511
15512        // Now determine the memory trimming level of background processes.
15513        // Unfortunately we need to start at the back of the list to do this
15514        // properly.  We only do this if the number of background apps we
15515        // are managing to keep around is less than half the maximum we desire;
15516        // if we are keeping a good number around, we'll let them use whatever
15517        // memory they want.
15518        final int numCachedAndEmpty = numCached + numEmpty;
15519        int memFactor;
15520        if (numCached <= ProcessList.TRIM_CACHED_APPS
15521                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15522            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15523                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15524            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15525                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15526            } else {
15527                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15528            }
15529        } else {
15530            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15531        }
15532        // We always allow the memory level to go up (better).  We only allow it to go
15533        // down if we are in a state where that is allowed, *and* the total number of processes
15534        // has gone down since last time.
15535        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15536                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15537                + " last=" + mLastNumProcesses);
15538        if (memFactor > mLastMemoryLevel) {
15539            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15540                memFactor = mLastMemoryLevel;
15541                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15542            }
15543        }
15544        mLastMemoryLevel = memFactor;
15545        mLastNumProcesses = mLruProcesses.size();
15546        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15547        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15548        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15549            if (mLowRamStartTime == 0) {
15550                mLowRamStartTime = now;
15551            }
15552            int step = 0;
15553            int fgTrimLevel;
15554            switch (memFactor) {
15555                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15556                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15557                    break;
15558                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15559                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15560                    break;
15561                default:
15562                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15563                    break;
15564            }
15565            int factor = numTrimming/3;
15566            int minFactor = 2;
15567            if (mHomeProcess != null) minFactor++;
15568            if (mPreviousProcess != null) minFactor++;
15569            if (factor < minFactor) factor = minFactor;
15570            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15571            for (int i=N-1; i>=0; i--) {
15572                ProcessRecord app = mLruProcesses.get(i);
15573                if (allChanged || app.procStateChanged) {
15574                    setProcessTrackerState(app, trackerMemFactor, now);
15575                    app.procStateChanged = false;
15576                }
15577                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15578                        && !app.killedByAm) {
15579                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15580                        try {
15581                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15582                                    "Trimming memory of " + app.processName
15583                                    + " to " + curLevel);
15584                            app.thread.scheduleTrimMemory(curLevel);
15585                        } catch (RemoteException e) {
15586                        }
15587                        if (false) {
15588                            // For now we won't do this; our memory trimming seems
15589                            // to be good enough at this point that destroying
15590                            // activities causes more harm than good.
15591                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15592                                    && app != mHomeProcess && app != mPreviousProcess) {
15593                                // Need to do this on its own message because the stack may not
15594                                // be in a consistent state at this point.
15595                                // For these apps we will also finish their activities
15596                                // to help them free memory.
15597                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15598                            }
15599                        }
15600                    }
15601                    app.trimMemoryLevel = curLevel;
15602                    step++;
15603                    if (step >= factor) {
15604                        step = 0;
15605                        switch (curLevel) {
15606                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15607                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15608                                break;
15609                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15610                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15611                                break;
15612                        }
15613                    }
15614                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15615                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15616                            && app.thread != null) {
15617                        try {
15618                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15619                                    "Trimming memory of heavy-weight " + app.processName
15620                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15621                            app.thread.scheduleTrimMemory(
15622                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15623                        } catch (RemoteException e) {
15624                        }
15625                    }
15626                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15627                } else {
15628                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15629                            || app.systemNoUi) && app.pendingUiClean) {
15630                        // If this application is now in the background and it
15631                        // had done UI, then give it the special trim level to
15632                        // have it free UI resources.
15633                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15634                        if (app.trimMemoryLevel < level && app.thread != null) {
15635                            try {
15636                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15637                                        "Trimming memory of bg-ui " + app.processName
15638                                        + " to " + level);
15639                                app.thread.scheduleTrimMemory(level);
15640                            } catch (RemoteException e) {
15641                            }
15642                        }
15643                        app.pendingUiClean = false;
15644                    }
15645                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15646                        try {
15647                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15648                                    "Trimming memory of fg " + app.processName
15649                                    + " to " + fgTrimLevel);
15650                            app.thread.scheduleTrimMemory(fgTrimLevel);
15651                        } catch (RemoteException e) {
15652                        }
15653                    }
15654                    app.trimMemoryLevel = fgTrimLevel;
15655                }
15656            }
15657        } else {
15658            if (mLowRamStartTime != 0) {
15659                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15660                mLowRamStartTime = 0;
15661            }
15662            for (int i=N-1; i>=0; i--) {
15663                ProcessRecord app = mLruProcesses.get(i);
15664                if (allChanged || app.procStateChanged) {
15665                    setProcessTrackerState(app, trackerMemFactor, now);
15666                    app.procStateChanged = false;
15667                }
15668                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15669                        || app.systemNoUi) && app.pendingUiClean) {
15670                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15671                            && app.thread != null) {
15672                        try {
15673                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15674                                    "Trimming memory of ui hidden " + app.processName
15675                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15676                            app.thread.scheduleTrimMemory(
15677                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15678                        } catch (RemoteException e) {
15679                        }
15680                    }
15681                    app.pendingUiClean = false;
15682                }
15683                app.trimMemoryLevel = 0;
15684            }
15685        }
15686
15687        if (mAlwaysFinishActivities) {
15688            // Need to do this on its own message because the stack may not
15689            // be in a consistent state at this point.
15690            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15691        }
15692
15693        if (allChanged) {
15694            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15695        }
15696
15697        if (mProcessStats.shouldWriteNowLocked(now)) {
15698            mHandler.post(new Runnable() {
15699                @Override public void run() {
15700                    synchronized (ActivityManagerService.this) {
15701                        mProcessStats.writeStateAsyncLocked();
15702                    }
15703                }
15704            });
15705        }
15706
15707        if (DEBUG_OOM_ADJ) {
15708            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15709        }
15710    }
15711
15712    final void trimApplications() {
15713        synchronized (this) {
15714            int i;
15715
15716            // First remove any unused application processes whose package
15717            // has been removed.
15718            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15719                final ProcessRecord app = mRemovedProcesses.get(i);
15720                if (app.activities.size() == 0
15721                        && app.curReceiver == null && app.services.size() == 0) {
15722                    Slog.i(
15723                        TAG, "Exiting empty application process "
15724                        + app.processName + " ("
15725                        + (app.thread != null ? app.thread.asBinder() : null)
15726                        + ")\n");
15727                    if (app.pid > 0 && app.pid != MY_PID) {
15728                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15729                                app.processName, app.setAdj, "empty");
15730                        app.killedByAm = true;
15731                        Process.killProcessQuiet(app.pid);
15732                    } else {
15733                        try {
15734                            app.thread.scheduleExit();
15735                        } catch (Exception e) {
15736                            // Ignore exceptions.
15737                        }
15738                    }
15739                    cleanUpApplicationRecordLocked(app, false, true, -1);
15740                    mRemovedProcesses.remove(i);
15741
15742                    if (app.persistent) {
15743                        if (app.persistent) {
15744                            addAppLocked(app.info, false);
15745                        }
15746                    }
15747                }
15748            }
15749
15750            // Now update the oom adj for all processes.
15751            updateOomAdjLocked();
15752        }
15753    }
15754
15755    /** This method sends the specified signal to each of the persistent apps */
15756    public void signalPersistentProcesses(int sig) throws RemoteException {
15757        if (sig != Process.SIGNAL_USR1) {
15758            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15759        }
15760
15761        synchronized (this) {
15762            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15763                    != PackageManager.PERMISSION_GRANTED) {
15764                throw new SecurityException("Requires permission "
15765                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15766            }
15767
15768            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15769                ProcessRecord r = mLruProcesses.get(i);
15770                if (r.thread != null && r.persistent) {
15771                    Process.sendSignal(r.pid, sig);
15772                }
15773            }
15774        }
15775    }
15776
15777    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15778        if (proc == null || proc == mProfileProc) {
15779            proc = mProfileProc;
15780            path = mProfileFile;
15781            profileType = mProfileType;
15782            clearProfilerLocked();
15783        }
15784        if (proc == null) {
15785            return;
15786        }
15787        try {
15788            proc.thread.profilerControl(false, path, null, profileType);
15789        } catch (RemoteException e) {
15790            throw new IllegalStateException("Process disappeared");
15791        }
15792    }
15793
15794    private void clearProfilerLocked() {
15795        if (mProfileFd != null) {
15796            try {
15797                mProfileFd.close();
15798            } catch (IOException e) {
15799            }
15800        }
15801        mProfileApp = null;
15802        mProfileProc = null;
15803        mProfileFile = null;
15804        mProfileType = 0;
15805        mAutoStopProfiler = false;
15806    }
15807
15808    public boolean profileControl(String process, int userId, boolean start,
15809            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15810
15811        try {
15812            synchronized (this) {
15813                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15814                // its own permission.
15815                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15816                        != PackageManager.PERMISSION_GRANTED) {
15817                    throw new SecurityException("Requires permission "
15818                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15819                }
15820
15821                if (start && fd == null) {
15822                    throw new IllegalArgumentException("null fd");
15823                }
15824
15825                ProcessRecord proc = null;
15826                if (process != null) {
15827                    proc = findProcessLocked(process, userId, "profileControl");
15828                }
15829
15830                if (start && (proc == null || proc.thread == null)) {
15831                    throw new IllegalArgumentException("Unknown process: " + process);
15832                }
15833
15834                if (start) {
15835                    stopProfilerLocked(null, null, 0);
15836                    setProfileApp(proc.info, proc.processName, path, fd, false);
15837                    mProfileProc = proc;
15838                    mProfileType = profileType;
15839                    try {
15840                        fd = fd.dup();
15841                    } catch (IOException e) {
15842                        fd = null;
15843                    }
15844                    proc.thread.profilerControl(start, path, fd, profileType);
15845                    fd = null;
15846                    mProfileFd = null;
15847                } else {
15848                    stopProfilerLocked(proc, path, profileType);
15849                    if (fd != null) {
15850                        try {
15851                            fd.close();
15852                        } catch (IOException e) {
15853                        }
15854                    }
15855                }
15856
15857                return true;
15858            }
15859        } catch (RemoteException e) {
15860            throw new IllegalStateException("Process disappeared");
15861        } finally {
15862            if (fd != null) {
15863                try {
15864                    fd.close();
15865                } catch (IOException e) {
15866                }
15867            }
15868        }
15869    }
15870
15871    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15872        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15873                userId, true, true, callName, null);
15874        ProcessRecord proc = null;
15875        try {
15876            int pid = Integer.parseInt(process);
15877            synchronized (mPidsSelfLocked) {
15878                proc = mPidsSelfLocked.get(pid);
15879            }
15880        } catch (NumberFormatException e) {
15881        }
15882
15883        if (proc == null) {
15884            ArrayMap<String, SparseArray<ProcessRecord>> all
15885                    = mProcessNames.getMap();
15886            SparseArray<ProcessRecord> procs = all.get(process);
15887            if (procs != null && procs.size() > 0) {
15888                proc = procs.valueAt(0);
15889                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
15890                    for (int i=1; i<procs.size(); i++) {
15891                        ProcessRecord thisProc = procs.valueAt(i);
15892                        if (thisProc.userId == userId) {
15893                            proc = thisProc;
15894                            break;
15895                        }
15896                    }
15897                }
15898            }
15899        }
15900
15901        return proc;
15902    }
15903
15904    public boolean dumpHeap(String process, int userId, boolean managed,
15905            String path, ParcelFileDescriptor fd) throws RemoteException {
15906
15907        try {
15908            synchronized (this) {
15909                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15910                // its own permission (same as profileControl).
15911                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15912                        != PackageManager.PERMISSION_GRANTED) {
15913                    throw new SecurityException("Requires permission "
15914                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15915                }
15916
15917                if (fd == null) {
15918                    throw new IllegalArgumentException("null fd");
15919                }
15920
15921                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
15922                if (proc == null || proc.thread == null) {
15923                    throw new IllegalArgumentException("Unknown process: " + process);
15924                }
15925
15926                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15927                if (!isDebuggable) {
15928                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15929                        throw new SecurityException("Process not debuggable: " + proc);
15930                    }
15931                }
15932
15933                proc.thread.dumpHeap(managed, path, fd);
15934                fd = null;
15935                return true;
15936            }
15937        } catch (RemoteException e) {
15938            throw new IllegalStateException("Process disappeared");
15939        } finally {
15940            if (fd != null) {
15941                try {
15942                    fd.close();
15943                } catch (IOException e) {
15944                }
15945            }
15946        }
15947    }
15948
15949    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15950    public void monitor() {
15951        synchronized (this) { }
15952    }
15953
15954    void onCoreSettingsChange(Bundle settings) {
15955        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15956            ProcessRecord processRecord = mLruProcesses.get(i);
15957            try {
15958                if (processRecord.thread != null) {
15959                    processRecord.thread.setCoreSettings(settings);
15960                }
15961            } catch (RemoteException re) {
15962                /* ignore */
15963            }
15964        }
15965    }
15966
15967    // Multi-user methods
15968
15969    @Override
15970    public boolean switchUser(final int userId) {
15971        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
15972                != PackageManager.PERMISSION_GRANTED) {
15973            String msg = "Permission Denial: switchUser() from pid="
15974                    + Binder.getCallingPid()
15975                    + ", uid=" + Binder.getCallingUid()
15976                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
15977            Slog.w(TAG, msg);
15978            throw new SecurityException(msg);
15979        }
15980
15981        final long ident = Binder.clearCallingIdentity();
15982        try {
15983            synchronized (this) {
15984                final int oldUserId = mCurrentUserId;
15985                if (oldUserId == userId) {
15986                    return true;
15987                }
15988
15989                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
15990                if (userInfo == null) {
15991                    Slog.w(TAG, "No user info for user #" + userId);
15992                    return false;
15993                }
15994
15995                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
15996                        R.anim.screen_user_enter);
15997
15998                boolean needStart = false;
15999
16000                // If the user we are switching to is not currently started, then
16001                // we need to start it now.
16002                if (mStartedUsers.get(userId) == null) {
16003                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16004                    updateStartedUserArrayLocked();
16005                    needStart = true;
16006                }
16007
16008                mCurrentUserId = userId;
16009                final Integer userIdInt = Integer.valueOf(userId);
16010                mUserLru.remove(userIdInt);
16011                mUserLru.add(userIdInt);
16012
16013                mWindowManager.setCurrentUser(userId);
16014
16015                // Once the internal notion of the active user has switched, we lock the device
16016                // with the option to show the user switcher on the keyguard.
16017                mWindowManager.lockNow(null);
16018
16019                final UserStartedState uss = mStartedUsers.get(userId);
16020
16021                // Make sure user is in the started state.  If it is currently
16022                // stopping, we need to knock that off.
16023                if (uss.mState == UserStartedState.STATE_STOPPING) {
16024                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16025                    // so we can just fairly silently bring the user back from
16026                    // the almost-dead.
16027                    uss.mState = UserStartedState.STATE_RUNNING;
16028                    updateStartedUserArrayLocked();
16029                    needStart = true;
16030                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16031                    // This means ACTION_SHUTDOWN has been sent, so we will
16032                    // need to treat this as a new boot of the user.
16033                    uss.mState = UserStartedState.STATE_BOOTING;
16034                    updateStartedUserArrayLocked();
16035                    needStart = true;
16036                }
16037
16038                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16039                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16040                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16041                        oldUserId, userId, uss));
16042                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16043                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16044                if (needStart) {
16045                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16046                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16047                            | Intent.FLAG_RECEIVER_FOREGROUND);
16048                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16049                    broadcastIntentLocked(null, null, intent,
16050                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16051                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16052                }
16053
16054                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16055                    if (userId != 0) {
16056                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16057                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16058                        broadcastIntentLocked(null, null, intent, null,
16059                                new IIntentReceiver.Stub() {
16060                                    public void performReceive(Intent intent, int resultCode,
16061                                            String data, Bundle extras, boolean ordered,
16062                                            boolean sticky, int sendingUser) {
16063                                        userInitialized(uss, userId);
16064                                    }
16065                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16066                                true, false, MY_PID, Process.SYSTEM_UID,
16067                                userId);
16068                        uss.initializing = true;
16069                    } else {
16070                        getUserManagerLocked().makeInitialized(userInfo.id);
16071                    }
16072                }
16073
16074                boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16075                if (homeInFront) {
16076                    startHomeActivityLocked(userId);
16077                } else {
16078                    mStackSupervisor.resumeTopActivitiesLocked();
16079                }
16080
16081                EventLogTags.writeAmSwitchUser(userId);
16082                getUserManagerLocked().userForeground(userId);
16083                sendUserSwitchBroadcastsLocked(oldUserId, userId);
16084                if (needStart) {
16085                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16086                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16087                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16088                    broadcastIntentLocked(null, null, intent,
16089                            null, new IIntentReceiver.Stub() {
16090                                @Override
16091                                public void performReceive(Intent intent, int resultCode, String data,
16092                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16093                                        throws RemoteException {
16094                                }
16095                            }, 0, null, null,
16096                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16097                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16098                }
16099            }
16100        } finally {
16101            Binder.restoreCallingIdentity(ident);
16102        }
16103
16104        return true;
16105    }
16106
16107    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16108        long ident = Binder.clearCallingIdentity();
16109        try {
16110            Intent intent;
16111            if (oldUserId >= 0) {
16112                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16113                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16114                        | Intent.FLAG_RECEIVER_FOREGROUND);
16115                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16116                broadcastIntentLocked(null, null, intent,
16117                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16118                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16119            }
16120            if (newUserId >= 0) {
16121                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16122                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16123                        | Intent.FLAG_RECEIVER_FOREGROUND);
16124                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16125                broadcastIntentLocked(null, null, intent,
16126                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16127                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16128                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16129                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16130                        | Intent.FLAG_RECEIVER_FOREGROUND);
16131                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16132                broadcastIntentLocked(null, null, intent,
16133                        null, null, 0, null, null,
16134                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16135                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16136            }
16137        } finally {
16138            Binder.restoreCallingIdentity(ident);
16139        }
16140    }
16141
16142    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16143            final int newUserId) {
16144        final int N = mUserSwitchObservers.beginBroadcast();
16145        if (N > 0) {
16146            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16147                int mCount = 0;
16148                @Override
16149                public void sendResult(Bundle data) throws RemoteException {
16150                    synchronized (ActivityManagerService.this) {
16151                        if (mCurUserSwitchCallback == this) {
16152                            mCount++;
16153                            if (mCount == N) {
16154                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16155                            }
16156                        }
16157                    }
16158                }
16159            };
16160            synchronized (this) {
16161                uss.switching = true;
16162                mCurUserSwitchCallback = callback;
16163            }
16164            for (int i=0; i<N; i++) {
16165                try {
16166                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16167                            newUserId, callback);
16168                } catch (RemoteException e) {
16169                }
16170            }
16171        } else {
16172            synchronized (this) {
16173                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16174            }
16175        }
16176        mUserSwitchObservers.finishBroadcast();
16177    }
16178
16179    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16180        synchronized (this) {
16181            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16182            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16183        }
16184    }
16185
16186    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16187        mCurUserSwitchCallback = null;
16188        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16189        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16190                oldUserId, newUserId, uss));
16191    }
16192
16193    void userInitialized(UserStartedState uss, int newUserId) {
16194        completeSwitchAndInitalize(uss, newUserId, true, false);
16195    }
16196
16197    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16198        completeSwitchAndInitalize(uss, newUserId, false, true);
16199    }
16200
16201    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16202            boolean clearInitializing, boolean clearSwitching) {
16203        boolean unfrozen = false;
16204        synchronized (this) {
16205            if (clearInitializing) {
16206                uss.initializing = false;
16207                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16208            }
16209            if (clearSwitching) {
16210                uss.switching = false;
16211            }
16212            if (!uss.switching && !uss.initializing) {
16213                mWindowManager.stopFreezingScreen();
16214                unfrozen = true;
16215            }
16216        }
16217        if (unfrozen) {
16218            final int N = mUserSwitchObservers.beginBroadcast();
16219            for (int i=0; i<N; i++) {
16220                try {
16221                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16222                } catch (RemoteException e) {
16223                }
16224            }
16225            mUserSwitchObservers.finishBroadcast();
16226        }
16227    }
16228
16229    void finishUserSwitch(UserStartedState uss) {
16230        synchronized (this) {
16231            if (uss.mState == UserStartedState.STATE_BOOTING
16232                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16233                uss.mState = UserStartedState.STATE_RUNNING;
16234                final int userId = uss.mHandle.getIdentifier();
16235                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16236                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16237                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16238                broadcastIntentLocked(null, null, intent,
16239                        null, null, 0, null, null,
16240                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16241                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16242            }
16243            int num = mUserLru.size();
16244            int i = 0;
16245            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16246                Integer oldUserId = mUserLru.get(i);
16247                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16248                if (oldUss == null) {
16249                    // Shouldn't happen, but be sane if it does.
16250                    mUserLru.remove(i);
16251                    num--;
16252                    continue;
16253                }
16254                if (oldUss.mState == UserStartedState.STATE_STOPPING
16255                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16256                    // This user is already stopping, doesn't count.
16257                    num--;
16258                    i++;
16259                    continue;
16260                }
16261                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16262                    // Owner and current can't be stopped, but count as running.
16263                    i++;
16264                    continue;
16265                }
16266                // This is a user to be stopped.
16267                stopUserLocked(oldUserId, null);
16268                num--;
16269                i++;
16270            }
16271        }
16272    }
16273
16274    @Override
16275    public int stopUser(final int userId, final IStopUserCallback callback) {
16276        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16277                != PackageManager.PERMISSION_GRANTED) {
16278            String msg = "Permission Denial: switchUser() from pid="
16279                    + Binder.getCallingPid()
16280                    + ", uid=" + Binder.getCallingUid()
16281                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16282            Slog.w(TAG, msg);
16283            throw new SecurityException(msg);
16284        }
16285        if (userId <= 0) {
16286            throw new IllegalArgumentException("Can't stop primary user " + userId);
16287        }
16288        synchronized (this) {
16289            return stopUserLocked(userId, callback);
16290        }
16291    }
16292
16293    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16294        if (mCurrentUserId == userId) {
16295            return ActivityManager.USER_OP_IS_CURRENT;
16296        }
16297
16298        final UserStartedState uss = mStartedUsers.get(userId);
16299        if (uss == null) {
16300            // User is not started, nothing to do...  but we do need to
16301            // callback if requested.
16302            if (callback != null) {
16303                mHandler.post(new Runnable() {
16304                    @Override
16305                    public void run() {
16306                        try {
16307                            callback.userStopped(userId);
16308                        } catch (RemoteException e) {
16309                        }
16310                    }
16311                });
16312            }
16313            return ActivityManager.USER_OP_SUCCESS;
16314        }
16315
16316        if (callback != null) {
16317            uss.mStopCallbacks.add(callback);
16318        }
16319
16320        if (uss.mState != UserStartedState.STATE_STOPPING
16321                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16322            uss.mState = UserStartedState.STATE_STOPPING;
16323            updateStartedUserArrayLocked();
16324
16325            long ident = Binder.clearCallingIdentity();
16326            try {
16327                // We are going to broadcast ACTION_USER_STOPPING and then
16328                // once that is done send a final ACTION_SHUTDOWN and then
16329                // stop the user.
16330                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16331                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16332                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16333                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16334                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16335                // This is the result receiver for the final shutdown broadcast.
16336                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16337                    @Override
16338                    public void performReceive(Intent intent, int resultCode, String data,
16339                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16340                        finishUserStop(uss);
16341                    }
16342                };
16343                // This is the result receiver for the initial stopping broadcast.
16344                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16345                    @Override
16346                    public void performReceive(Intent intent, int resultCode, String data,
16347                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16348                        // On to the next.
16349                        synchronized (ActivityManagerService.this) {
16350                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16351                                // Whoops, we are being started back up.  Abort, abort!
16352                                return;
16353                            }
16354                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16355                        }
16356                        broadcastIntentLocked(null, null, shutdownIntent,
16357                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16358                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16359                    }
16360                };
16361                // Kick things off.
16362                broadcastIntentLocked(null, null, stoppingIntent,
16363                        null, stoppingReceiver, 0, null, null,
16364                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16365                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16366            } finally {
16367                Binder.restoreCallingIdentity(ident);
16368            }
16369        }
16370
16371        return ActivityManager.USER_OP_SUCCESS;
16372    }
16373
16374    void finishUserStop(UserStartedState uss) {
16375        final int userId = uss.mHandle.getIdentifier();
16376        boolean stopped;
16377        ArrayList<IStopUserCallback> callbacks;
16378        synchronized (this) {
16379            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16380            if (mStartedUsers.get(userId) != uss) {
16381                stopped = false;
16382            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16383                stopped = false;
16384            } else {
16385                stopped = true;
16386                // User can no longer run.
16387                mStartedUsers.remove(userId);
16388                mUserLru.remove(Integer.valueOf(userId));
16389                updateStartedUserArrayLocked();
16390
16391                // Clean up all state and processes associated with the user.
16392                // Kill all the processes for the user.
16393                forceStopUserLocked(userId, "finish user");
16394            }
16395        }
16396
16397        for (int i=0; i<callbacks.size(); i++) {
16398            try {
16399                if (stopped) callbacks.get(i).userStopped(userId);
16400                else callbacks.get(i).userStopAborted(userId);
16401            } catch (RemoteException e) {
16402            }
16403        }
16404
16405        mStackSupervisor.removeUserLocked(userId);
16406    }
16407
16408    @Override
16409    public UserInfo getCurrentUser() {
16410        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16411                != PackageManager.PERMISSION_GRANTED) && (
16412                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16413                != PackageManager.PERMISSION_GRANTED)) {
16414            String msg = "Permission Denial: getCurrentUser() from pid="
16415                    + Binder.getCallingPid()
16416                    + ", uid=" + Binder.getCallingUid()
16417                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16418            Slog.w(TAG, msg);
16419            throw new SecurityException(msg);
16420        }
16421        synchronized (this) {
16422            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16423        }
16424    }
16425
16426    int getCurrentUserIdLocked() {
16427        return mCurrentUserId;
16428    }
16429
16430    @Override
16431    public boolean isUserRunning(int userId, boolean orStopped) {
16432        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16433                != PackageManager.PERMISSION_GRANTED) {
16434            String msg = "Permission Denial: isUserRunning() from pid="
16435                    + Binder.getCallingPid()
16436                    + ", uid=" + Binder.getCallingUid()
16437                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16438            Slog.w(TAG, msg);
16439            throw new SecurityException(msg);
16440        }
16441        synchronized (this) {
16442            return isUserRunningLocked(userId, orStopped);
16443        }
16444    }
16445
16446    boolean isUserRunningLocked(int userId, boolean orStopped) {
16447        UserStartedState state = mStartedUsers.get(userId);
16448        if (state == null) {
16449            return false;
16450        }
16451        if (orStopped) {
16452            return true;
16453        }
16454        return state.mState != UserStartedState.STATE_STOPPING
16455                && state.mState != UserStartedState.STATE_SHUTDOWN;
16456    }
16457
16458    @Override
16459    public int[] getRunningUserIds() {
16460        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16461                != PackageManager.PERMISSION_GRANTED) {
16462            String msg = "Permission Denial: isUserRunning() from pid="
16463                    + Binder.getCallingPid()
16464                    + ", uid=" + Binder.getCallingUid()
16465                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16466            Slog.w(TAG, msg);
16467            throw new SecurityException(msg);
16468        }
16469        synchronized (this) {
16470            return mStartedUserArray;
16471        }
16472    }
16473
16474    private void updateStartedUserArrayLocked() {
16475        int num = 0;
16476        for (int i=0; i<mStartedUsers.size();  i++) {
16477            UserStartedState uss = mStartedUsers.valueAt(i);
16478            // This list does not include stopping users.
16479            if (uss.mState != UserStartedState.STATE_STOPPING
16480                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16481                num++;
16482            }
16483        }
16484        mStartedUserArray = new int[num];
16485        num = 0;
16486        for (int i=0; i<mStartedUsers.size();  i++) {
16487            UserStartedState uss = mStartedUsers.valueAt(i);
16488            if (uss.mState != UserStartedState.STATE_STOPPING
16489                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16490                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16491                num++;
16492            }
16493        }
16494    }
16495
16496    @Override
16497    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16498        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16499                != PackageManager.PERMISSION_GRANTED) {
16500            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16501                    + Binder.getCallingPid()
16502                    + ", uid=" + Binder.getCallingUid()
16503                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16504            Slog.w(TAG, msg);
16505            throw new SecurityException(msg);
16506        }
16507
16508        mUserSwitchObservers.register(observer);
16509    }
16510
16511    @Override
16512    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16513        mUserSwitchObservers.unregister(observer);
16514    }
16515
16516    private boolean userExists(int userId) {
16517        if (userId == 0) {
16518            return true;
16519        }
16520        UserManagerService ums = getUserManagerLocked();
16521        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16522    }
16523
16524    int[] getUsersLocked() {
16525        UserManagerService ums = getUserManagerLocked();
16526        return ums != null ? ums.getUserIds() : new int[] { 0 };
16527    }
16528
16529    UserManagerService getUserManagerLocked() {
16530        if (mUserManager == null) {
16531            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16532            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16533        }
16534        return mUserManager;
16535    }
16536
16537    private int applyUserId(int uid, int userId) {
16538        return UserHandle.getUid(userId, uid);
16539    }
16540
16541    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16542        if (info == null) return null;
16543        ApplicationInfo newInfo = new ApplicationInfo(info);
16544        newInfo.uid = applyUserId(info.uid, userId);
16545        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16546                + info.packageName;
16547        return newInfo;
16548    }
16549
16550    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16551        if (aInfo == null
16552                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16553            return aInfo;
16554        }
16555
16556        ActivityInfo info = new ActivityInfo(aInfo);
16557        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16558        return info;
16559    }
16560}
16561