ActivityManagerService.java revision ee36c77acd3b92c64e53e19c570e2482382db870
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readIntAttribute;
21import static com.android.internal.util.XmlUtils.readLongAttribute;
22import static com.android.internal.util.XmlUtils.writeIntAttribute;
23import static com.android.internal.util.XmlUtils.writeLongAttribute;
24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
26import static org.xmlpull.v1.XmlPullParser.START_TAG;
27import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
28
29import android.app.AppOpsManager;
30import android.app.IActivityContainer;
31import android.app.IActivityContainerCallback;
32import android.appwidget.AppWidgetManager;
33import android.graphics.Rect;
34import android.util.ArrayMap;
35
36import com.android.internal.R;
37import com.android.internal.annotations.GuardedBy;
38import com.android.internal.app.IAppOpsService;
39import com.android.internal.app.ProcessMap;
40import com.android.internal.app.ProcessStats;
41import com.android.internal.os.BackgroundThread;
42import com.android.internal.os.BatteryStatsImpl;
43import com.android.internal.os.ProcessCpuTracker;
44import com.android.internal.os.TransferPipe;
45import com.android.internal.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.LocalServices;
53import com.android.server.ServiceThread;
54import com.android.server.SystemService;
55import com.android.server.Watchdog;
56import com.android.server.am.ActivityStack.ActivityState;
57import com.android.server.firewall.IntentFirewall;
58import com.android.server.pm.UserManagerService;
59import com.android.server.wm.AppTransition;
60import com.android.server.wm.WindowManagerService;
61import com.google.android.collect.Lists;
62import com.google.android.collect.Maps;
63
64import dalvik.system.Zygote;
65import libcore.io.IoUtils;
66
67import org.xmlpull.v1.XmlPullParser;
68import org.xmlpull.v1.XmlPullParserException;
69import org.xmlpull.v1.XmlSerializer;
70
71import android.app.Activity;
72import android.app.ActivityManager;
73import android.app.ActivityManager.RunningTaskInfo;
74import android.app.ActivityManager.StackInfo;
75import android.app.ActivityManagerInternal;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.ApplicationErrorReport;
82import android.app.Dialog;
83import android.app.IActivityController;
84import android.app.IApplicationThread;
85import android.app.IInstrumentationWatcher;
86import android.app.INotificationManager;
87import android.app.IProcessObserver;
88import android.app.IServiceConnection;
89import android.app.IStopUserCallback;
90import android.app.IThumbnailReceiver;
91import android.app.IUiAutomationConnection;
92import android.app.IUserSwitchObserver;
93import android.app.Instrumentation;
94import android.app.Notification;
95import android.app.NotificationManager;
96import android.app.PendingIntent;
97import android.app.backup.IBackupManager;
98import android.content.ActivityNotFoundException;
99import android.content.BroadcastReceiver;
100import android.content.ClipData;
101import android.content.ComponentCallbacks2;
102import android.content.ComponentName;
103import android.content.ContentProvider;
104import android.content.ContentResolver;
105import android.content.Context;
106import android.content.DialogInterface;
107import android.content.IContentProvider;
108import android.content.IIntentReceiver;
109import android.content.IIntentSender;
110import android.content.Intent;
111import android.content.IntentFilter;
112import android.content.IntentSender;
113import android.content.pm.ActivityInfo;
114import android.content.pm.ApplicationInfo;
115import android.content.pm.ConfigurationInfo;
116import android.content.pm.IPackageDataObserver;
117import android.content.pm.IPackageManager;
118import android.content.pm.InstrumentationInfo;
119import android.content.pm.PackageInfo;
120import android.content.pm.PackageManager;
121import android.content.pm.ParceledListSlice;
122import android.content.pm.UserInfo;
123import android.content.pm.PackageManager.NameNotFoundException;
124import android.content.pm.PathPermission;
125import android.content.pm.ProviderInfo;
126import android.content.pm.ResolveInfo;
127import android.content.pm.ServiceInfo;
128import android.content.res.CompatibilityInfo;
129import android.content.res.Configuration;
130import android.graphics.Bitmap;
131import android.net.Proxy;
132import android.net.ProxyProperties;
133import android.net.Uri;
134import android.os.Binder;
135import android.os.Build;
136import android.os.Bundle;
137import android.os.Debug;
138import android.os.DropBoxManager;
139import android.os.Environment;
140import android.os.FactoryTest;
141import android.os.FileObserver;
142import android.os.FileUtils;
143import android.os.Handler;
144import android.os.IBinder;
145import android.os.IPermissionController;
146import android.os.IRemoteCallback;
147import android.os.IUserManager;
148import android.os.Looper;
149import android.os.Message;
150import android.os.Parcel;
151import android.os.ParcelFileDescriptor;
152import android.os.Process;
153import android.os.RemoteCallbackList;
154import android.os.RemoteException;
155import android.os.SELinux;
156import android.os.ServiceManager;
157import android.os.StrictMode;
158import android.os.SystemClock;
159import android.os.SystemProperties;
160import android.os.UpdateLock;
161import android.os.UserHandle;
162import android.provider.Settings;
163import android.text.format.DateUtils;
164import android.text.format.Time;
165import android.util.AtomicFile;
166import android.util.EventLog;
167import android.util.Log;
168import android.util.Pair;
169import android.util.PrintWriterPrinter;
170import android.util.Slog;
171import android.util.SparseArray;
172import android.util.TimeUtils;
173import android.util.Xml;
174import android.view.Gravity;
175import android.view.LayoutInflater;
176import android.view.View;
177import android.view.WindowManager;
178
179import java.io.BufferedInputStream;
180import java.io.BufferedOutputStream;
181import java.io.DataInputStream;
182import java.io.DataOutputStream;
183import java.io.File;
184import java.io.FileDescriptor;
185import java.io.FileInputStream;
186import java.io.FileNotFoundException;
187import java.io.FileOutputStream;
188import java.io.IOException;
189import java.io.InputStreamReader;
190import java.io.PrintWriter;
191import java.io.StringWriter;
192import java.lang.ref.WeakReference;
193import java.util.ArrayList;
194import java.util.Arrays;
195import java.util.Collections;
196import java.util.Comparator;
197import java.util.HashMap;
198import java.util.HashSet;
199import java.util.Iterator;
200import java.util.List;
201import java.util.Locale;
202import java.util.Map;
203import java.util.Set;
204import java.util.concurrent.atomic.AtomicBoolean;
205import java.util.concurrent.atomic.AtomicLong;
206
207public final class ActivityManagerService extends ActivityManagerNative
208        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
209    private static final String USER_DATA_DIR = "/data/user/";
210    static final String TAG = "ActivityManager";
211    static final String TAG_MU = "ActivityManagerServiceMU";
212    static final boolean DEBUG = false;
213    static final boolean localLOGV = DEBUG;
214    static final boolean DEBUG_BACKUP = localLOGV || false;
215    static final boolean DEBUG_BROADCAST = localLOGV || false;
216    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
217    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
218    static final boolean DEBUG_CLEANUP = localLOGV || false;
219    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
220    static final boolean DEBUG_FOCUS = false;
221    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
222    static final boolean DEBUG_MU = localLOGV || false;
223    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
224    static final boolean DEBUG_LRU = localLOGV || false;
225    static final boolean DEBUG_PAUSE = localLOGV || false;
226    static final boolean DEBUG_POWER = localLOGV || false;
227    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
228    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
229    static final boolean DEBUG_PROCESSES = localLOGV || false;
230    static final boolean DEBUG_PROVIDER = localLOGV || false;
231    static final boolean DEBUG_RESULTS = localLOGV || false;
232    static final boolean DEBUG_SERVICE = localLOGV || false;
233    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
234    static final boolean DEBUG_STACK = localLOGV || false;
235    static final boolean DEBUG_SWITCH = localLOGV || false;
236    static final boolean DEBUG_TASKS = localLOGV || false;
237    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
238    static final boolean DEBUG_TRANSITION = localLOGV || false;
239    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
240    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
241    static final boolean DEBUG_VISBILITY = localLOGV || false;
242    static final boolean DEBUG_PSS = localLOGV || false;
243    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
244    static final boolean VALIDATE_TOKENS = false;
245    static final boolean SHOW_ACTIVITY_START_TIME = true;
246
247    // Control over CPU and battery monitoring.
248    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
249    static final boolean MONITOR_CPU_USAGE = true;
250    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
251    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
252    static final boolean MONITOR_THREAD_CPU_USAGE = false;
253
254    // The flags that are set for all calls we make to the package manager.
255    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
256
257    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
258
259    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
260
261    // Maximum number of recent tasks that we can remember.
262    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
263
264    // Amount of time after a call to stopAppSwitches() during which we will
265    // prevent further untrusted switches from happening.
266    static final long APP_SWITCH_DELAY_TIME = 5*1000;
267
268    // How long we wait for a launched process to attach to the activity manager
269    // before we decide it's never going to come up for real.
270    static final int PROC_START_TIMEOUT = 10*1000;
271
272    // How long we wait for a launched process to attach to the activity manager
273    // before we decide it's never going to come up for real, when the process was
274    // started with a wrapper for instrumentation (such as Valgrind) because it
275    // could take much longer than usual.
276    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
277
278    // How long to wait after going idle before forcing apps to GC.
279    static final int GC_TIMEOUT = 5*1000;
280
281    // The minimum amount of time between successive GC requests for a process.
282    static final int GC_MIN_INTERVAL = 60*1000;
283
284    // The minimum amount of time between successive PSS requests for a process.
285    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
286
287    // The minimum amount of time between successive PSS requests for a process
288    // when the request is due to the memory state being lowered.
289    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
290
291    // The rate at which we check for apps using excessive power -- 15 mins.
292    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
293
294    // The minimum sample duration we will allow before deciding we have
295    // enough data on wake locks to start killing things.
296    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
297
298    // The minimum sample duration we will allow before deciding we have
299    // enough data on CPU usage to start killing things.
300    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
301
302    // How long we allow a receiver to run before giving up on it.
303    static final int BROADCAST_FG_TIMEOUT = 10*1000;
304    static final int BROADCAST_BG_TIMEOUT = 60*1000;
305
306    // How long we wait until we timeout on key dispatching.
307    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
308
309    // How long we wait until we timeout on key dispatching during instrumentation.
310    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
311
312    // Amount of time we wait for observers to handle a user switch before
313    // giving up on them and unfreezing the screen.
314    static final int USER_SWITCH_TIMEOUT = 2*1000;
315
316    // Maximum number of users we allow to be running at a time.
317    static final int MAX_RUNNING_USERS = 3;
318
319    // How long to wait in getAssistContextExtras for the activity and foreground services
320    // to respond with the result.
321    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
322
323    // Maximum number of persisted Uri grants a package is allowed
324    static final int MAX_PERSISTED_URI_GRANTS = 128;
325
326    static final int MY_PID = Process.myPid();
327
328    static final String[] EMPTY_STRING_ARRAY = new String[0];
329
330    // How many bytes to write into the dropbox log before truncating
331    static final int DROPBOX_MAX_SIZE = 256 * 1024;
332
333    /** Run all ActivityStacks through this */
334    ActivityStackSupervisor mStackSupervisor;
335
336    public IntentFirewall mIntentFirewall;
337
338    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
339    // default actuion automatically.  Important for devices without direct input
340    // devices.
341    private boolean mShowDialogs = true;
342
343    BroadcastQueue mFgBroadcastQueue;
344    BroadcastQueue mBgBroadcastQueue;
345    // Convenient for easy iteration over the queues. Foreground is first
346    // so that dispatch of foreground broadcasts gets precedence.
347    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
348
349    BroadcastQueue broadcastQueueForIntent(Intent intent) {
350        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
351        if (DEBUG_BACKGROUND_BROADCAST) {
352            Slog.i(TAG, "Broadcast intent " + intent + " on "
353                    + (isFg ? "foreground" : "background")
354                    + " queue");
355        }
356        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
357    }
358
359    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
360        for (BroadcastQueue queue : mBroadcastQueues) {
361            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
362            if (r != null) {
363                return r;
364            }
365        }
366        return null;
367    }
368
369    /**
370     * Activity we have told the window manager to have key focus.
371     */
372    ActivityRecord mFocusedActivity = null;
373
374    /**
375     * List of intents that were used to start the most recent tasks.
376     */
377    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
378
379    public class PendingAssistExtras extends Binder implements Runnable {
380        public final ActivityRecord activity;
381        public boolean haveResult = false;
382        public Bundle result = null;
383        public PendingAssistExtras(ActivityRecord _activity) {
384            activity = _activity;
385        }
386        @Override
387        public void run() {
388            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
389            synchronized (this) {
390                haveResult = true;
391                notifyAll();
392            }
393        }
394    }
395
396    final ArrayList<PendingAssistExtras> mPendingAssistExtras
397            = new ArrayList<PendingAssistExtras>();
398
399    /**
400     * Process management.
401     */
402    final ProcessList mProcessList = new ProcessList();
403
404    /**
405     * All of the applications we currently have running organized by name.
406     * The keys are strings of the application package name (as
407     * returned by the package manager), and the keys are ApplicationRecord
408     * objects.
409     */
410    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
411
412    /**
413     * Tracking long-term execution of processes to look for abuse and other
414     * bad app behavior.
415     */
416    final ProcessStatsService mProcessStats;
417
418    /**
419     * The currently running isolated processes.
420     */
421    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
422
423    /**
424     * Counter for assigning isolated process uids, to avoid frequently reusing the
425     * same ones.
426     */
427    int mNextIsolatedProcessUid = 0;
428
429    /**
430     * The currently running heavy-weight process, if any.
431     */
432    ProcessRecord mHeavyWeightProcess = null;
433
434    /**
435     * The last time that various processes have crashed.
436     */
437    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
438
439    /**
440     * Information about a process that is currently marked as bad.
441     */
442    static final class BadProcessInfo {
443        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
444            this.time = time;
445            this.shortMsg = shortMsg;
446            this.longMsg = longMsg;
447            this.stack = stack;
448        }
449
450        final long time;
451        final String shortMsg;
452        final String longMsg;
453        final String stack;
454    }
455
456    /**
457     * Set of applications that we consider to be bad, and will reject
458     * incoming broadcasts from (which the user has no control over).
459     * Processes are added to this set when they have crashed twice within
460     * a minimum amount of time; they are removed from it when they are
461     * later restarted (hopefully due to some user action).  The value is the
462     * time it was added to the list.
463     */
464    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
465
466    /**
467     * All of the processes we currently have running organized by pid.
468     * The keys are the pid running the application.
469     *
470     * <p>NOTE: This object is protected by its own lock, NOT the global
471     * activity manager lock!
472     */
473    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
474
475    /**
476     * All of the processes that have been forced to be foreground.  The key
477     * is the pid of the caller who requested it (we hold a death
478     * link on it).
479     */
480    abstract class ForegroundToken implements IBinder.DeathRecipient {
481        int pid;
482        IBinder token;
483    }
484    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
485
486    /**
487     * List of records for processes that someone had tried to start before the
488     * system was ready.  We don't start them at that point, but ensure they
489     * are started by the time booting is complete.
490     */
491    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
492
493    /**
494     * List of persistent applications that are in the process
495     * of being started.
496     */
497    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
498
499    /**
500     * Processes that are being forcibly torn down.
501     */
502    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
503
504    /**
505     * List of running applications, sorted by recent usage.
506     * The first entry in the list is the least recently used.
507     */
508    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
509
510    /**
511     * Where in mLruProcesses that the processes hosting activities start.
512     */
513    int mLruProcessActivityStart = 0;
514
515    /**
516     * Where in mLruProcesses that the processes hosting services start.
517     * This is after (lower index) than mLruProcessesActivityStart.
518     */
519    int mLruProcessServiceStart = 0;
520
521    /**
522     * List of processes that should gc as soon as things are idle.
523     */
524    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
525
526    /**
527     * Processes we want to collect PSS data from.
528     */
529    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
530
531    /**
532     * Last time we requested PSS data of all processes.
533     */
534    long mLastFullPssTime = SystemClock.uptimeMillis();
535
536    /**
537     * This is the process holding what we currently consider to be
538     * the "home" activity.
539     */
540    ProcessRecord mHomeProcess;
541
542    /**
543     * This is the process holding the activity the user last visited that
544     * is in a different process from the one they are currently in.
545     */
546    ProcessRecord mPreviousProcess;
547
548    /**
549     * The time at which the previous process was last visible.
550     */
551    long mPreviousProcessVisibleTime;
552
553    /**
554     * Which uses have been started, so are allowed to run code.
555     */
556    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
557
558    /**
559     * LRU list of history of current users.  Most recently current is at the end.
560     */
561    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
562
563    /**
564     * Constant array of the users that are currently started.
565     */
566    int[] mStartedUserArray = new int[] { 0 };
567
568    /**
569     * Registered observers of the user switching mechanics.
570     */
571    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
572            = new RemoteCallbackList<IUserSwitchObserver>();
573
574    /**
575     * Currently active user switch.
576     */
577    Object mCurUserSwitchCallback;
578
579    /**
580     * Packages that the user has asked to have run in screen size
581     * compatibility mode instead of filling the screen.
582     */
583    final CompatModePackages mCompatModePackages;
584
585    /**
586     * Set of IntentSenderRecord objects that are currently active.
587     */
588    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
589            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
590
591    /**
592     * Fingerprints (hashCode()) of stack traces that we've
593     * already logged DropBox entries for.  Guarded by itself.  If
594     * something (rogue user app) forces this over
595     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
596     */
597    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
598    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
599
600    /**
601     * Strict Mode background batched logging state.
602     *
603     * The string buffer is guarded by itself, and its lock is also
604     * used to determine if another batched write is already
605     * in-flight.
606     */
607    private final StringBuilder mStrictModeBuffer = new StringBuilder();
608
609    /**
610     * Keeps track of all IIntentReceivers that have been registered for
611     * broadcasts.  Hash keys are the receiver IBinder, hash value is
612     * a ReceiverList.
613     */
614    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
615            new HashMap<IBinder, ReceiverList>();
616
617    /**
618     * Resolver for broadcast intents to registered receivers.
619     * Holds BroadcastFilter (subclass of IntentFilter).
620     */
621    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
622            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
623        @Override
624        protected boolean allowFilterResult(
625                BroadcastFilter filter, List<BroadcastFilter> dest) {
626            IBinder target = filter.receiverList.receiver.asBinder();
627            for (int i=dest.size()-1; i>=0; i--) {
628                if (dest.get(i).receiverList.receiver.asBinder() == target) {
629                    return false;
630                }
631            }
632            return true;
633        }
634
635        @Override
636        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
637            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
638                    || userId == filter.owningUserId) {
639                return super.newResult(filter, match, userId);
640            }
641            return null;
642        }
643
644        @Override
645        protected BroadcastFilter[] newArray(int size) {
646            return new BroadcastFilter[size];
647        }
648
649        @Override
650        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
651            return packageName.equals(filter.packageName);
652        }
653    };
654
655    /**
656     * State of all active sticky broadcasts per user.  Keys are the action of the
657     * sticky Intent, values are an ArrayList of all broadcasted intents with
658     * that action (which should usually be one).  The SparseArray is keyed
659     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
660     * for stickies that are sent to all users.
661     */
662    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
663            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
664
665    final ActiveServices mServices;
666
667    /**
668     * Backup/restore process management
669     */
670    String mBackupAppName = null;
671    BackupRecord mBackupTarget = null;
672
673    /**
674     * List of PendingThumbnailsRecord objects of clients who are still
675     * waiting to receive all of the thumbnails for a task.
676     */
677    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
678            new ArrayList<PendingThumbnailsRecord>();
679
680    final ProviderMap mProviderMap;
681
682    /**
683     * List of content providers who have clients waiting for them.  The
684     * application is currently being launched and the provider will be
685     * removed from this list once it is published.
686     */
687    final ArrayList<ContentProviderRecord> mLaunchingProviders
688            = new ArrayList<ContentProviderRecord>();
689
690    /**
691     * File storing persisted {@link #mGrantedUriPermissions}.
692     */
693    private final AtomicFile mGrantFile;
694
695    /** XML constants used in {@link #mGrantFile} */
696    private static final String TAG_URI_GRANTS = "uri-grants";
697    private static final String TAG_URI_GRANT = "uri-grant";
698    private static final String ATTR_USER_HANDLE = "userHandle";
699    private static final String ATTR_SOURCE_PKG = "sourcePkg";
700    private static final String ATTR_TARGET_PKG = "targetPkg";
701    private static final String ATTR_URI = "uri";
702    private static final String ATTR_MODE_FLAGS = "modeFlags";
703    private static final String ATTR_CREATED_TIME = "createdTime";
704
705    /**
706     * Global set of specific {@link Uri} permissions that have been granted.
707     * This optimized lookup structure maps from {@link UriPermission#targetUid}
708     * to {@link UriPermission#uri} to {@link UriPermission}.
709     */
710    @GuardedBy("this")
711    private final SparseArray<ArrayMap<Uri, UriPermission>>
712            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
713
714    CoreSettingsObserver mCoreSettingsObserver;
715
716    /**
717     * Thread-local storage used to carry caller permissions over through
718     * indirect content-provider access.
719     */
720    private class Identity {
721        public int pid;
722        public int uid;
723
724        Identity(int _pid, int _uid) {
725            pid = _pid;
726            uid = _uid;
727        }
728    }
729
730    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
731
732    /**
733     * All information we have collected about the runtime performance of
734     * any user id that can impact battery performance.
735     */
736    final BatteryStatsService mBatteryStatsService;
737
738    /**
739     * Information about component usage
740     */
741    final UsageStatsService mUsageStatsService;
742
743    /**
744     * Information about and control over application operations
745     */
746    final AppOpsService mAppOpsService;
747
748    /**
749     * Current configuration information.  HistoryRecord objects are given
750     * a reference to this object to indicate which configuration they are
751     * currently running in, so this object must be kept immutable.
752     */
753    Configuration mConfiguration = new Configuration();
754
755    /**
756     * Current sequencing integer of the configuration, for skipping old
757     * configurations.
758     */
759    int mConfigurationSeq = 0;
760
761    /**
762     * Hardware-reported OpenGLES version.
763     */
764    final int GL_ES_VERSION;
765
766    /**
767     * List of initialization arguments to pass to all processes when binding applications to them.
768     * For example, references to the commonly used services.
769     */
770    HashMap<String, IBinder> mAppBindArgs;
771
772    /**
773     * Temporary to avoid allocations.  Protected by main lock.
774     */
775    final StringBuilder mStringBuilder = new StringBuilder(256);
776
777    /**
778     * Used to control how we initialize the service.
779     */
780    ComponentName mTopComponent;
781    String mTopAction = Intent.ACTION_MAIN;
782    String mTopData;
783    boolean mProcessesReady = false;
784    boolean mSystemReady = false;
785    boolean mBooting = false;
786    boolean mWaitingUpdate = false;
787    boolean mDidUpdate = false;
788    boolean mOnBattery = false;
789    boolean mLaunchWarningShown = false;
790
791    Context mContext;
792
793    int mFactoryTest;
794
795    boolean mCheckedForSetup;
796
797    /**
798     * The time at which we will allow normal application switches again,
799     * after a call to {@link #stopAppSwitches()}.
800     */
801    long mAppSwitchesAllowedTime;
802
803    /**
804     * This is set to true after the first switch after mAppSwitchesAllowedTime
805     * is set; any switches after that will clear the time.
806     */
807    boolean mDidAppSwitch;
808
809    /**
810     * Last time (in realtime) at which we checked for power usage.
811     */
812    long mLastPowerCheckRealtime;
813
814    /**
815     * Last time (in uptime) at which we checked for power usage.
816     */
817    long mLastPowerCheckUptime;
818
819    /**
820     * Set while we are wanting to sleep, to prevent any
821     * activities from being started/resumed.
822     */
823    boolean mSleeping = false;
824
825    /**
826     * State of external calls telling us if the device is asleep.
827     */
828    boolean mWentToSleep = false;
829
830    /**
831     * State of external call telling us if the lock screen is shown.
832     */
833    boolean mLockScreenShown = false;
834
835    /**
836     * Set if we are shutting down the system, similar to sleeping.
837     */
838    boolean mShuttingDown = false;
839
840    /**
841     * Current sequence id for oom_adj computation traversal.
842     */
843    int mAdjSeq = 0;
844
845    /**
846     * Current sequence id for process LRU updating.
847     */
848    int mLruSeq = 0;
849
850    /**
851     * Keep track of the non-cached/empty process we last found, to help
852     * determine how to distribute cached/empty processes next time.
853     */
854    int mNumNonCachedProcs = 0;
855
856    /**
857     * Keep track of the number of cached hidden procs, to balance oom adj
858     * distribution between those and empty procs.
859     */
860    int mNumCachedHiddenProcs = 0;
861
862    /**
863     * Keep track of the number of service processes we last found, to
864     * determine on the next iteration which should be B services.
865     */
866    int mNumServiceProcs = 0;
867    int mNewNumAServiceProcs = 0;
868    int mNewNumServiceProcs = 0;
869
870    /**
871     * Allow the current computed overall memory level of the system to go down?
872     * This is set to false when we are killing processes for reasons other than
873     * memory management, so that the now smaller process list will not be taken as
874     * an indication that memory is tighter.
875     */
876    boolean mAllowLowerMemLevel = false;
877
878    /**
879     * The last computed memory level, for holding when we are in a state that
880     * processes are going away for other reasons.
881     */
882    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
883
884    /**
885     * The last total number of process we have, to determine if changes actually look
886     * like a shrinking number of process due to lower RAM.
887     */
888    int mLastNumProcesses;
889
890    /**
891     * The uptime of the last time we performed idle maintenance.
892     */
893    long mLastIdleTime = SystemClock.uptimeMillis();
894
895    /**
896     * Total time spent with RAM that has been added in the past since the last idle time.
897     */
898    long mLowRamTimeSinceLastIdle = 0;
899
900    /**
901     * If RAM is currently low, when that horrible situatin started.
902     */
903    long mLowRamStartTime = 0;
904
905    /**
906     * This is set if we had to do a delayed dexopt of an app before launching
907     * it, to increasing the ANR timeouts in that case.
908     */
909    boolean mDidDexOpt;
910
911    String mDebugApp = null;
912    boolean mWaitForDebugger = false;
913    boolean mDebugTransient = false;
914    String mOrigDebugApp = null;
915    boolean mOrigWaitForDebugger = false;
916    boolean mAlwaysFinishActivities = false;
917    IActivityController mController = null;
918    String mProfileApp = null;
919    ProcessRecord mProfileProc = null;
920    String mProfileFile;
921    ParcelFileDescriptor mProfileFd;
922    int mProfileType = 0;
923    boolean mAutoStopProfiler = false;
924    String mOpenGlTraceApp = null;
925
926    static class ProcessChangeItem {
927        static final int CHANGE_ACTIVITIES = 1<<0;
928        static final int CHANGE_IMPORTANCE= 1<<1;
929        int changes;
930        int uid;
931        int pid;
932        int importance;
933        boolean foregroundActivities;
934    }
935
936    final RemoteCallbackList<IProcessObserver> mProcessObservers
937            = new RemoteCallbackList<IProcessObserver>();
938    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
939
940    final ArrayList<ProcessChangeItem> mPendingProcessChanges
941            = new ArrayList<ProcessChangeItem>();
942    final ArrayList<ProcessChangeItem> mAvailProcessChanges
943            = new ArrayList<ProcessChangeItem>();
944
945    /**
946     * Runtime CPU use collection thread.  This object's lock is used to
947     * protect all related state.
948     */
949    final Thread mProcessCpuThread;
950
951    /**
952     * Used to collect process stats when showing not responding dialog.
953     * Protected by mProcessCpuThread.
954     */
955    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
956            MONITOR_THREAD_CPU_USAGE);
957    final AtomicLong mLastCpuTime = new AtomicLong(0);
958    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
959
960    long mLastWriteTime = 0;
961
962    /**
963     * Used to retain an update lock when the foreground activity is in
964     * immersive mode.
965     */
966    final UpdateLock mUpdateLock = new UpdateLock("immersive");
967
968    /**
969     * Set to true after the system has finished booting.
970     */
971    boolean mBooted = false;
972
973    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
974    int mProcessLimitOverride = -1;
975
976    WindowManagerService mWindowManager;
977
978    final ActivityThread mSystemThread;
979
980    int mCurrentUserId = 0;
981    private UserManagerService mUserManager;
982
983    private final class AppDeathRecipient implements IBinder.DeathRecipient {
984        final ProcessRecord mApp;
985        final int mPid;
986        final IApplicationThread mAppThread;
987
988        AppDeathRecipient(ProcessRecord app, int pid,
989                IApplicationThread thread) {
990            if (localLOGV) Slog.v(
991                TAG, "New death recipient " + this
992                + " for thread " + thread.asBinder());
993            mApp = app;
994            mPid = pid;
995            mAppThread = thread;
996        }
997
998        @Override
999        public void binderDied() {
1000            if (localLOGV) Slog.v(
1001                TAG, "Death received in " + this
1002                + " for thread " + mAppThread.asBinder());
1003            synchronized(ActivityManagerService.this) {
1004                appDiedLocked(mApp, mPid, mAppThread);
1005            }
1006        }
1007    }
1008
1009    static final int SHOW_ERROR_MSG = 1;
1010    static final int SHOW_NOT_RESPONDING_MSG = 2;
1011    static final int SHOW_FACTORY_ERROR_MSG = 3;
1012    static final int UPDATE_CONFIGURATION_MSG = 4;
1013    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1014    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1015    static final int SERVICE_TIMEOUT_MSG = 12;
1016    static final int UPDATE_TIME_ZONE = 13;
1017    static final int SHOW_UID_ERROR_MSG = 14;
1018    static final int IM_FEELING_LUCKY_MSG = 15;
1019    static final int PROC_START_TIMEOUT_MSG = 20;
1020    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1021    static final int KILL_APPLICATION_MSG = 22;
1022    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1023    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1024    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1025    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1026    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1027    static final int CLEAR_DNS_CACHE_MSG = 28;
1028    static final int UPDATE_HTTP_PROXY_MSG = 29;
1029    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1030    static final int DISPATCH_PROCESSES_CHANGED = 31;
1031    static final int DISPATCH_PROCESS_DIED = 32;
1032    static final int REPORT_MEM_USAGE_MSG = 33;
1033    static final int REPORT_USER_SWITCH_MSG = 34;
1034    static final int CONTINUE_USER_SWITCH_MSG = 35;
1035    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1036    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1037    static final int PERSIST_URI_GRANTS_MSG = 38;
1038    static final int REQUEST_ALL_PSS_MSG = 39;
1039
1040    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1041    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1042    static final int FIRST_COMPAT_MODE_MSG = 300;
1043    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1044
1045    AlertDialog mUidAlert;
1046    CompatModeDialog mCompatModeDialog;
1047    long mLastMemUsageReportTime = 0;
1048
1049    /**
1050     * Flag whether the current user is a "monkey", i.e. whether
1051     * the UI is driven by a UI automation tool.
1052     */
1053    private boolean mUserIsMonkey;
1054
1055    /** Flag whether the device has a recents UI */
1056    final boolean mHasRecents;
1057
1058    final ServiceThread mHandlerThread;
1059    final MainHandler mHandler;
1060
1061    final class MainHandler extends Handler {
1062        public MainHandler(Looper looper) {
1063            super(looper, null, true);
1064        }
1065
1066        @Override
1067        public void handleMessage(Message msg) {
1068            switch (msg.what) {
1069            case SHOW_ERROR_MSG: {
1070                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1071                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1072                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1073                synchronized (ActivityManagerService.this) {
1074                    ProcessRecord proc = (ProcessRecord)data.get("app");
1075                    AppErrorResult res = (AppErrorResult) data.get("result");
1076                    if (proc != null && proc.crashDialog != null) {
1077                        Slog.e(TAG, "App already has crash dialog: " + proc);
1078                        if (res != null) {
1079                            res.set(0);
1080                        }
1081                        return;
1082                    }
1083                    if (!showBackground && UserHandle.getAppId(proc.uid)
1084                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1085                            && proc.pid != MY_PID) {
1086                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1087                        if (res != null) {
1088                            res.set(0);
1089                        }
1090                        return;
1091                    }
1092                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1093                        Dialog d = new AppErrorDialog(mContext,
1094                                ActivityManagerService.this, res, proc);
1095                        d.show();
1096                        proc.crashDialog = d;
1097                    } else {
1098                        // The device is asleep, so just pretend that the user
1099                        // saw a crash dialog and hit "force quit".
1100                        if (res != null) {
1101                            res.set(0);
1102                        }
1103                    }
1104                }
1105
1106                ensureBootCompleted();
1107            } break;
1108            case SHOW_NOT_RESPONDING_MSG: {
1109                synchronized (ActivityManagerService.this) {
1110                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1111                    ProcessRecord proc = (ProcessRecord)data.get("app");
1112                    if (proc != null && proc.anrDialog != null) {
1113                        Slog.e(TAG, "App already has anr dialog: " + proc);
1114                        return;
1115                    }
1116
1117                    Intent intent = new Intent("android.intent.action.ANR");
1118                    if (!mProcessesReady) {
1119                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1120                                | Intent.FLAG_RECEIVER_FOREGROUND);
1121                    }
1122                    broadcastIntentLocked(null, null, intent,
1123                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1124                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1125
1126                    if (mShowDialogs) {
1127                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1128                                mContext, proc, (ActivityRecord)data.get("activity"),
1129                                msg.arg1 != 0);
1130                        d.show();
1131                        proc.anrDialog = d;
1132                    } else {
1133                        // Just kill the app if there is no dialog to be shown.
1134                        killAppAtUsersRequest(proc, null);
1135                    }
1136                }
1137
1138                ensureBootCompleted();
1139            } break;
1140            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1141                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1142                synchronized (ActivityManagerService.this) {
1143                    ProcessRecord proc = (ProcessRecord) data.get("app");
1144                    if (proc == null) {
1145                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1146                        break;
1147                    }
1148                    if (proc.crashDialog != null) {
1149                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1150                        return;
1151                    }
1152                    AppErrorResult res = (AppErrorResult) data.get("result");
1153                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1154                        Dialog d = new StrictModeViolationDialog(mContext,
1155                                ActivityManagerService.this, res, proc);
1156                        d.show();
1157                        proc.crashDialog = d;
1158                    } else {
1159                        // The device is asleep, so just pretend that the user
1160                        // saw a crash dialog and hit "force quit".
1161                        res.set(0);
1162                    }
1163                }
1164                ensureBootCompleted();
1165            } break;
1166            case SHOW_FACTORY_ERROR_MSG: {
1167                Dialog d = new FactoryErrorDialog(
1168                    mContext, msg.getData().getCharSequence("msg"));
1169                d.show();
1170                ensureBootCompleted();
1171            } break;
1172            case UPDATE_CONFIGURATION_MSG: {
1173                final ContentResolver resolver = mContext.getContentResolver();
1174                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1175            } break;
1176            case GC_BACKGROUND_PROCESSES_MSG: {
1177                synchronized (ActivityManagerService.this) {
1178                    performAppGcsIfAppropriateLocked();
1179                }
1180            } break;
1181            case WAIT_FOR_DEBUGGER_MSG: {
1182                synchronized (ActivityManagerService.this) {
1183                    ProcessRecord app = (ProcessRecord)msg.obj;
1184                    if (msg.arg1 != 0) {
1185                        if (!app.waitedForDebugger) {
1186                            Dialog d = new AppWaitingForDebuggerDialog(
1187                                    ActivityManagerService.this,
1188                                    mContext, app);
1189                            app.waitDialog = d;
1190                            app.waitedForDebugger = true;
1191                            d.show();
1192                        }
1193                    } else {
1194                        if (app.waitDialog != null) {
1195                            app.waitDialog.dismiss();
1196                            app.waitDialog = null;
1197                        }
1198                    }
1199                }
1200            } break;
1201            case SERVICE_TIMEOUT_MSG: {
1202                if (mDidDexOpt) {
1203                    mDidDexOpt = false;
1204                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1205                    nmsg.obj = msg.obj;
1206                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1207                    return;
1208                }
1209                mServices.serviceTimeout((ProcessRecord)msg.obj);
1210            } break;
1211            case UPDATE_TIME_ZONE: {
1212                synchronized (ActivityManagerService.this) {
1213                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1214                        ProcessRecord r = mLruProcesses.get(i);
1215                        if (r.thread != null) {
1216                            try {
1217                                r.thread.updateTimeZone();
1218                            } catch (RemoteException ex) {
1219                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1220                            }
1221                        }
1222                    }
1223                }
1224            } break;
1225            case CLEAR_DNS_CACHE_MSG: {
1226                synchronized (ActivityManagerService.this) {
1227                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1228                        ProcessRecord r = mLruProcesses.get(i);
1229                        if (r.thread != null) {
1230                            try {
1231                                r.thread.clearDnsCache();
1232                            } catch (RemoteException ex) {
1233                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1234                            }
1235                        }
1236                    }
1237                }
1238            } break;
1239            case UPDATE_HTTP_PROXY_MSG: {
1240                ProxyProperties proxy = (ProxyProperties)msg.obj;
1241                String host = "";
1242                String port = "";
1243                String exclList = "";
1244                String pacFileUrl = null;
1245                if (proxy != null) {
1246                    host = proxy.getHost();
1247                    port = Integer.toString(proxy.getPort());
1248                    exclList = proxy.getExclusionList();
1249                    pacFileUrl = proxy.getPacFileUrl();
1250                }
1251                synchronized (ActivityManagerService.this) {
1252                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1253                        ProcessRecord r = mLruProcesses.get(i);
1254                        if (r.thread != null) {
1255                            try {
1256                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1257                            } catch (RemoteException ex) {
1258                                Slog.w(TAG, "Failed to update http proxy for: " +
1259                                        r.info.processName);
1260                            }
1261                        }
1262                    }
1263                }
1264            } break;
1265            case SHOW_UID_ERROR_MSG: {
1266                String title = "System UIDs Inconsistent";
1267                String text = "UIDs on the system are inconsistent, you need to wipe your"
1268                        + " data partition or your device will be unstable.";
1269                Log.e(TAG, title + ": " + text);
1270                if (mShowDialogs) {
1271                    // XXX This is a temporary dialog, no need to localize.
1272                    AlertDialog d = new BaseErrorDialog(mContext);
1273                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1274                    d.setCancelable(false);
1275                    d.setTitle(title);
1276                    d.setMessage(text);
1277                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1278                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1279                    mUidAlert = d;
1280                    d.show();
1281                }
1282            } break;
1283            case IM_FEELING_LUCKY_MSG: {
1284                if (mUidAlert != null) {
1285                    mUidAlert.dismiss();
1286                    mUidAlert = null;
1287                }
1288            } break;
1289            case PROC_START_TIMEOUT_MSG: {
1290                if (mDidDexOpt) {
1291                    mDidDexOpt = false;
1292                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1293                    nmsg.obj = msg.obj;
1294                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1295                    return;
1296                }
1297                ProcessRecord app = (ProcessRecord)msg.obj;
1298                synchronized (ActivityManagerService.this) {
1299                    processStartTimedOutLocked(app);
1300                }
1301            } break;
1302            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1303                synchronized (ActivityManagerService.this) {
1304                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1305                }
1306            } break;
1307            case KILL_APPLICATION_MSG: {
1308                synchronized (ActivityManagerService.this) {
1309                    int appid = msg.arg1;
1310                    boolean restart = (msg.arg2 == 1);
1311                    Bundle bundle = (Bundle)msg.obj;
1312                    String pkg = bundle.getString("pkg");
1313                    String reason = bundle.getString("reason");
1314                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1315                            UserHandle.USER_ALL, reason);
1316                }
1317            } break;
1318            case FINALIZE_PENDING_INTENT_MSG: {
1319                ((PendingIntentRecord)msg.obj).completeFinalize();
1320            } break;
1321            case POST_HEAVY_NOTIFICATION_MSG: {
1322                INotificationManager inm = NotificationManager.getService();
1323                if (inm == null) {
1324                    return;
1325                }
1326
1327                ActivityRecord root = (ActivityRecord)msg.obj;
1328                ProcessRecord process = root.app;
1329                if (process == null) {
1330                    return;
1331                }
1332
1333                try {
1334                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1335                    String text = mContext.getString(R.string.heavy_weight_notification,
1336                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1337                    Notification notification = new Notification();
1338                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1339                    notification.when = 0;
1340                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1341                    notification.tickerText = text;
1342                    notification.defaults = 0; // please be quiet
1343                    notification.sound = null;
1344                    notification.vibrate = null;
1345                    notification.setLatestEventInfo(context, text,
1346                            mContext.getText(R.string.heavy_weight_notification_detail),
1347                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1348                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1349                                    new UserHandle(root.userId)));
1350
1351                    try {
1352                        int[] outId = new int[1];
1353                        inm.enqueueNotificationWithTag("android", "android", null,
1354                                R.string.heavy_weight_notification,
1355                                notification, outId, root.userId);
1356                    } catch (RuntimeException e) {
1357                        Slog.w(ActivityManagerService.TAG,
1358                                "Error showing notification for heavy-weight app", e);
1359                    } catch (RemoteException e) {
1360                    }
1361                } catch (NameNotFoundException e) {
1362                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1363                }
1364            } break;
1365            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1366                INotificationManager inm = NotificationManager.getService();
1367                if (inm == null) {
1368                    return;
1369                }
1370                try {
1371                    inm.cancelNotificationWithTag("android", null,
1372                            R.string.heavy_weight_notification,  msg.arg1);
1373                } catch (RuntimeException e) {
1374                    Slog.w(ActivityManagerService.TAG,
1375                            "Error canceling notification for service", e);
1376                } catch (RemoteException e) {
1377                }
1378            } break;
1379            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1380                synchronized (ActivityManagerService.this) {
1381                    checkExcessivePowerUsageLocked(true);
1382                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1383                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1384                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1385                }
1386            } break;
1387            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1388                synchronized (ActivityManagerService.this) {
1389                    ActivityRecord ar = (ActivityRecord)msg.obj;
1390                    if (mCompatModeDialog != null) {
1391                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1392                                ar.info.applicationInfo.packageName)) {
1393                            return;
1394                        }
1395                        mCompatModeDialog.dismiss();
1396                        mCompatModeDialog = null;
1397                    }
1398                    if (ar != null && false) {
1399                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1400                                ar.packageName)) {
1401                            int mode = mCompatModePackages.computeCompatModeLocked(
1402                                    ar.info.applicationInfo);
1403                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1404                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1405                                mCompatModeDialog = new CompatModeDialog(
1406                                        ActivityManagerService.this, mContext,
1407                                        ar.info.applicationInfo);
1408                                mCompatModeDialog.show();
1409                            }
1410                        }
1411                    }
1412                }
1413                break;
1414            }
1415            case DISPATCH_PROCESSES_CHANGED: {
1416                dispatchProcessesChanged();
1417                break;
1418            }
1419            case DISPATCH_PROCESS_DIED: {
1420                final int pid = msg.arg1;
1421                final int uid = msg.arg2;
1422                dispatchProcessDied(pid, uid);
1423                break;
1424            }
1425            case REPORT_MEM_USAGE_MSG: {
1426                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1427                Thread thread = new Thread() {
1428                    @Override public void run() {
1429                        final SparseArray<ProcessMemInfo> infoMap
1430                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1431                        for (int i=0, N=memInfos.size(); i<N; i++) {
1432                            ProcessMemInfo mi = memInfos.get(i);
1433                            infoMap.put(mi.pid, mi);
1434                        }
1435                        updateCpuStatsNow();
1436                        synchronized (mProcessCpuThread) {
1437                            final int N = mProcessCpuTracker.countStats();
1438                            for (int i=0; i<N; i++) {
1439                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1440                                if (st.vsize > 0) {
1441                                    long pss = Debug.getPss(st.pid, null);
1442                                    if (pss > 0) {
1443                                        if (infoMap.indexOfKey(st.pid) < 0) {
1444                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1445                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1446                                            mi.pss = pss;
1447                                            memInfos.add(mi);
1448                                        }
1449                                    }
1450                                }
1451                            }
1452                        }
1453
1454                        long totalPss = 0;
1455                        for (int i=0, N=memInfos.size(); i<N; i++) {
1456                            ProcessMemInfo mi = memInfos.get(i);
1457                            if (mi.pss == 0) {
1458                                mi.pss = Debug.getPss(mi.pid, null);
1459                            }
1460                            totalPss += mi.pss;
1461                        }
1462                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1463                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1464                                if (lhs.oomAdj != rhs.oomAdj) {
1465                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1466                                }
1467                                if (lhs.pss != rhs.pss) {
1468                                    return lhs.pss < rhs.pss ? 1 : -1;
1469                                }
1470                                return 0;
1471                            }
1472                        });
1473
1474                        StringBuilder tag = new StringBuilder(128);
1475                        StringBuilder stack = new StringBuilder(128);
1476                        tag.append("Low on memory -- ");
1477                        appendMemBucket(tag, totalPss, "total", false);
1478                        appendMemBucket(stack, totalPss, "total", true);
1479
1480                        StringBuilder logBuilder = new StringBuilder(1024);
1481                        logBuilder.append("Low on memory:\n");
1482
1483                        boolean firstLine = true;
1484                        int lastOomAdj = Integer.MIN_VALUE;
1485                        for (int i=0, N=memInfos.size(); i<N; i++) {
1486                            ProcessMemInfo mi = memInfos.get(i);
1487
1488                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1489                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1490                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1491                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1492                                if (lastOomAdj != mi.oomAdj) {
1493                                    lastOomAdj = mi.oomAdj;
1494                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1495                                        tag.append(" / ");
1496                                    }
1497                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1498                                        if (firstLine) {
1499                                            stack.append(":");
1500                                            firstLine = false;
1501                                        }
1502                                        stack.append("\n\t at ");
1503                                    } else {
1504                                        stack.append("$");
1505                                    }
1506                                } else {
1507                                    tag.append(" ");
1508                                    stack.append("$");
1509                                }
1510                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1511                                    appendMemBucket(tag, mi.pss, mi.name, false);
1512                                }
1513                                appendMemBucket(stack, mi.pss, mi.name, true);
1514                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1515                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1516                                    stack.append("(");
1517                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1518                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1519                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1520                                            stack.append(":");
1521                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1522                                        }
1523                                    }
1524                                    stack.append(")");
1525                                }
1526                            }
1527
1528                            logBuilder.append("  ");
1529                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1530                            logBuilder.append(' ');
1531                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1532                            logBuilder.append(' ');
1533                            ProcessList.appendRamKb(logBuilder, mi.pss);
1534                            logBuilder.append(" kB: ");
1535                            logBuilder.append(mi.name);
1536                            logBuilder.append(" (");
1537                            logBuilder.append(mi.pid);
1538                            logBuilder.append(") ");
1539                            logBuilder.append(mi.adjType);
1540                            logBuilder.append('\n');
1541                            if (mi.adjReason != null) {
1542                                logBuilder.append("                      ");
1543                                logBuilder.append(mi.adjReason);
1544                                logBuilder.append('\n');
1545                            }
1546                        }
1547
1548                        logBuilder.append("           ");
1549                        ProcessList.appendRamKb(logBuilder, totalPss);
1550                        logBuilder.append(" kB: TOTAL\n");
1551
1552                        long[] infos = new long[Debug.MEMINFO_COUNT];
1553                        Debug.getMemInfo(infos);
1554                        logBuilder.append("  MemInfo: ");
1555                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1556                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1557                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1558                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1559                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1560                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1561                            logBuilder.append("  ZRAM: ");
1562                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1563                            logBuilder.append(" kB RAM, ");
1564                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1565                            logBuilder.append(" kB swap total, ");
1566                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1567                            logBuilder.append(" kB swap free\n");
1568                        }
1569                        Slog.i(TAG, logBuilder.toString());
1570
1571                        StringBuilder dropBuilder = new StringBuilder(1024);
1572                        /*
1573                        StringWriter oomSw = new StringWriter();
1574                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1575                        StringWriter catSw = new StringWriter();
1576                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1577                        String[] emptyArgs = new String[] { };
1578                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1579                        oomPw.flush();
1580                        String oomString = oomSw.toString();
1581                        */
1582                        dropBuilder.append(stack);
1583                        dropBuilder.append('\n');
1584                        dropBuilder.append('\n');
1585                        dropBuilder.append(logBuilder);
1586                        dropBuilder.append('\n');
1587                        /*
1588                        dropBuilder.append(oomString);
1589                        dropBuilder.append('\n');
1590                        */
1591                        StringWriter catSw = new StringWriter();
1592                        synchronized (ActivityManagerService.this) {
1593                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1594                            String[] emptyArgs = new String[] { };
1595                            catPw.println();
1596                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1597                            catPw.println();
1598                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1599                                    false, false, null);
1600                            catPw.println();
1601                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1602                            catPw.flush();
1603                        }
1604                        dropBuilder.append(catSw.toString());
1605                        addErrorToDropBox("lowmem", null, "system_server", null,
1606                                null, tag.toString(), dropBuilder.toString(), null, null);
1607                        //Slog.i(TAG, "Sent to dropbox:");
1608                        //Slog.i(TAG, dropBuilder.toString());
1609                        synchronized (ActivityManagerService.this) {
1610                            long now = SystemClock.uptimeMillis();
1611                            if (mLastMemUsageReportTime < now) {
1612                                mLastMemUsageReportTime = now;
1613                            }
1614                        }
1615                    }
1616                };
1617                thread.start();
1618                break;
1619            }
1620            case REPORT_USER_SWITCH_MSG: {
1621                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1622                break;
1623            }
1624            case CONTINUE_USER_SWITCH_MSG: {
1625                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1626                break;
1627            }
1628            case USER_SWITCH_TIMEOUT_MSG: {
1629                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1630                break;
1631            }
1632            case IMMERSIVE_MODE_LOCK_MSG: {
1633                final boolean nextState = (msg.arg1 != 0);
1634                if (mUpdateLock.isHeld() != nextState) {
1635                    if (DEBUG_IMMERSIVE) {
1636                        final ActivityRecord r = (ActivityRecord) msg.obj;
1637                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1638                    }
1639                    if (nextState) {
1640                        mUpdateLock.acquire();
1641                    } else {
1642                        mUpdateLock.release();
1643                    }
1644                }
1645                break;
1646            }
1647            case PERSIST_URI_GRANTS_MSG: {
1648                writeGrantedUriPermissions();
1649                break;
1650            }
1651            case REQUEST_ALL_PSS_MSG: {
1652                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1653                break;
1654            }
1655            }
1656        }
1657    };
1658
1659    static final int COLLECT_PSS_BG_MSG = 1;
1660
1661    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1662        @Override
1663        public void handleMessage(Message msg) {
1664            switch (msg.what) {
1665            case COLLECT_PSS_BG_MSG: {
1666                int i=0, num=0;
1667                long start = SystemClock.uptimeMillis();
1668                long[] tmp = new long[1];
1669                do {
1670                    ProcessRecord proc;
1671                    int procState;
1672                    int pid;
1673                    synchronized (ActivityManagerService.this) {
1674                        if (i >= mPendingPssProcesses.size()) {
1675                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1676                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1677                            mPendingPssProcesses.clear();
1678                            return;
1679                        }
1680                        proc = mPendingPssProcesses.get(i);
1681                        procState = proc.pssProcState;
1682                        if (proc.thread != null && procState == proc.setProcState) {
1683                            pid = proc.pid;
1684                        } else {
1685                            proc = null;
1686                            pid = 0;
1687                        }
1688                        i++;
1689                    }
1690                    if (proc != null) {
1691                        long pss = Debug.getPss(pid, tmp);
1692                        synchronized (ActivityManagerService.this) {
1693                            if (proc.thread != null && proc.setProcState == procState
1694                                    && proc.pid == pid) {
1695                                num++;
1696                                proc.lastPssTime = SystemClock.uptimeMillis();
1697                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1698                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1699                                        + ": " + pss + " lastPss=" + proc.lastPss
1700                                        + " state=" + ProcessList.makeProcStateString(procState));
1701                                if (proc.initialIdlePss == 0) {
1702                                    proc.initialIdlePss = pss;
1703                                }
1704                                proc.lastPss = pss;
1705                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1706                                    proc.lastCachedPss = pss;
1707                                }
1708                            }
1709                        }
1710                    }
1711                } while (true);
1712            }
1713            }
1714        }
1715    };
1716
1717    public void setSystemProcess() {
1718        try {
1719            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1720            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1721            ServiceManager.addService("meminfo", new MemBinder(this));
1722            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1723            ServiceManager.addService("dbinfo", new DbBinder(this));
1724            if (MONITOR_CPU_USAGE) {
1725                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1726            }
1727            ServiceManager.addService("permission", new PermissionController(this));
1728
1729            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1730                    "android", STOCK_PM_FLAGS);
1731            mSystemThread.installSystemApplicationInfo(info);
1732
1733            synchronized (this) {
1734                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1735                app.persistent = true;
1736                app.pid = MY_PID;
1737                app.maxAdj = ProcessList.SYSTEM_ADJ;
1738                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1739                mProcessNames.put(app.processName, app.uid, app);
1740                synchronized (mPidsSelfLocked) {
1741                    mPidsSelfLocked.put(app.pid, app);
1742                }
1743                updateLruProcessLocked(app, false, null);
1744                updateOomAdjLocked();
1745            }
1746        } catch (PackageManager.NameNotFoundException e) {
1747            throw new RuntimeException(
1748                    "Unable to find android system package", e);
1749        }
1750    }
1751
1752    public void setWindowManager(WindowManagerService wm) {
1753        mWindowManager = wm;
1754        mStackSupervisor.setWindowManager(wm);
1755    }
1756
1757    public void startObservingNativeCrashes() {
1758        final NativeCrashListener ncl = new NativeCrashListener(this);
1759        ncl.start();
1760    }
1761
1762    public IAppOpsService getAppOpsService() {
1763        return mAppOpsService;
1764    }
1765
1766    static class MemBinder extends Binder {
1767        ActivityManagerService mActivityManagerService;
1768        MemBinder(ActivityManagerService activityManagerService) {
1769            mActivityManagerService = activityManagerService;
1770        }
1771
1772        @Override
1773        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1774            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1775                    != PackageManager.PERMISSION_GRANTED) {
1776                pw.println("Permission Denial: can't dump meminfo from from pid="
1777                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1778                        + " without permission " + android.Manifest.permission.DUMP);
1779                return;
1780            }
1781
1782            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1783        }
1784    }
1785
1786    static class GraphicsBinder extends Binder {
1787        ActivityManagerService mActivityManagerService;
1788        GraphicsBinder(ActivityManagerService activityManagerService) {
1789            mActivityManagerService = activityManagerService;
1790        }
1791
1792        @Override
1793        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1794            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1795                    != PackageManager.PERMISSION_GRANTED) {
1796                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1797                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1798                        + " without permission " + android.Manifest.permission.DUMP);
1799                return;
1800            }
1801
1802            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1803        }
1804    }
1805
1806    static class DbBinder extends Binder {
1807        ActivityManagerService mActivityManagerService;
1808        DbBinder(ActivityManagerService activityManagerService) {
1809            mActivityManagerService = activityManagerService;
1810        }
1811
1812        @Override
1813        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1814            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1815                    != PackageManager.PERMISSION_GRANTED) {
1816                pw.println("Permission Denial: can't dump dbinfo from from pid="
1817                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1818                        + " without permission " + android.Manifest.permission.DUMP);
1819                return;
1820            }
1821
1822            mActivityManagerService.dumpDbInfo(fd, pw, args);
1823        }
1824    }
1825
1826    static class CpuBinder extends Binder {
1827        ActivityManagerService mActivityManagerService;
1828        CpuBinder(ActivityManagerService activityManagerService) {
1829            mActivityManagerService = activityManagerService;
1830        }
1831
1832        @Override
1833        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1834            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1835                    != PackageManager.PERMISSION_GRANTED) {
1836                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1837                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1838                        + " without permission " + android.Manifest.permission.DUMP);
1839                return;
1840            }
1841
1842            synchronized (mActivityManagerService.mProcessCpuThread) {
1843                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1844                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1845                        SystemClock.uptimeMillis()));
1846            }
1847        }
1848    }
1849
1850    public static final class Lifecycle extends SystemService {
1851        private final ActivityManagerService mService;
1852
1853        public Lifecycle(Context context) {
1854            super(context);
1855            mService = new ActivityManagerService(context);
1856        }
1857
1858        @Override
1859        public void onStart() {
1860            mService.start();
1861        }
1862
1863        public ActivityManagerService getService() {
1864            return mService;
1865        }
1866    }
1867
1868    // Note: This method is invoked on the main thread but may need to attach various
1869    // handlers to other threads.  So take care to be explicit about the looper.
1870    public ActivityManagerService(Context systemContext) {
1871        mContext = systemContext;
1872        mFactoryTest = FactoryTest.getMode();
1873        mSystemThread = ActivityThread.currentActivityThread();
1874
1875        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1876
1877        mHandlerThread = new ServiceThread(TAG,
1878                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1879        mHandlerThread.start();
1880        mHandler = new MainHandler(mHandlerThread.getLooper());
1881
1882        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1883                "foreground", BROADCAST_FG_TIMEOUT, false);
1884        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1885                "background", BROADCAST_BG_TIMEOUT, true);
1886        mBroadcastQueues[0] = mFgBroadcastQueue;
1887        mBroadcastQueues[1] = mBgBroadcastQueue;
1888
1889        mServices = new ActiveServices(this);
1890        mProviderMap = new ProviderMap(this);
1891
1892        // TODO: Move creation of battery stats service outside of activity manager service.
1893        File dataDir = Environment.getDataDirectory();
1894        File systemDir = new File(dataDir, "system");
1895        systemDir.mkdirs();
1896        mBatteryStatsService = new BatteryStatsService(new File(
1897                systemDir, "batterystats.bin").toString(), mHandler);
1898        mBatteryStatsService.getActiveStatistics().readLocked();
1899        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1900        mOnBattery = DEBUG_POWER ? true
1901                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1902        mBatteryStatsService.getActiveStatistics().setCallback(this);
1903
1904        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1905
1906        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1907        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1908
1909        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1910
1911        // User 0 is the first and only user that runs at boot.
1912        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1913        mUserLru.add(Integer.valueOf(0));
1914        updateStartedUserArrayLocked();
1915
1916        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1917            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1918
1919        mConfiguration.setToDefaults();
1920        mConfiguration.setLocale(Locale.getDefault());
1921
1922        mConfigurationSeq = mConfiguration.seq = 1;
1923        mProcessCpuTracker.init();
1924
1925        mHasRecents = mContext.getResources().getBoolean(
1926                com.android.internal.R.bool.config_hasRecents);
1927
1928        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1929        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1930        mStackSupervisor = new ActivityStackSupervisor(this);
1931
1932        mProcessCpuThread = new Thread("CpuTracker") {
1933            @Override
1934            public void run() {
1935                while (true) {
1936                    try {
1937                        try {
1938                            synchronized(this) {
1939                                final long now = SystemClock.uptimeMillis();
1940                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1941                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1942                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1943                                //        + ", write delay=" + nextWriteDelay);
1944                                if (nextWriteDelay < nextCpuDelay) {
1945                                    nextCpuDelay = nextWriteDelay;
1946                                }
1947                                if (nextCpuDelay > 0) {
1948                                    mProcessCpuMutexFree.set(true);
1949                                    this.wait(nextCpuDelay);
1950                                }
1951                            }
1952                        } catch (InterruptedException e) {
1953                        }
1954                        updateCpuStatsNow();
1955                    } catch (Exception e) {
1956                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1957                    }
1958                }
1959            }
1960        };
1961
1962        Watchdog.getInstance().addMonitor(this);
1963        Watchdog.getInstance().addThread(mHandler);
1964    }
1965
1966    private void start() {
1967        mProcessCpuThread.start();
1968
1969        mBatteryStatsService.publish(mContext);
1970        mUsageStatsService.publish(mContext);
1971        mAppOpsService.publish(mContext);
1972
1973        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
1974    }
1975
1976    @Override
1977    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1978            throws RemoteException {
1979        if (code == SYSPROPS_TRANSACTION) {
1980            // We need to tell all apps about the system property change.
1981            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1982            synchronized(this) {
1983                final int NP = mProcessNames.getMap().size();
1984                for (int ip=0; ip<NP; ip++) {
1985                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
1986                    final int NA = apps.size();
1987                    for (int ia=0; ia<NA; ia++) {
1988                        ProcessRecord app = apps.valueAt(ia);
1989                        if (app.thread != null) {
1990                            procs.add(app.thread.asBinder());
1991                        }
1992                    }
1993                }
1994            }
1995
1996            int N = procs.size();
1997            for (int i=0; i<N; i++) {
1998                Parcel data2 = Parcel.obtain();
1999                try {
2000                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2001                } catch (RemoteException e) {
2002                }
2003                data2.recycle();
2004            }
2005        }
2006        try {
2007            return super.onTransact(code, data, reply, flags);
2008        } catch (RuntimeException e) {
2009            // The activity manager only throws security exceptions, so let's
2010            // log all others.
2011            if (!(e instanceof SecurityException)) {
2012                Slog.wtf(TAG, "Activity Manager Crash", e);
2013            }
2014            throw e;
2015        }
2016    }
2017
2018    void updateCpuStats() {
2019        final long now = SystemClock.uptimeMillis();
2020        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2021            return;
2022        }
2023        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2024            synchronized (mProcessCpuThread) {
2025                mProcessCpuThread.notify();
2026            }
2027        }
2028    }
2029
2030    void updateCpuStatsNow() {
2031        synchronized (mProcessCpuThread) {
2032            mProcessCpuMutexFree.set(false);
2033            final long now = SystemClock.uptimeMillis();
2034            boolean haveNewCpuStats = false;
2035
2036            if (MONITOR_CPU_USAGE &&
2037                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2038                mLastCpuTime.set(now);
2039                haveNewCpuStats = true;
2040                mProcessCpuTracker.update();
2041                //Slog.i(TAG, mProcessCpu.printCurrentState());
2042                //Slog.i(TAG, "Total CPU usage: "
2043                //        + mProcessCpu.getTotalCpuPercent() + "%");
2044
2045                // Slog the cpu usage if the property is set.
2046                if ("true".equals(SystemProperties.get("events.cpu"))) {
2047                    int user = mProcessCpuTracker.getLastUserTime();
2048                    int system = mProcessCpuTracker.getLastSystemTime();
2049                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2050                    int irq = mProcessCpuTracker.getLastIrqTime();
2051                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2052                    int idle = mProcessCpuTracker.getLastIdleTime();
2053
2054                    int total = user + system + iowait + irq + softIrq + idle;
2055                    if (total == 0) total = 1;
2056
2057                    EventLog.writeEvent(EventLogTags.CPU,
2058                            ((user+system+iowait+irq+softIrq) * 100) / total,
2059                            (user * 100) / total,
2060                            (system * 100) / total,
2061                            (iowait * 100) / total,
2062                            (irq * 100) / total,
2063                            (softIrq * 100) / total);
2064                }
2065            }
2066
2067            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2068            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2069            synchronized(bstats) {
2070                synchronized(mPidsSelfLocked) {
2071                    if (haveNewCpuStats) {
2072                        if (mOnBattery) {
2073                            int perc = bstats.startAddingCpuLocked();
2074                            int totalUTime = 0;
2075                            int totalSTime = 0;
2076                            final int N = mProcessCpuTracker.countStats();
2077                            for (int i=0; i<N; i++) {
2078                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2079                                if (!st.working) {
2080                                    continue;
2081                                }
2082                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2083                                int otherUTime = (st.rel_utime*perc)/100;
2084                                int otherSTime = (st.rel_stime*perc)/100;
2085                                totalUTime += otherUTime;
2086                                totalSTime += otherSTime;
2087                                if (pr != null) {
2088                                    BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked(
2089                                            st.name, st.pid);
2090                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2091                                            st.rel_stime-otherSTime);
2092                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2093                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2094                                } else if (st.uid >= Process.FIRST_APPLICATION_UID) {
2095                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2096                                    if (ps == null) {
2097                                        st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid,
2098                                                "(Unknown)");
2099                                    }
2100                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2101                                            st.rel_stime-otherSTime);
2102                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2103                                } else {
2104                                    BatteryStatsImpl.Uid.Proc ps =
2105                                            bstats.getProcessStatsLocked(st.name, st.pid);
2106                                    if (ps != null) {
2107                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2108                                                st.rel_stime-otherSTime);
2109                                        ps.addSpeedStepTimes(cpuSpeedTimes);
2110                                    }
2111                                }
2112                            }
2113                            bstats.finishAddingCpuLocked(perc, totalUTime,
2114                                    totalSTime, cpuSpeedTimes);
2115                        }
2116                    }
2117                }
2118
2119                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2120                    mLastWriteTime = now;
2121                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2122                }
2123            }
2124        }
2125    }
2126
2127    @Override
2128    public void batteryNeedsCpuUpdate() {
2129        updateCpuStatsNow();
2130    }
2131
2132    @Override
2133    public void batteryPowerChanged(boolean onBattery) {
2134        // When plugging in, update the CPU stats first before changing
2135        // the plug state.
2136        updateCpuStatsNow();
2137        synchronized (this) {
2138            synchronized(mPidsSelfLocked) {
2139                mOnBattery = DEBUG_POWER ? true : onBattery;
2140            }
2141        }
2142    }
2143
2144    /**
2145     * Initialize the application bind args. These are passed to each
2146     * process when the bindApplication() IPC is sent to the process. They're
2147     * lazily setup to make sure the services are running when they're asked for.
2148     */
2149    private HashMap<String, IBinder> getCommonServicesLocked() {
2150        if (mAppBindArgs == null) {
2151            mAppBindArgs = new HashMap<String, IBinder>();
2152
2153            // Setup the application init args
2154            mAppBindArgs.put("package", ServiceManager.getService("package"));
2155            mAppBindArgs.put("window", ServiceManager.getService("window"));
2156            mAppBindArgs.put(Context.ALARM_SERVICE,
2157                    ServiceManager.getService(Context.ALARM_SERVICE));
2158        }
2159        return mAppBindArgs;
2160    }
2161
2162    final void setFocusedActivityLocked(ActivityRecord r) {
2163        if (mFocusedActivity != r) {
2164            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2165            mFocusedActivity = r;
2166            mStackSupervisor.setFocusedStack(r);
2167            if (r != null) {
2168                mWindowManager.setFocusedApp(r.appToken, true);
2169            }
2170            applyUpdateLockStateLocked(r);
2171        }
2172    }
2173
2174    @Override
2175    public void setFocusedStack(int stackId) {
2176        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2177        synchronized (ActivityManagerService.this) {
2178            ActivityStack stack = mStackSupervisor.getStack(stackId);
2179            if (stack != null) {
2180                ActivityRecord r = stack.topRunningActivityLocked(null);
2181                if (r != null) {
2182                    setFocusedActivityLocked(r);
2183                }
2184            }
2185        }
2186    }
2187
2188    @Override
2189    public void notifyActivityDrawn(IBinder token) {
2190        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2191        synchronized (this) {
2192            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2193            if (r != null) {
2194                r.task.stack.notifyActivityDrawnLocked(r);
2195            }
2196        }
2197    }
2198
2199    final void applyUpdateLockStateLocked(ActivityRecord r) {
2200        // Modifications to the UpdateLock state are done on our handler, outside
2201        // the activity manager's locks.  The new state is determined based on the
2202        // state *now* of the relevant activity record.  The object is passed to
2203        // the handler solely for logging detail, not to be consulted/modified.
2204        final boolean nextState = r != null && r.immersive;
2205        mHandler.sendMessage(
2206                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2207    }
2208
2209    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2210        Message msg = Message.obtain();
2211        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2212        msg.obj = r.task.askedCompatMode ? null : r;
2213        mHandler.sendMessage(msg);
2214    }
2215
2216    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2217            String what, Object obj, ProcessRecord srcApp) {
2218        app.lastActivityTime = now;
2219
2220        if (app.activities.size() > 0) {
2221            // Don't want to touch dependent processes that are hosting activities.
2222            return index;
2223        }
2224
2225        int lrui = mLruProcesses.lastIndexOf(app);
2226        if (lrui < 0) {
2227            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2228                    + what + " " + obj + " from " + srcApp);
2229            return index;
2230        }
2231
2232        if (lrui >= index) {
2233            // Don't want to cause this to move dependent processes *back* in the
2234            // list as if they were less frequently used.
2235            return index;
2236        }
2237
2238        if (lrui >= mLruProcessActivityStart) {
2239            // Don't want to touch dependent processes that are hosting activities.
2240            return index;
2241        }
2242
2243        mLruProcesses.remove(lrui);
2244        if (index > 0) {
2245            index--;
2246        }
2247        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2248                + " in LRU list: " + app);
2249        mLruProcesses.add(index, app);
2250        return index;
2251    }
2252
2253    final void removeLruProcessLocked(ProcessRecord app) {
2254        int lrui = mLruProcesses.lastIndexOf(app);
2255        if (lrui >= 0) {
2256            if (lrui <= mLruProcessActivityStart) {
2257                mLruProcessActivityStart--;
2258            }
2259            if (lrui <= mLruProcessServiceStart) {
2260                mLruProcessServiceStart--;
2261            }
2262            mLruProcesses.remove(lrui);
2263        }
2264    }
2265
2266    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2267            ProcessRecord client) {
2268        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2269        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2270        if (!activityChange && hasActivity) {
2271            // The process has activties, so we are only going to allow activity-based
2272            // adjustments move it.  It should be kept in the front of the list with other
2273            // processes that have activities, and we don't want those to change their
2274            // order except due to activity operations.
2275            return;
2276        }
2277
2278        mLruSeq++;
2279        final long now = SystemClock.uptimeMillis();
2280        app.lastActivityTime = now;
2281
2282        // First a quick reject: if the app is already at the position we will
2283        // put it, then there is nothing to do.
2284        if (hasActivity) {
2285            final int N = mLruProcesses.size();
2286            if (N > 0 && mLruProcesses.get(N-1) == app) {
2287                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2288                return;
2289            }
2290        } else {
2291            if (mLruProcessServiceStart > 0
2292                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2293                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2294                return;
2295            }
2296        }
2297
2298        int lrui = mLruProcesses.lastIndexOf(app);
2299
2300        if (app.persistent && lrui >= 0) {
2301            // We don't care about the position of persistent processes, as long as
2302            // they are in the list.
2303            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2304            return;
2305        }
2306
2307        /* In progress: compute new position first, so we can avoid doing work
2308           if the process is not actually going to move.  Not yet working.
2309        int addIndex;
2310        int nextIndex;
2311        boolean inActivity = false, inService = false;
2312        if (hasActivity) {
2313            // Process has activities, put it at the very tipsy-top.
2314            addIndex = mLruProcesses.size();
2315            nextIndex = mLruProcessServiceStart;
2316            inActivity = true;
2317        } else if (hasService) {
2318            // Process has services, put it at the top of the service list.
2319            addIndex = mLruProcessActivityStart;
2320            nextIndex = mLruProcessServiceStart;
2321            inActivity = true;
2322            inService = true;
2323        } else  {
2324            // Process not otherwise of interest, it goes to the top of the non-service area.
2325            addIndex = mLruProcessServiceStart;
2326            if (client != null) {
2327                int clientIndex = mLruProcesses.lastIndexOf(client);
2328                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2329                        + app);
2330                if (clientIndex >= 0 && addIndex > clientIndex) {
2331                    addIndex = clientIndex;
2332                }
2333            }
2334            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2335        }
2336
2337        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2338                + mLruProcessActivityStart + "): " + app);
2339        */
2340
2341        if (lrui >= 0) {
2342            if (lrui < mLruProcessActivityStart) {
2343                mLruProcessActivityStart--;
2344            }
2345            if (lrui < mLruProcessServiceStart) {
2346                mLruProcessServiceStart--;
2347            }
2348            /*
2349            if (addIndex > lrui) {
2350                addIndex--;
2351            }
2352            if (nextIndex > lrui) {
2353                nextIndex--;
2354            }
2355            */
2356            mLruProcesses.remove(lrui);
2357        }
2358
2359        /*
2360        mLruProcesses.add(addIndex, app);
2361        if (inActivity) {
2362            mLruProcessActivityStart++;
2363        }
2364        if (inService) {
2365            mLruProcessActivityStart++;
2366        }
2367        */
2368
2369        int nextIndex;
2370        if (hasActivity) {
2371            final int N = mLruProcesses.size();
2372            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2373                // Process doesn't have activities, but has clients with
2374                // activities...  move it up, but one below the top (the top
2375                // should always have a real activity).
2376                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2377                mLruProcesses.add(N-1, app);
2378                // To keep it from spamming the LRU list (by making a bunch of clients),
2379                // we will push down any other entries owned by the app.
2380                final int uid = app.info.uid;
2381                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2382                    ProcessRecord subProc = mLruProcesses.get(i);
2383                    if (subProc.info.uid == uid) {
2384                        // We want to push this one down the list.  If the process after
2385                        // it is for the same uid, however, don't do so, because we don't
2386                        // want them internally to be re-ordered.
2387                        if (mLruProcesses.get(i-1).info.uid != uid) {
2388                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2389                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2390                            ProcessRecord tmp = mLruProcesses.get(i);
2391                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2392                            mLruProcesses.set(i-1, tmp);
2393                            i--;
2394                        }
2395                    } else {
2396                        // A gap, we can stop here.
2397                        break;
2398                    }
2399                }
2400            } else {
2401                // Process has activities, put it at the very tipsy-top.
2402                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2403                mLruProcesses.add(app);
2404            }
2405            nextIndex = mLruProcessServiceStart;
2406        } else if (hasService) {
2407            // Process has services, put it at the top of the service list.
2408            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2409            mLruProcesses.add(mLruProcessActivityStart, app);
2410            nextIndex = mLruProcessServiceStart;
2411            mLruProcessActivityStart++;
2412        } else  {
2413            // Process not otherwise of interest, it goes to the top of the non-service area.
2414            int index = mLruProcessServiceStart;
2415            if (client != null) {
2416                // If there is a client, don't allow the process to be moved up higher
2417                // in the list than that client.
2418                int clientIndex = mLruProcesses.lastIndexOf(client);
2419                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2420                        + " when updating " + app);
2421                if (clientIndex <= lrui) {
2422                    // Don't allow the client index restriction to push it down farther in the
2423                    // list than it already is.
2424                    clientIndex = lrui;
2425                }
2426                if (clientIndex >= 0 && index > clientIndex) {
2427                    index = clientIndex;
2428                }
2429            }
2430            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2431            mLruProcesses.add(index, app);
2432            nextIndex = index-1;
2433            mLruProcessActivityStart++;
2434            mLruProcessServiceStart++;
2435        }
2436
2437        // If the app is currently using a content provider or service,
2438        // bump those processes as well.
2439        for (int j=app.connections.size()-1; j>=0; j--) {
2440            ConnectionRecord cr = app.connections.valueAt(j);
2441            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2442                    && cr.binding.service.app != null
2443                    && cr.binding.service.app.lruSeq != mLruSeq
2444                    && !cr.binding.service.app.persistent) {
2445                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2446                        "service connection", cr, app);
2447            }
2448        }
2449        for (int j=app.conProviders.size()-1; j>=0; j--) {
2450            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2451            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2452                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2453                        "provider reference", cpr, app);
2454            }
2455        }
2456    }
2457
2458    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2459        if (uid == Process.SYSTEM_UID) {
2460            // The system gets to run in any process.  If there are multiple
2461            // processes with the same uid, just pick the first (this
2462            // should never happen).
2463            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2464            if (procs == null) return null;
2465            final int N = procs.size();
2466            for (int i = 0; i < N; i++) {
2467                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2468            }
2469        }
2470        ProcessRecord proc = mProcessNames.get(processName, uid);
2471        if (false && proc != null && !keepIfLarge
2472                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2473                && proc.lastCachedPss >= 4000) {
2474            // Turn this condition on to cause killing to happen regularly, for testing.
2475            if (proc.baseProcessTracker != null) {
2476                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2477            }
2478            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2479                    + "k from cached");
2480        } else if (proc != null && !keepIfLarge
2481                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2482                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2483            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2484            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2485                if (proc.baseProcessTracker != null) {
2486                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2487                }
2488                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2489                        + "k from cached");
2490            }
2491        }
2492        return proc;
2493    }
2494
2495    void ensurePackageDexOpt(String packageName) {
2496        IPackageManager pm = AppGlobals.getPackageManager();
2497        try {
2498            if (pm.performDexOpt(packageName)) {
2499                mDidDexOpt = true;
2500            }
2501        } catch (RemoteException e) {
2502        }
2503    }
2504
2505    boolean isNextTransitionForward() {
2506        int transit = mWindowManager.getPendingAppTransition();
2507        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2508                || transit == AppTransition.TRANSIT_TASK_OPEN
2509                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2510    }
2511
2512    final ProcessRecord startProcessLocked(String processName,
2513            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2514            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2515            boolean isolated, boolean keepIfLarge) {
2516        ProcessRecord app;
2517        if (!isolated) {
2518            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2519        } else {
2520            // If this is an isolated process, it can't re-use an existing process.
2521            app = null;
2522        }
2523        // We don't have to do anything more if:
2524        // (1) There is an existing application record; and
2525        // (2) The caller doesn't think it is dead, OR there is no thread
2526        //     object attached to it so we know it couldn't have crashed; and
2527        // (3) There is a pid assigned to it, so it is either starting or
2528        //     already running.
2529        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2530                + " app=" + app + " knownToBeDead=" + knownToBeDead
2531                + " thread=" + (app != null ? app.thread : null)
2532                + " pid=" + (app != null ? app.pid : -1));
2533        if (app != null && app.pid > 0) {
2534            if (!knownToBeDead || app.thread == null) {
2535                // We already have the app running, or are waiting for it to
2536                // come up (we have a pid but not yet its thread), so keep it.
2537                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2538                // If this is a new package in the process, add the package to the list
2539                app.addPackage(info.packageName, mProcessStats);
2540                return app;
2541            }
2542
2543            // An application record is attached to a previous process,
2544            // clean it up now.
2545            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2546            handleAppDiedLocked(app, true, true);
2547        }
2548
2549        String hostingNameStr = hostingName != null
2550                ? hostingName.flattenToShortString() : null;
2551
2552        if (!isolated) {
2553            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2554                // If we are in the background, then check to see if this process
2555                // is bad.  If so, we will just silently fail.
2556                if (mBadProcesses.get(info.processName, info.uid) != null) {
2557                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2558                            + "/" + info.processName);
2559                    return null;
2560                }
2561            } else {
2562                // When the user is explicitly starting a process, then clear its
2563                // crash count so that we won't make it bad until they see at
2564                // least one crash dialog again, and make the process good again
2565                // if it had been bad.
2566                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2567                        + "/" + info.processName);
2568                mProcessCrashTimes.remove(info.processName, info.uid);
2569                if (mBadProcesses.get(info.processName, info.uid) != null) {
2570                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2571                            UserHandle.getUserId(info.uid), info.uid,
2572                            info.processName);
2573                    mBadProcesses.remove(info.processName, info.uid);
2574                    if (app != null) {
2575                        app.bad = false;
2576                    }
2577                }
2578            }
2579        }
2580
2581        if (app == null) {
2582            app = newProcessRecordLocked(info, processName, isolated);
2583            if (app == null) {
2584                Slog.w(TAG, "Failed making new process record for "
2585                        + processName + "/" + info.uid + " isolated=" + isolated);
2586                return null;
2587            }
2588            mProcessNames.put(processName, app.uid, app);
2589            if (isolated) {
2590                mIsolatedProcesses.put(app.uid, app);
2591            }
2592        } else {
2593            // If this is a new package in the process, add the package to the list
2594            app.addPackage(info.packageName, mProcessStats);
2595        }
2596
2597        // If the system is not ready yet, then hold off on starting this
2598        // process until it is.
2599        if (!mProcessesReady
2600                && !isAllowedWhileBooting(info)
2601                && !allowWhileBooting) {
2602            if (!mProcessesOnHold.contains(app)) {
2603                mProcessesOnHold.add(app);
2604            }
2605            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2606            return app;
2607        }
2608
2609        startProcessLocked(app, hostingType, hostingNameStr);
2610        return (app.pid != 0) ? app : null;
2611    }
2612
2613    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2614        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2615    }
2616
2617    private final void startProcessLocked(ProcessRecord app,
2618            String hostingType, String hostingNameStr) {
2619        if (app.pid > 0 && app.pid != MY_PID) {
2620            synchronized (mPidsSelfLocked) {
2621                mPidsSelfLocked.remove(app.pid);
2622                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2623            }
2624            app.setPid(0);
2625        }
2626
2627        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2628                "startProcessLocked removing on hold: " + app);
2629        mProcessesOnHold.remove(app);
2630
2631        updateCpuStats();
2632
2633        try {
2634            int uid = app.uid;
2635
2636            int[] gids = null;
2637            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2638            if (!app.isolated) {
2639                int[] permGids = null;
2640                try {
2641                    final PackageManager pm = mContext.getPackageManager();
2642                    permGids = pm.getPackageGids(app.info.packageName);
2643
2644                    if (Environment.isExternalStorageEmulated()) {
2645                        if (pm.checkPermission(
2646                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2647                                app.info.packageName) == PERMISSION_GRANTED) {
2648                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2649                        } else {
2650                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2651                        }
2652                    }
2653                } catch (PackageManager.NameNotFoundException e) {
2654                    Slog.w(TAG, "Unable to retrieve gids", e);
2655                }
2656
2657                /*
2658                 * Add shared application GID so applications can share some
2659                 * resources like shared libraries
2660                 */
2661                if (permGids == null) {
2662                    gids = new int[1];
2663                } else {
2664                    gids = new int[permGids.length + 1];
2665                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2666                }
2667                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2668            }
2669            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2670                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2671                        && mTopComponent != null
2672                        && app.processName.equals(mTopComponent.getPackageName())) {
2673                    uid = 0;
2674                }
2675                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2676                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2677                    uid = 0;
2678                }
2679            }
2680            int debugFlags = 0;
2681            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2682                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2683                // Also turn on CheckJNI for debuggable apps. It's quite
2684                // awkward to turn on otherwise.
2685                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2686            }
2687            // Run the app in safe mode if its manifest requests so or the
2688            // system is booted in safe mode.
2689            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2690                Zygote.systemInSafeMode == true) {
2691                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2692            }
2693            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2694                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2695            }
2696            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2697                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2698            }
2699            if ("1".equals(SystemProperties.get("debug.assert"))) {
2700                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2701            }
2702
2703            // Start the process.  It will either succeed and return a result containing
2704            // the PID of the new process, or else throw a RuntimeException.
2705            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2706                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2707                    app.info.targetSdkVersion, app.info.seinfo, null);
2708
2709            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2710            synchronized (bs) {
2711                if (bs.isOnBattery()) {
2712                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2713                }
2714            }
2715
2716            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2717                    UserHandle.getUserId(uid), startResult.pid, uid,
2718                    app.processName, hostingType,
2719                    hostingNameStr != null ? hostingNameStr : "");
2720
2721            if (app.persistent) {
2722                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2723            }
2724
2725            StringBuilder buf = mStringBuilder;
2726            buf.setLength(0);
2727            buf.append("Start proc ");
2728            buf.append(app.processName);
2729            buf.append(" for ");
2730            buf.append(hostingType);
2731            if (hostingNameStr != null) {
2732                buf.append(" ");
2733                buf.append(hostingNameStr);
2734            }
2735            buf.append(": pid=");
2736            buf.append(startResult.pid);
2737            buf.append(" uid=");
2738            buf.append(uid);
2739            buf.append(" gids={");
2740            if (gids != null) {
2741                for (int gi=0; gi<gids.length; gi++) {
2742                    if (gi != 0) buf.append(", ");
2743                    buf.append(gids[gi]);
2744
2745                }
2746            }
2747            buf.append("}");
2748            Slog.i(TAG, buf.toString());
2749            app.setPid(startResult.pid);
2750            app.usingWrapper = startResult.usingWrapper;
2751            app.removed = false;
2752            synchronized (mPidsSelfLocked) {
2753                this.mPidsSelfLocked.put(startResult.pid, app);
2754                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2755                msg.obj = app;
2756                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2757                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2758            }
2759        } catch (RuntimeException e) {
2760            // XXX do better error recovery.
2761            app.setPid(0);
2762            Slog.e(TAG, "Failure starting process " + app.processName, e);
2763        }
2764    }
2765
2766    void updateUsageStats(ActivityRecord component, boolean resumed) {
2767        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2768        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2769        if (resumed) {
2770            mUsageStatsService.noteResumeComponent(component.realActivity);
2771            synchronized (stats) {
2772                stats.noteActivityResumedLocked(component.app.uid);
2773            }
2774        } else {
2775            mUsageStatsService.notePauseComponent(component.realActivity);
2776            synchronized (stats) {
2777                stats.noteActivityPausedLocked(component.app.uid);
2778            }
2779        }
2780    }
2781
2782    Intent getHomeIntent() {
2783        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2784        intent.setComponent(mTopComponent);
2785        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2786            intent.addCategory(Intent.CATEGORY_HOME);
2787        }
2788        return intent;
2789    }
2790
2791    boolean startHomeActivityLocked(int userId) {
2792        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2793                && mTopAction == null) {
2794            // We are running in factory test mode, but unable to find
2795            // the factory test app, so just sit around displaying the
2796            // error message and don't try to start anything.
2797            return false;
2798        }
2799        Intent intent = getHomeIntent();
2800        ActivityInfo aInfo =
2801            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2802        if (aInfo != null) {
2803            intent.setComponent(new ComponentName(
2804                    aInfo.applicationInfo.packageName, aInfo.name));
2805            // Don't do this if the home app is currently being
2806            // instrumented.
2807            aInfo = new ActivityInfo(aInfo);
2808            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2809            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2810                    aInfo.applicationInfo.uid, true);
2811            if (app == null || app.instrumentationClass == null) {
2812                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2813                mStackSupervisor.startHomeActivity(intent, aInfo);
2814            }
2815        }
2816
2817        return true;
2818    }
2819
2820    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2821        ActivityInfo ai = null;
2822        ComponentName comp = intent.getComponent();
2823        try {
2824            if (comp != null) {
2825                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2826            } else {
2827                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2828                        intent,
2829                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2830                            flags, userId);
2831
2832                if (info != null) {
2833                    ai = info.activityInfo;
2834                }
2835            }
2836        } catch (RemoteException e) {
2837            // ignore
2838        }
2839
2840        return ai;
2841    }
2842
2843    /**
2844     * Starts the "new version setup screen" if appropriate.
2845     */
2846    void startSetupActivityLocked() {
2847        // Only do this once per boot.
2848        if (mCheckedForSetup) {
2849            return;
2850        }
2851
2852        // We will show this screen if the current one is a different
2853        // version than the last one shown, and we are not running in
2854        // low-level factory test mode.
2855        final ContentResolver resolver = mContext.getContentResolver();
2856        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2857                Settings.Global.getInt(resolver,
2858                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2859            mCheckedForSetup = true;
2860
2861            // See if we should be showing the platform update setup UI.
2862            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2863            List<ResolveInfo> ris = mContext.getPackageManager()
2864                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2865
2866            // We don't allow third party apps to replace this.
2867            ResolveInfo ri = null;
2868            for (int i=0; ris != null && i<ris.size(); i++) {
2869                if ((ris.get(i).activityInfo.applicationInfo.flags
2870                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2871                    ri = ris.get(i);
2872                    break;
2873                }
2874            }
2875
2876            if (ri != null) {
2877                String vers = ri.activityInfo.metaData != null
2878                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2879                        : null;
2880                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2881                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2882                            Intent.METADATA_SETUP_VERSION);
2883                }
2884                String lastVers = Settings.Secure.getString(
2885                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2886                if (vers != null && !vers.equals(lastVers)) {
2887                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2888                    intent.setComponent(new ComponentName(
2889                            ri.activityInfo.packageName, ri.activityInfo.name));
2890                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2891                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2892                }
2893            }
2894        }
2895    }
2896
2897    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2898        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2899    }
2900
2901    void enforceNotIsolatedCaller(String caller) {
2902        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2903            throw new SecurityException("Isolated process not allowed to call " + caller);
2904        }
2905    }
2906
2907    @Override
2908    public int getFrontActivityScreenCompatMode() {
2909        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2910        synchronized (this) {
2911            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2912        }
2913    }
2914
2915    @Override
2916    public void setFrontActivityScreenCompatMode(int mode) {
2917        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2918                "setFrontActivityScreenCompatMode");
2919        synchronized (this) {
2920            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2921        }
2922    }
2923
2924    @Override
2925    public int getPackageScreenCompatMode(String packageName) {
2926        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2927        synchronized (this) {
2928            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2929        }
2930    }
2931
2932    @Override
2933    public void setPackageScreenCompatMode(String packageName, int mode) {
2934        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2935                "setPackageScreenCompatMode");
2936        synchronized (this) {
2937            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2938        }
2939    }
2940
2941    @Override
2942    public boolean getPackageAskScreenCompat(String packageName) {
2943        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2944        synchronized (this) {
2945            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2946        }
2947    }
2948
2949    @Override
2950    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2951        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2952                "setPackageAskScreenCompat");
2953        synchronized (this) {
2954            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2955        }
2956    }
2957
2958    private void dispatchProcessesChanged() {
2959        int N;
2960        synchronized (this) {
2961            N = mPendingProcessChanges.size();
2962            if (mActiveProcessChanges.length < N) {
2963                mActiveProcessChanges = new ProcessChangeItem[N];
2964            }
2965            mPendingProcessChanges.toArray(mActiveProcessChanges);
2966            mAvailProcessChanges.addAll(mPendingProcessChanges);
2967            mPendingProcessChanges.clear();
2968            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2969        }
2970
2971        int i = mProcessObservers.beginBroadcast();
2972        while (i > 0) {
2973            i--;
2974            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2975            if (observer != null) {
2976                try {
2977                    for (int j=0; j<N; j++) {
2978                        ProcessChangeItem item = mActiveProcessChanges[j];
2979                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2980                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2981                                    + item.pid + " uid=" + item.uid + ": "
2982                                    + item.foregroundActivities);
2983                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2984                                    item.foregroundActivities);
2985                        }
2986                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2987                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2988                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2989                            observer.onImportanceChanged(item.pid, item.uid,
2990                                    item.importance);
2991                        }
2992                    }
2993                } catch (RemoteException e) {
2994                }
2995            }
2996        }
2997        mProcessObservers.finishBroadcast();
2998    }
2999
3000    private void dispatchProcessDied(int pid, int uid) {
3001        int i = mProcessObservers.beginBroadcast();
3002        while (i > 0) {
3003            i--;
3004            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3005            if (observer != null) {
3006                try {
3007                    observer.onProcessDied(pid, uid);
3008                } catch (RemoteException e) {
3009                }
3010            }
3011        }
3012        mProcessObservers.finishBroadcast();
3013    }
3014
3015    @Override
3016    public final int startActivity(IApplicationThread caller, String callingPackage,
3017            Intent intent, String resolvedType, IBinder resultTo,
3018            String resultWho, int requestCode, int startFlags,
3019            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3020        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3021                resultWho, requestCode,
3022                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3023    }
3024
3025    @Override
3026    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3027            Intent intent, String resolvedType, IBinder resultTo,
3028            String resultWho, int requestCode, int startFlags,
3029            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3030        enforceNotIsolatedCaller("startActivity");
3031        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3032                false, true, "startActivity", null);
3033        // TODO: Switch to user app stacks here.
3034        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3035                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3036                null, null, options, userId, null);
3037    }
3038
3039    @Override
3040    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3041            Intent intent, String resolvedType, IBinder resultTo,
3042            String resultWho, int requestCode, int startFlags, String profileFile,
3043            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3044        enforceNotIsolatedCaller("startActivityAndWait");
3045        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3046                false, true, "startActivityAndWait", null);
3047        WaitResult res = new WaitResult();
3048        // TODO: Switch to user app stacks here.
3049        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3050                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3051                res, null, options, UserHandle.getCallingUserId(), null);
3052        return res;
3053    }
3054
3055    @Override
3056    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3057            Intent intent, String resolvedType, IBinder resultTo,
3058            String resultWho, int requestCode, int startFlags, Configuration config,
3059            Bundle options, int userId) {
3060        enforceNotIsolatedCaller("startActivityWithConfig");
3061        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3062                false, true, "startActivityWithConfig", null);
3063        // TODO: Switch to user app stacks here.
3064        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3065                resolvedType, resultTo, resultWho, requestCode, startFlags,
3066                null, null, null, config, options, userId, null);
3067        return ret;
3068    }
3069
3070    @Override
3071    public int startActivityIntentSender(IApplicationThread caller,
3072            IntentSender intent, Intent fillInIntent, String resolvedType,
3073            IBinder resultTo, String resultWho, int requestCode,
3074            int flagsMask, int flagsValues, Bundle options) {
3075        enforceNotIsolatedCaller("startActivityIntentSender");
3076        // Refuse possible leaked file descriptors
3077        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3078            throw new IllegalArgumentException("File descriptors passed in Intent");
3079        }
3080
3081        IIntentSender sender = intent.getTarget();
3082        if (!(sender instanceof PendingIntentRecord)) {
3083            throw new IllegalArgumentException("Bad PendingIntent object");
3084        }
3085
3086        PendingIntentRecord pir = (PendingIntentRecord)sender;
3087
3088        synchronized (this) {
3089            // If this is coming from the currently resumed activity, it is
3090            // effectively saying that app switches are allowed at this point.
3091            final ActivityStack stack = getFocusedStack();
3092            if (stack.mResumedActivity != null &&
3093                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3094                mAppSwitchesAllowedTime = 0;
3095            }
3096        }
3097        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3098                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3099        return ret;
3100    }
3101
3102    @Override
3103    public boolean startNextMatchingActivity(IBinder callingActivity,
3104            Intent intent, Bundle options) {
3105        // Refuse possible leaked file descriptors
3106        if (intent != null && intent.hasFileDescriptors() == true) {
3107            throw new IllegalArgumentException("File descriptors passed in Intent");
3108        }
3109
3110        synchronized (this) {
3111            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3112            if (r == null) {
3113                ActivityOptions.abort(options);
3114                return false;
3115            }
3116            if (r.app == null || r.app.thread == null) {
3117                // The caller is not running...  d'oh!
3118                ActivityOptions.abort(options);
3119                return false;
3120            }
3121            intent = new Intent(intent);
3122            // The caller is not allowed to change the data.
3123            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3124            // And we are resetting to find the next component...
3125            intent.setComponent(null);
3126
3127            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3128
3129            ActivityInfo aInfo = null;
3130            try {
3131                List<ResolveInfo> resolves =
3132                    AppGlobals.getPackageManager().queryIntentActivities(
3133                            intent, r.resolvedType,
3134                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3135                            UserHandle.getCallingUserId());
3136
3137                // Look for the original activity in the list...
3138                final int N = resolves != null ? resolves.size() : 0;
3139                for (int i=0; i<N; i++) {
3140                    ResolveInfo rInfo = resolves.get(i);
3141                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3142                            && rInfo.activityInfo.name.equals(r.info.name)) {
3143                        // We found the current one...  the next matching is
3144                        // after it.
3145                        i++;
3146                        if (i<N) {
3147                            aInfo = resolves.get(i).activityInfo;
3148                        }
3149                        if (debug) {
3150                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3151                                    + "/" + r.info.name);
3152                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3153                                    + "/" + aInfo.name);
3154                        }
3155                        break;
3156                    }
3157                }
3158            } catch (RemoteException e) {
3159            }
3160
3161            if (aInfo == null) {
3162                // Nobody who is next!
3163                ActivityOptions.abort(options);
3164                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3165                return false;
3166            }
3167
3168            intent.setComponent(new ComponentName(
3169                    aInfo.applicationInfo.packageName, aInfo.name));
3170            intent.setFlags(intent.getFlags()&~(
3171                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3172                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3173                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3174                    Intent.FLAG_ACTIVITY_NEW_TASK));
3175
3176            // Okay now we need to start the new activity, replacing the
3177            // currently running activity.  This is a little tricky because
3178            // we want to start the new one as if the current one is finished,
3179            // but not finish the current one first so that there is no flicker.
3180            // And thus...
3181            final boolean wasFinishing = r.finishing;
3182            r.finishing = true;
3183
3184            // Propagate reply information over to the new activity.
3185            final ActivityRecord resultTo = r.resultTo;
3186            final String resultWho = r.resultWho;
3187            final int requestCode = r.requestCode;
3188            r.resultTo = null;
3189            if (resultTo != null) {
3190                resultTo.removeResultsLocked(r, resultWho, requestCode);
3191            }
3192
3193            final long origId = Binder.clearCallingIdentity();
3194            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3195                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3196                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3197                    options, false, null, null);
3198            Binder.restoreCallingIdentity(origId);
3199
3200            r.finishing = wasFinishing;
3201            if (res != ActivityManager.START_SUCCESS) {
3202                return false;
3203            }
3204            return true;
3205        }
3206    }
3207
3208    final int startActivityInPackage(int uid, String callingPackage,
3209            Intent intent, String resolvedType, IBinder resultTo,
3210            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3211                    IActivityContainer container) {
3212
3213        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3214                false, true, "startActivityInPackage", null);
3215
3216        // TODO: Switch to user app stacks here.
3217        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3218                resultTo, resultWho, requestCode, startFlags,
3219                null, null, null, null, options, userId, container);
3220        return ret;
3221    }
3222
3223    @Override
3224    public final int startActivities(IApplicationThread caller, String callingPackage,
3225            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3226            int userId) {
3227        enforceNotIsolatedCaller("startActivities");
3228        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3229                false, true, "startActivity", null);
3230        // TODO: Switch to user app stacks here.
3231        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3232                resolvedTypes, resultTo, options, userId);
3233        return ret;
3234    }
3235
3236    final int startActivitiesInPackage(int uid, String callingPackage,
3237            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3238            Bundle options, int userId) {
3239
3240        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3241                false, true, "startActivityInPackage", null);
3242        // TODO: Switch to user app stacks here.
3243        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3244                resultTo, options, userId);
3245        return ret;
3246    }
3247
3248    final void addRecentTaskLocked(TaskRecord task) {
3249        int N = mRecentTasks.size();
3250        // Quick case: check if the top-most recent task is the same.
3251        if (N > 0 && mRecentTasks.get(0) == task) {
3252            return;
3253        }
3254        // Remove any existing entries that are the same kind of task.
3255        for (int i=0; i<N; i++) {
3256            TaskRecord tr = mRecentTasks.get(i);
3257            if (task.userId == tr.userId
3258                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3259                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3260                tr.disposeThumbnail();
3261                mRecentTasks.remove(i);
3262                i--;
3263                N--;
3264                if (task.intent == null) {
3265                    // If the new recent task we are adding is not fully
3266                    // specified, then replace it with the existing recent task.
3267                    task = tr;
3268                }
3269            }
3270        }
3271        if (N >= MAX_RECENT_TASKS) {
3272            mRecentTasks.remove(N-1).disposeThumbnail();
3273        }
3274        mRecentTasks.add(0, task);
3275    }
3276
3277    @Override
3278    public void reportActivityFullyDrawn(IBinder token) {
3279        synchronized (this) {
3280            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3281            if (r == null) {
3282                return;
3283            }
3284            r.reportFullyDrawnLocked();
3285        }
3286    }
3287
3288    @Override
3289    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3290        synchronized (this) {
3291            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3292            if (r == null) {
3293                return;
3294            }
3295            final long origId = Binder.clearCallingIdentity();
3296            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3297            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3298                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3299            if (config != null) {
3300                r.frozenBeforeDestroy = true;
3301                if (!updateConfigurationLocked(config, r, false, false)) {
3302                    mStackSupervisor.resumeTopActivitiesLocked();
3303                }
3304            }
3305            Binder.restoreCallingIdentity(origId);
3306        }
3307    }
3308
3309    @Override
3310    public int getRequestedOrientation(IBinder token) {
3311        synchronized (this) {
3312            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3313            if (r == null) {
3314                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3315            }
3316            return mWindowManager.getAppOrientation(r.appToken);
3317        }
3318    }
3319
3320    /**
3321     * This is the internal entry point for handling Activity.finish().
3322     *
3323     * @param token The Binder token referencing the Activity we want to finish.
3324     * @param resultCode Result code, if any, from this Activity.
3325     * @param resultData Result data (Intent), if any, from this Activity.
3326     *
3327     * @return Returns true if the activity successfully finished, or false if it is still running.
3328     */
3329    @Override
3330    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3331        // Refuse possible leaked file descriptors
3332        if (resultData != null && resultData.hasFileDescriptors() == true) {
3333            throw new IllegalArgumentException("File descriptors passed in Intent");
3334        }
3335
3336        synchronized(this) {
3337            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3338            if (r == null) {
3339                return true;
3340            }
3341            if (mController != null) {
3342                // Find the first activity that is not finishing.
3343                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3344                if (next != null) {
3345                    // ask watcher if this is allowed
3346                    boolean resumeOK = true;
3347                    try {
3348                        resumeOK = mController.activityResuming(next.packageName);
3349                    } catch (RemoteException e) {
3350                        mController = null;
3351                        Watchdog.getInstance().setActivityController(null);
3352                    }
3353
3354                    if (!resumeOK) {
3355                        return false;
3356                    }
3357                }
3358            }
3359            final long origId = Binder.clearCallingIdentity();
3360            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3361                    resultData, "app-request", true);
3362            Binder.restoreCallingIdentity(origId);
3363            return res;
3364        }
3365    }
3366
3367    @Override
3368    public final void finishHeavyWeightApp() {
3369        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3370                != PackageManager.PERMISSION_GRANTED) {
3371            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3372                    + Binder.getCallingPid()
3373                    + ", uid=" + Binder.getCallingUid()
3374                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3375            Slog.w(TAG, msg);
3376            throw new SecurityException(msg);
3377        }
3378
3379        synchronized(this) {
3380            if (mHeavyWeightProcess == null) {
3381                return;
3382            }
3383
3384            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3385                    mHeavyWeightProcess.activities);
3386            for (int i=0; i<activities.size(); i++) {
3387                ActivityRecord r = activities.get(i);
3388                if (!r.finishing) {
3389                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3390                            null, "finish-heavy", true);
3391                }
3392            }
3393
3394            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3395                    mHeavyWeightProcess.userId, 0));
3396            mHeavyWeightProcess = null;
3397        }
3398    }
3399
3400    @Override
3401    public void crashApplication(int uid, int initialPid, String packageName,
3402            String message) {
3403        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3404                != PackageManager.PERMISSION_GRANTED) {
3405            String msg = "Permission Denial: crashApplication() from pid="
3406                    + Binder.getCallingPid()
3407                    + ", uid=" + Binder.getCallingUid()
3408                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3409            Slog.w(TAG, msg);
3410            throw new SecurityException(msg);
3411        }
3412
3413        synchronized(this) {
3414            ProcessRecord proc = null;
3415
3416            // Figure out which process to kill.  We don't trust that initialPid
3417            // still has any relation to current pids, so must scan through the
3418            // list.
3419            synchronized (mPidsSelfLocked) {
3420                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3421                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3422                    if (p.uid != uid) {
3423                        continue;
3424                    }
3425                    if (p.pid == initialPid) {
3426                        proc = p;
3427                        break;
3428                    }
3429                    if (p.pkgList.containsKey(packageName)) {
3430                        proc = p;
3431                    }
3432                }
3433            }
3434
3435            if (proc == null) {
3436                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3437                        + " initialPid=" + initialPid
3438                        + " packageName=" + packageName);
3439                return;
3440            }
3441
3442            if (proc.thread != null) {
3443                if (proc.pid == Process.myPid()) {
3444                    Log.w(TAG, "crashApplication: trying to crash self!");
3445                    return;
3446                }
3447                long ident = Binder.clearCallingIdentity();
3448                try {
3449                    proc.thread.scheduleCrash(message);
3450                } catch (RemoteException e) {
3451                }
3452                Binder.restoreCallingIdentity(ident);
3453            }
3454        }
3455    }
3456
3457    @Override
3458    public final void finishSubActivity(IBinder token, String resultWho,
3459            int requestCode) {
3460        synchronized(this) {
3461            final long origId = Binder.clearCallingIdentity();
3462            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3463            if (r != null) {
3464                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3465            }
3466            Binder.restoreCallingIdentity(origId);
3467        }
3468    }
3469
3470    @Override
3471    public boolean finishActivityAffinity(IBinder token) {
3472        synchronized(this) {
3473            final long origId = Binder.clearCallingIdentity();
3474            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3475            boolean res = false;
3476            if (r != null) {
3477                res = r.task.stack.finishActivityAffinityLocked(r);
3478            }
3479            Binder.restoreCallingIdentity(origId);
3480            return res;
3481        }
3482    }
3483
3484    @Override
3485    public boolean willActivityBeVisible(IBinder token) {
3486        synchronized(this) {
3487            ActivityStack stack = ActivityRecord.getStackLocked(token);
3488            if (stack != null) {
3489                return stack.willActivityBeVisibleLocked(token);
3490            }
3491            return false;
3492        }
3493    }
3494
3495    @Override
3496    public void overridePendingTransition(IBinder token, String packageName,
3497            int enterAnim, int exitAnim) {
3498        synchronized(this) {
3499            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3500            if (self == null) {
3501                return;
3502            }
3503
3504            final long origId = Binder.clearCallingIdentity();
3505
3506            if (self.state == ActivityState.RESUMED
3507                    || self.state == ActivityState.PAUSING) {
3508                mWindowManager.overridePendingAppTransition(packageName,
3509                        enterAnim, exitAnim, null);
3510            }
3511
3512            Binder.restoreCallingIdentity(origId);
3513        }
3514    }
3515
3516    /**
3517     * Main function for removing an existing process from the activity manager
3518     * as a result of that process going away.  Clears out all connections
3519     * to the process.
3520     */
3521    private final void handleAppDiedLocked(ProcessRecord app,
3522            boolean restarting, boolean allowRestart) {
3523        int pid = app.pid;
3524        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3525        if (!restarting) {
3526            removeLruProcessLocked(app);
3527            if (pid > 0) {
3528                ProcessList.remove(pid);
3529            }
3530        }
3531
3532        if (mProfileProc == app) {
3533            clearProfilerLocked();
3534        }
3535
3536        // Remove this application's activities from active lists.
3537        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3538
3539        app.activities.clear();
3540
3541        if (app.instrumentationClass != null) {
3542            Slog.w(TAG, "Crash of app " + app.processName
3543                  + " running instrumentation " + app.instrumentationClass);
3544            Bundle info = new Bundle();
3545            info.putString("shortMsg", "Process crashed.");
3546            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3547        }
3548
3549        if (!restarting) {
3550            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3551                // If there was nothing to resume, and we are not already
3552                // restarting this process, but there is a visible activity that
3553                // is hosted by the process...  then make sure all visible
3554                // activities are running, taking care of restarting this
3555                // process.
3556                if (hasVisibleActivities) {
3557                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3558                }
3559            }
3560        }
3561    }
3562
3563    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3564        IBinder threadBinder = thread.asBinder();
3565        // Find the application record.
3566        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3567            ProcessRecord rec = mLruProcesses.get(i);
3568            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3569                return i;
3570            }
3571        }
3572        return -1;
3573    }
3574
3575    final ProcessRecord getRecordForAppLocked(
3576            IApplicationThread thread) {
3577        if (thread == null) {
3578            return null;
3579        }
3580
3581        int appIndex = getLRURecordIndexForAppLocked(thread);
3582        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3583    }
3584
3585    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3586        // If there are no longer any background processes running,
3587        // and the app that died was not running instrumentation,
3588        // then tell everyone we are now low on memory.
3589        boolean haveBg = false;
3590        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3591            ProcessRecord rec = mLruProcesses.get(i);
3592            if (rec.thread != null
3593                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3594                haveBg = true;
3595                break;
3596            }
3597        }
3598
3599        if (!haveBg) {
3600            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3601            if (doReport) {
3602                long now = SystemClock.uptimeMillis();
3603                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3604                    doReport = false;
3605                } else {
3606                    mLastMemUsageReportTime = now;
3607                }
3608            }
3609            final ArrayList<ProcessMemInfo> memInfos
3610                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3611            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3612            long now = SystemClock.uptimeMillis();
3613            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3614                ProcessRecord rec = mLruProcesses.get(i);
3615                if (rec == dyingProc || rec.thread == null) {
3616                    continue;
3617                }
3618                if (doReport) {
3619                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3620                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3621                }
3622                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3623                    // The low memory report is overriding any current
3624                    // state for a GC request.  Make sure to do
3625                    // heavy/important/visible/foreground processes first.
3626                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3627                        rec.lastRequestedGc = 0;
3628                    } else {
3629                        rec.lastRequestedGc = rec.lastLowMemory;
3630                    }
3631                    rec.reportLowMemory = true;
3632                    rec.lastLowMemory = now;
3633                    mProcessesToGc.remove(rec);
3634                    addProcessToGcListLocked(rec);
3635                }
3636            }
3637            if (doReport) {
3638                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3639                mHandler.sendMessage(msg);
3640            }
3641            scheduleAppGcsLocked();
3642        }
3643    }
3644
3645    final void appDiedLocked(ProcessRecord app, int pid,
3646            IApplicationThread thread) {
3647
3648        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3649        synchronized (stats) {
3650            stats.noteProcessDiedLocked(app.info.uid, pid);
3651        }
3652
3653        // Clean up already done if the process has been re-started.
3654        if (app.pid == pid && app.thread != null &&
3655                app.thread.asBinder() == thread.asBinder()) {
3656            boolean doLowMem = app.instrumentationClass == null;
3657            boolean doOomAdj = doLowMem;
3658            if (!app.killedByAm) {
3659                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3660                        + ") has died.");
3661                mAllowLowerMemLevel = true;
3662            } else {
3663                // Note that we always want to do oom adj to update our state with the
3664                // new number of procs.
3665                mAllowLowerMemLevel = false;
3666                doLowMem = false;
3667            }
3668            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3669            if (DEBUG_CLEANUP) Slog.v(
3670                TAG, "Dying app: " + app + ", pid: " + pid
3671                + ", thread: " + thread.asBinder());
3672            handleAppDiedLocked(app, false, true);
3673
3674            if (doOomAdj) {
3675                updateOomAdjLocked();
3676            }
3677            if (doLowMem) {
3678                doLowMemReportIfNeededLocked(app);
3679            }
3680        } else if (app.pid != pid) {
3681            // A new process has already been started.
3682            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3683                    + ") has died and restarted (pid " + app.pid + ").");
3684            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3685        } else if (DEBUG_PROCESSES) {
3686            Slog.d(TAG, "Received spurious death notification for thread "
3687                    + thread.asBinder());
3688        }
3689    }
3690
3691    /**
3692     * If a stack trace dump file is configured, dump process stack traces.
3693     * @param clearTraces causes the dump file to be erased prior to the new
3694     *    traces being written, if true; when false, the new traces will be
3695     *    appended to any existing file content.
3696     * @param firstPids of dalvik VM processes to dump stack traces for first
3697     * @param lastPids of dalvik VM processes to dump stack traces for last
3698     * @param nativeProcs optional list of native process names to dump stack crawls
3699     * @return file containing stack traces, or null if no dump file is configured
3700     */
3701    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3702            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3703        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3704        if (tracesPath == null || tracesPath.length() == 0) {
3705            return null;
3706        }
3707
3708        File tracesFile = new File(tracesPath);
3709        try {
3710            File tracesDir = tracesFile.getParentFile();
3711            if (!tracesDir.exists()) {
3712                tracesFile.mkdirs();
3713                if (!SELinux.restorecon(tracesDir)) {
3714                    return null;
3715                }
3716            }
3717            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3718
3719            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3720            tracesFile.createNewFile();
3721            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3722        } catch (IOException e) {
3723            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3724            return null;
3725        }
3726
3727        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3728        return tracesFile;
3729    }
3730
3731    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3732            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3733        // Use a FileObserver to detect when traces finish writing.
3734        // The order of traces is considered important to maintain for legibility.
3735        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3736            @Override
3737            public synchronized void onEvent(int event, String path) { notify(); }
3738        };
3739
3740        try {
3741            observer.startWatching();
3742
3743            // First collect all of the stacks of the most important pids.
3744            if (firstPids != null) {
3745                try {
3746                    int num = firstPids.size();
3747                    for (int i = 0; i < num; i++) {
3748                        synchronized (observer) {
3749                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3750                            observer.wait(200);  // Wait for write-close, give up after 200msec
3751                        }
3752                    }
3753                } catch (InterruptedException e) {
3754                    Log.wtf(TAG, e);
3755                }
3756            }
3757
3758            // Next collect the stacks of the native pids
3759            if (nativeProcs != null) {
3760                int[] pids = Process.getPidsForCommands(nativeProcs);
3761                if (pids != null) {
3762                    for (int pid : pids) {
3763                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3764                    }
3765                }
3766            }
3767
3768            // Lastly, measure CPU usage.
3769            if (processCpuTracker != null) {
3770                processCpuTracker.init();
3771                System.gc();
3772                processCpuTracker.update();
3773                try {
3774                    synchronized (processCpuTracker) {
3775                        processCpuTracker.wait(500); // measure over 1/2 second.
3776                    }
3777                } catch (InterruptedException e) {
3778                }
3779                processCpuTracker.update();
3780
3781                // We'll take the stack crawls of just the top apps using CPU.
3782                final int N = processCpuTracker.countWorkingStats();
3783                int numProcs = 0;
3784                for (int i=0; i<N && numProcs<5; i++) {
3785                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3786                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3787                        numProcs++;
3788                        try {
3789                            synchronized (observer) {
3790                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3791                                observer.wait(200);  // Wait for write-close, give up after 200msec
3792                            }
3793                        } catch (InterruptedException e) {
3794                            Log.wtf(TAG, e);
3795                        }
3796
3797                    }
3798                }
3799            }
3800        } finally {
3801            observer.stopWatching();
3802        }
3803    }
3804
3805    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3806        if (true || IS_USER_BUILD) {
3807            return;
3808        }
3809        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3810        if (tracesPath == null || tracesPath.length() == 0) {
3811            return;
3812        }
3813
3814        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3815        StrictMode.allowThreadDiskWrites();
3816        try {
3817            final File tracesFile = new File(tracesPath);
3818            final File tracesDir = tracesFile.getParentFile();
3819            final File tracesTmp = new File(tracesDir, "__tmp__");
3820            try {
3821                if (!tracesDir.exists()) {
3822                    tracesFile.mkdirs();
3823                    if (!SELinux.restorecon(tracesDir.getPath())) {
3824                        return;
3825                    }
3826                }
3827                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3828
3829                if (tracesFile.exists()) {
3830                    tracesTmp.delete();
3831                    tracesFile.renameTo(tracesTmp);
3832                }
3833                StringBuilder sb = new StringBuilder();
3834                Time tobj = new Time();
3835                tobj.set(System.currentTimeMillis());
3836                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3837                sb.append(": ");
3838                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3839                sb.append(" since ");
3840                sb.append(msg);
3841                FileOutputStream fos = new FileOutputStream(tracesFile);
3842                fos.write(sb.toString().getBytes());
3843                if (app == null) {
3844                    fos.write("\n*** No application process!".getBytes());
3845                }
3846                fos.close();
3847                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3848            } catch (IOException e) {
3849                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3850                return;
3851            }
3852
3853            if (app != null) {
3854                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3855                firstPids.add(app.pid);
3856                dumpStackTraces(tracesPath, firstPids, null, null, null);
3857            }
3858
3859            File lastTracesFile = null;
3860            File curTracesFile = null;
3861            for (int i=9; i>=0; i--) {
3862                String name = String.format(Locale.US, "slow%02d.txt", i);
3863                curTracesFile = new File(tracesDir, name);
3864                if (curTracesFile.exists()) {
3865                    if (lastTracesFile != null) {
3866                        curTracesFile.renameTo(lastTracesFile);
3867                    } else {
3868                        curTracesFile.delete();
3869                    }
3870                }
3871                lastTracesFile = curTracesFile;
3872            }
3873            tracesFile.renameTo(curTracesFile);
3874            if (tracesTmp.exists()) {
3875                tracesTmp.renameTo(tracesFile);
3876            }
3877        } finally {
3878            StrictMode.setThreadPolicy(oldPolicy);
3879        }
3880    }
3881
3882    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3883            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3884        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3885        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3886
3887        if (mController != null) {
3888            try {
3889                // 0 == continue, -1 = kill process immediately
3890                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3891                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3892            } catch (RemoteException e) {
3893                mController = null;
3894                Watchdog.getInstance().setActivityController(null);
3895            }
3896        }
3897
3898        long anrTime = SystemClock.uptimeMillis();
3899        if (MONITOR_CPU_USAGE) {
3900            updateCpuStatsNow();
3901        }
3902
3903        synchronized (this) {
3904            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3905            if (mShuttingDown) {
3906                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3907                return;
3908            } else if (app.notResponding) {
3909                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3910                return;
3911            } else if (app.crashing) {
3912                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3913                return;
3914            }
3915
3916            // In case we come through here for the same app before completing
3917            // this one, mark as anring now so we will bail out.
3918            app.notResponding = true;
3919
3920            // Log the ANR to the event log.
3921            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3922                    app.processName, app.info.flags, annotation);
3923
3924            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3925            firstPids.add(app.pid);
3926
3927            int parentPid = app.pid;
3928            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3929            if (parentPid != app.pid) firstPids.add(parentPid);
3930
3931            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3932
3933            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3934                ProcessRecord r = mLruProcesses.get(i);
3935                if (r != null && r.thread != null) {
3936                    int pid = r.pid;
3937                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3938                        if (r.persistent) {
3939                            firstPids.add(pid);
3940                        } else {
3941                            lastPids.put(pid, Boolean.TRUE);
3942                        }
3943                    }
3944                }
3945            }
3946        }
3947
3948        // Log the ANR to the main log.
3949        StringBuilder info = new StringBuilder();
3950        info.setLength(0);
3951        info.append("ANR in ").append(app.processName);
3952        if (activity != null && activity.shortComponentName != null) {
3953            info.append(" (").append(activity.shortComponentName).append(")");
3954        }
3955        info.append("\n");
3956        info.append("PID: ").append(app.pid).append("\n");
3957        if (annotation != null) {
3958            info.append("Reason: ").append(annotation).append("\n");
3959        }
3960        if (parent != null && parent != activity) {
3961            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3962        }
3963
3964        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
3965
3966        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
3967                NATIVE_STACKS_OF_INTEREST);
3968
3969        String cpuInfo = null;
3970        if (MONITOR_CPU_USAGE) {
3971            updateCpuStatsNow();
3972            synchronized (mProcessCpuThread) {
3973                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
3974            }
3975            info.append(processCpuTracker.printCurrentLoad());
3976            info.append(cpuInfo);
3977        }
3978
3979        info.append(processCpuTracker.printCurrentState(anrTime));
3980
3981        Slog.e(TAG, info.toString());
3982        if (tracesFile == null) {
3983            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3984            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3985        }
3986
3987        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3988                cpuInfo, tracesFile, null);
3989
3990        if (mController != null) {
3991            try {
3992                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3993                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3994                if (res != 0) {
3995                    if (res < 0 && app.pid != MY_PID) {
3996                        Process.killProcess(app.pid);
3997                    } else {
3998                        synchronized (this) {
3999                            mServices.scheduleServiceTimeoutLocked(app);
4000                        }
4001                    }
4002                    return;
4003                }
4004            } catch (RemoteException e) {
4005                mController = null;
4006                Watchdog.getInstance().setActivityController(null);
4007            }
4008        }
4009
4010        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4011        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4012                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4013
4014        synchronized (this) {
4015            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4016                killUnneededProcessLocked(app, "background ANR");
4017                return;
4018            }
4019
4020            // Set the app's notResponding state, and look up the errorReportReceiver
4021            makeAppNotRespondingLocked(app,
4022                    activity != null ? activity.shortComponentName : null,
4023                    annotation != null ? "ANR " + annotation : "ANR",
4024                    info.toString());
4025
4026            // Bring up the infamous App Not Responding dialog
4027            Message msg = Message.obtain();
4028            HashMap<String, Object> map = new HashMap<String, Object>();
4029            msg.what = SHOW_NOT_RESPONDING_MSG;
4030            msg.obj = map;
4031            msg.arg1 = aboveSystem ? 1 : 0;
4032            map.put("app", app);
4033            if (activity != null) {
4034                map.put("activity", activity);
4035            }
4036
4037            mHandler.sendMessage(msg);
4038        }
4039    }
4040
4041    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4042        if (!mLaunchWarningShown) {
4043            mLaunchWarningShown = true;
4044            mHandler.post(new Runnable() {
4045                @Override
4046                public void run() {
4047                    synchronized (ActivityManagerService.this) {
4048                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4049                        d.show();
4050                        mHandler.postDelayed(new Runnable() {
4051                            @Override
4052                            public void run() {
4053                                synchronized (ActivityManagerService.this) {
4054                                    d.dismiss();
4055                                    mLaunchWarningShown = false;
4056                                }
4057                            }
4058                        }, 4000);
4059                    }
4060                }
4061            });
4062        }
4063    }
4064
4065    @Override
4066    public boolean clearApplicationUserData(final String packageName,
4067            final IPackageDataObserver observer, int userId) {
4068        enforceNotIsolatedCaller("clearApplicationUserData");
4069        int uid = Binder.getCallingUid();
4070        int pid = Binder.getCallingPid();
4071        userId = handleIncomingUser(pid, uid,
4072                userId, false, true, "clearApplicationUserData", null);
4073        long callingId = Binder.clearCallingIdentity();
4074        try {
4075            IPackageManager pm = AppGlobals.getPackageManager();
4076            int pkgUid = -1;
4077            synchronized(this) {
4078                try {
4079                    pkgUid = pm.getPackageUid(packageName, userId);
4080                } catch (RemoteException e) {
4081                }
4082                if (pkgUid == -1) {
4083                    Slog.w(TAG, "Invalid packageName: " + packageName);
4084                    if (observer != null) {
4085                        try {
4086                            observer.onRemoveCompleted(packageName, false);
4087                        } catch (RemoteException e) {
4088                            Slog.i(TAG, "Observer no longer exists.");
4089                        }
4090                    }
4091                    return false;
4092                }
4093                if (uid == pkgUid || checkComponentPermission(
4094                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4095                        pid, uid, -1, true)
4096                        == PackageManager.PERMISSION_GRANTED) {
4097                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4098                } else {
4099                    throw new SecurityException("PID " + pid + " does not have permission "
4100                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4101                                    + " of package " + packageName);
4102                }
4103            }
4104
4105            try {
4106                // Clear application user data
4107                pm.clearApplicationUserData(packageName, observer, userId);
4108
4109                // Remove all permissions granted from/to this package
4110                removeUriPermissionsForPackageLocked(packageName, userId, true);
4111
4112                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4113                        Uri.fromParts("package", packageName, null));
4114                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4115                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4116                        null, null, 0, null, null, null, false, false, userId);
4117            } catch (RemoteException e) {
4118            }
4119        } finally {
4120            Binder.restoreCallingIdentity(callingId);
4121        }
4122        return true;
4123    }
4124
4125    @Override
4126    public void killBackgroundProcesses(final String packageName, int userId) {
4127        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4128                != PackageManager.PERMISSION_GRANTED &&
4129                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4130                        != PackageManager.PERMISSION_GRANTED) {
4131            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4132                    + Binder.getCallingPid()
4133                    + ", uid=" + Binder.getCallingUid()
4134                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4135            Slog.w(TAG, msg);
4136            throw new SecurityException(msg);
4137        }
4138
4139        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4140                userId, true, true, "killBackgroundProcesses", null);
4141        long callingId = Binder.clearCallingIdentity();
4142        try {
4143            IPackageManager pm = AppGlobals.getPackageManager();
4144            synchronized(this) {
4145                int appId = -1;
4146                try {
4147                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4148                } catch (RemoteException e) {
4149                }
4150                if (appId == -1) {
4151                    Slog.w(TAG, "Invalid packageName: " + packageName);
4152                    return;
4153                }
4154                killPackageProcessesLocked(packageName, appId, userId,
4155                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4156            }
4157        } finally {
4158            Binder.restoreCallingIdentity(callingId);
4159        }
4160    }
4161
4162    @Override
4163    public void killAllBackgroundProcesses() {
4164        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4165                != PackageManager.PERMISSION_GRANTED) {
4166            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4167                    + Binder.getCallingPid()
4168                    + ", uid=" + Binder.getCallingUid()
4169                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4170            Slog.w(TAG, msg);
4171            throw new SecurityException(msg);
4172        }
4173
4174        long callingId = Binder.clearCallingIdentity();
4175        try {
4176            synchronized(this) {
4177                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4178                final int NP = mProcessNames.getMap().size();
4179                for (int ip=0; ip<NP; ip++) {
4180                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4181                    final int NA = apps.size();
4182                    for (int ia=0; ia<NA; ia++) {
4183                        ProcessRecord app = apps.valueAt(ia);
4184                        if (app.persistent) {
4185                            // we don't kill persistent processes
4186                            continue;
4187                        }
4188                        if (app.removed) {
4189                            procs.add(app);
4190                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4191                            app.removed = true;
4192                            procs.add(app);
4193                        }
4194                    }
4195                }
4196
4197                int N = procs.size();
4198                for (int i=0; i<N; i++) {
4199                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4200                }
4201                mAllowLowerMemLevel = true;
4202                updateOomAdjLocked();
4203                doLowMemReportIfNeededLocked(null);
4204            }
4205        } finally {
4206            Binder.restoreCallingIdentity(callingId);
4207        }
4208    }
4209
4210    @Override
4211    public void forceStopPackage(final String packageName, int userId) {
4212        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4213                != PackageManager.PERMISSION_GRANTED) {
4214            String msg = "Permission Denial: forceStopPackage() from pid="
4215                    + Binder.getCallingPid()
4216                    + ", uid=" + Binder.getCallingUid()
4217                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4218            Slog.w(TAG, msg);
4219            throw new SecurityException(msg);
4220        }
4221        final int callingPid = Binder.getCallingPid();
4222        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4223                userId, true, true, "forceStopPackage", null);
4224        long callingId = Binder.clearCallingIdentity();
4225        try {
4226            IPackageManager pm = AppGlobals.getPackageManager();
4227            synchronized(this) {
4228                int[] users = userId == UserHandle.USER_ALL
4229                        ? getUsersLocked() : new int[] { userId };
4230                for (int user : users) {
4231                    int pkgUid = -1;
4232                    try {
4233                        pkgUid = pm.getPackageUid(packageName, user);
4234                    } catch (RemoteException e) {
4235                    }
4236                    if (pkgUid == -1) {
4237                        Slog.w(TAG, "Invalid packageName: " + packageName);
4238                        continue;
4239                    }
4240                    try {
4241                        pm.setPackageStoppedState(packageName, true, user);
4242                    } catch (RemoteException e) {
4243                    } catch (IllegalArgumentException e) {
4244                        Slog.w(TAG, "Failed trying to unstop package "
4245                                + packageName + ": " + e);
4246                    }
4247                    if (isUserRunningLocked(user, false)) {
4248                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4249                    }
4250                }
4251            }
4252        } finally {
4253            Binder.restoreCallingIdentity(callingId);
4254        }
4255    }
4256
4257    /*
4258     * The pkg name and app id have to be specified.
4259     */
4260    @Override
4261    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4262        if (pkg == null) {
4263            return;
4264        }
4265        // Make sure the uid is valid.
4266        if (appid < 0) {
4267            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4268            return;
4269        }
4270        int callerUid = Binder.getCallingUid();
4271        // Only the system server can kill an application
4272        if (callerUid == Process.SYSTEM_UID) {
4273            // Post an aysnc message to kill the application
4274            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4275            msg.arg1 = appid;
4276            msg.arg2 = 0;
4277            Bundle bundle = new Bundle();
4278            bundle.putString("pkg", pkg);
4279            bundle.putString("reason", reason);
4280            msg.obj = bundle;
4281            mHandler.sendMessage(msg);
4282        } else {
4283            throw new SecurityException(callerUid + " cannot kill pkg: " +
4284                    pkg);
4285        }
4286    }
4287
4288    @Override
4289    public void closeSystemDialogs(String reason) {
4290        enforceNotIsolatedCaller("closeSystemDialogs");
4291
4292        final int pid = Binder.getCallingPid();
4293        final int uid = Binder.getCallingUid();
4294        final long origId = Binder.clearCallingIdentity();
4295        try {
4296            synchronized (this) {
4297                // Only allow this from foreground processes, so that background
4298                // applications can't abuse it to prevent system UI from being shown.
4299                if (uid >= Process.FIRST_APPLICATION_UID) {
4300                    ProcessRecord proc;
4301                    synchronized (mPidsSelfLocked) {
4302                        proc = mPidsSelfLocked.get(pid);
4303                    }
4304                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4305                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4306                                + " from background process " + proc);
4307                        return;
4308                    }
4309                }
4310                closeSystemDialogsLocked(reason);
4311            }
4312        } finally {
4313            Binder.restoreCallingIdentity(origId);
4314        }
4315    }
4316
4317    void closeSystemDialogsLocked(String reason) {
4318        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4319        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4320                | Intent.FLAG_RECEIVER_FOREGROUND);
4321        if (reason != null) {
4322            intent.putExtra("reason", reason);
4323        }
4324        mWindowManager.closeSystemDialogs(reason);
4325
4326        mStackSupervisor.closeSystemDialogsLocked();
4327
4328        broadcastIntentLocked(null, null, intent, null,
4329                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4330                Process.SYSTEM_UID, UserHandle.USER_ALL);
4331    }
4332
4333    @Override
4334    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4335        enforceNotIsolatedCaller("getProcessMemoryInfo");
4336        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4337        for (int i=pids.length-1; i>=0; i--) {
4338            ProcessRecord proc;
4339            int oomAdj;
4340            synchronized (this) {
4341                synchronized (mPidsSelfLocked) {
4342                    proc = mPidsSelfLocked.get(pids[i]);
4343                    oomAdj = proc != null ? proc.setAdj : 0;
4344                }
4345            }
4346            infos[i] = new Debug.MemoryInfo();
4347            Debug.getMemoryInfo(pids[i], infos[i]);
4348            if (proc != null) {
4349                synchronized (this) {
4350                    if (proc.thread != null && proc.setAdj == oomAdj) {
4351                        // Record this for posterity if the process has been stable.
4352                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4353                                infos[i].getTotalUss(), false, proc.pkgList);
4354                    }
4355                }
4356            }
4357        }
4358        return infos;
4359    }
4360
4361    @Override
4362    public long[] getProcessPss(int[] pids) {
4363        enforceNotIsolatedCaller("getProcessPss");
4364        long[] pss = new long[pids.length];
4365        for (int i=pids.length-1; i>=0; i--) {
4366            ProcessRecord proc;
4367            int oomAdj;
4368            synchronized (this) {
4369                synchronized (mPidsSelfLocked) {
4370                    proc = mPidsSelfLocked.get(pids[i]);
4371                    oomAdj = proc != null ? proc.setAdj : 0;
4372                }
4373            }
4374            long[] tmpUss = new long[1];
4375            pss[i] = Debug.getPss(pids[i], tmpUss);
4376            if (proc != null) {
4377                synchronized (this) {
4378                    if (proc.thread != null && proc.setAdj == oomAdj) {
4379                        // Record this for posterity if the process has been stable.
4380                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4381                    }
4382                }
4383            }
4384        }
4385        return pss;
4386    }
4387
4388    @Override
4389    public void killApplicationProcess(String processName, int uid) {
4390        if (processName == null) {
4391            return;
4392        }
4393
4394        int callerUid = Binder.getCallingUid();
4395        // Only the system server can kill an application
4396        if (callerUid == Process.SYSTEM_UID) {
4397            synchronized (this) {
4398                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4399                if (app != null && app.thread != null) {
4400                    try {
4401                        app.thread.scheduleSuicide();
4402                    } catch (RemoteException e) {
4403                        // If the other end already died, then our work here is done.
4404                    }
4405                } else {
4406                    Slog.w(TAG, "Process/uid not found attempting kill of "
4407                            + processName + " / " + uid);
4408                }
4409            }
4410        } else {
4411            throw new SecurityException(callerUid + " cannot kill app process: " +
4412                    processName);
4413        }
4414    }
4415
4416    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4417        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4418                false, true, false, UserHandle.getUserId(uid), reason);
4419        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4420                Uri.fromParts("package", packageName, null));
4421        if (!mProcessesReady) {
4422            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4423                    | Intent.FLAG_RECEIVER_FOREGROUND);
4424        }
4425        intent.putExtra(Intent.EXTRA_UID, uid);
4426        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4427        broadcastIntentLocked(null, null, intent,
4428                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4429                false, false,
4430                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4431    }
4432
4433    private void forceStopUserLocked(int userId, String reason) {
4434        forceStopPackageLocked(null, -1, false, false, true, false, userId, reason);
4435        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4436        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4437                | Intent.FLAG_RECEIVER_FOREGROUND);
4438        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4439        broadcastIntentLocked(null, null, intent,
4440                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4441                false, false,
4442                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4443    }
4444
4445    private final boolean killPackageProcessesLocked(String packageName, int appId,
4446            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4447            boolean doit, boolean evenPersistent, String reason) {
4448        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4449
4450        // Remove all processes this package may have touched: all with the
4451        // same UID (except for the system or root user), and all whose name
4452        // matches the package name.
4453        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4454        final int NP = mProcessNames.getMap().size();
4455        for (int ip=0; ip<NP; ip++) {
4456            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4457            final int NA = apps.size();
4458            for (int ia=0; ia<NA; ia++) {
4459                ProcessRecord app = apps.valueAt(ia);
4460                if (app.persistent && !evenPersistent) {
4461                    // we don't kill persistent processes
4462                    continue;
4463                }
4464                if (app.removed) {
4465                    if (doit) {
4466                        procs.add(app);
4467                    }
4468                    continue;
4469                }
4470
4471                // Skip process if it doesn't meet our oom adj requirement.
4472                if (app.setAdj < minOomAdj) {
4473                    continue;
4474                }
4475
4476                // If no package is specified, we call all processes under the
4477                // give user id.
4478                if (packageName == null) {
4479                    if (app.userId != userId) {
4480                        continue;
4481                    }
4482                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4483                        continue;
4484                    }
4485                // Package has been specified, we want to hit all processes
4486                // that match it.  We need to qualify this by the processes
4487                // that are running under the specified app and user ID.
4488                } else {
4489                    if (UserHandle.getAppId(app.uid) != appId) {
4490                        continue;
4491                    }
4492                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4493                        continue;
4494                    }
4495                    if (!app.pkgList.containsKey(packageName)) {
4496                        continue;
4497                    }
4498                }
4499
4500                // Process has passed all conditions, kill it!
4501                if (!doit) {
4502                    return true;
4503                }
4504                app.removed = true;
4505                procs.add(app);
4506            }
4507        }
4508
4509        int N = procs.size();
4510        for (int i=0; i<N; i++) {
4511            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4512        }
4513        updateOomAdjLocked();
4514        return N > 0;
4515    }
4516
4517    private final boolean forceStopPackageLocked(String name, int appId,
4518            boolean callerWillRestart, boolean purgeCache, boolean doit,
4519            boolean evenPersistent, int userId, String reason) {
4520        int i;
4521        int N;
4522
4523        if (userId == UserHandle.USER_ALL && name == null) {
4524            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4525        }
4526
4527        if (appId < 0 && name != null) {
4528            try {
4529                appId = UserHandle.getAppId(
4530                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4531            } catch (RemoteException e) {
4532            }
4533        }
4534
4535        if (doit) {
4536            if (name != null) {
4537                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4538                        + " user=" + userId + ": " + reason);
4539            } else {
4540                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4541            }
4542
4543            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4544            for (int ip=pmap.size()-1; ip>=0; ip--) {
4545                SparseArray<Long> ba = pmap.valueAt(ip);
4546                for (i=ba.size()-1; i>=0; i--) {
4547                    boolean remove = false;
4548                    final int entUid = ba.keyAt(i);
4549                    if (name != null) {
4550                        if (userId == UserHandle.USER_ALL) {
4551                            if (UserHandle.getAppId(entUid) == appId) {
4552                                remove = true;
4553                            }
4554                        } else {
4555                            if (entUid == UserHandle.getUid(userId, appId)) {
4556                                remove = true;
4557                            }
4558                        }
4559                    } else if (UserHandle.getUserId(entUid) == userId) {
4560                        remove = true;
4561                    }
4562                    if (remove) {
4563                        ba.removeAt(i);
4564                    }
4565                }
4566                if (ba.size() == 0) {
4567                    pmap.removeAt(ip);
4568                }
4569            }
4570        }
4571
4572        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4573                -100, callerWillRestart, true, doit, evenPersistent,
4574                name == null ? ("stop user " + userId) : ("stop " + name));
4575
4576        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4577            if (!doit) {
4578                return true;
4579            }
4580            didSomething = true;
4581        }
4582
4583        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4584            if (!doit) {
4585                return true;
4586            }
4587            didSomething = true;
4588        }
4589
4590        if (name == null) {
4591            // Remove all sticky broadcasts from this user.
4592            mStickyBroadcasts.remove(userId);
4593        }
4594
4595        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4596        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4597                userId, providers)) {
4598            if (!doit) {
4599                return true;
4600            }
4601            didSomething = true;
4602        }
4603        N = providers.size();
4604        for (i=0; i<N; i++) {
4605            removeDyingProviderLocked(null, providers.get(i), true);
4606        }
4607
4608        // Remove transient permissions granted from/to this package/user
4609        removeUriPermissionsForPackageLocked(name, userId, false);
4610
4611        if (name == null) {
4612            // Remove pending intents.  For now we only do this when force
4613            // stopping users, because we have some problems when doing this
4614            // for packages -- app widgets are not currently cleaned up for
4615            // such packages, so they can be left with bad pending intents.
4616            if (mIntentSenderRecords.size() > 0) {
4617                Iterator<WeakReference<PendingIntentRecord>> it
4618                        = mIntentSenderRecords.values().iterator();
4619                while (it.hasNext()) {
4620                    WeakReference<PendingIntentRecord> wpir = it.next();
4621                    if (wpir == null) {
4622                        it.remove();
4623                        continue;
4624                    }
4625                    PendingIntentRecord pir = wpir.get();
4626                    if (pir == null) {
4627                        it.remove();
4628                        continue;
4629                    }
4630                    if (name == null) {
4631                        // Stopping user, remove all objects for the user.
4632                        if (pir.key.userId != userId) {
4633                            // Not the same user, skip it.
4634                            continue;
4635                        }
4636                    } else {
4637                        if (UserHandle.getAppId(pir.uid) != appId) {
4638                            // Different app id, skip it.
4639                            continue;
4640                        }
4641                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4642                            // Different user, skip it.
4643                            continue;
4644                        }
4645                        if (!pir.key.packageName.equals(name)) {
4646                            // Different package, skip it.
4647                            continue;
4648                        }
4649                    }
4650                    if (!doit) {
4651                        return true;
4652                    }
4653                    didSomething = true;
4654                    it.remove();
4655                    pir.canceled = true;
4656                    if (pir.key.activity != null) {
4657                        pir.key.activity.pendingResults.remove(pir.ref);
4658                    }
4659                }
4660            }
4661        }
4662
4663        if (doit) {
4664            if (purgeCache && name != null) {
4665                AttributeCache ac = AttributeCache.instance();
4666                if (ac != null) {
4667                    ac.removePackage(name);
4668                }
4669            }
4670            if (mBooted) {
4671                mStackSupervisor.resumeTopActivitiesLocked();
4672                mStackSupervisor.scheduleIdleLocked();
4673            }
4674        }
4675
4676        return didSomething;
4677    }
4678
4679    private final boolean removeProcessLocked(ProcessRecord app,
4680            boolean callerWillRestart, boolean allowRestart, String reason) {
4681        final String name = app.processName;
4682        final int uid = app.uid;
4683        if (DEBUG_PROCESSES) Slog.d(
4684            TAG, "Force removing proc " + app.toShortString() + " (" + name
4685            + "/" + uid + ")");
4686
4687        mProcessNames.remove(name, uid);
4688        mIsolatedProcesses.remove(app.uid);
4689        if (mHeavyWeightProcess == app) {
4690            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4691                    mHeavyWeightProcess.userId, 0));
4692            mHeavyWeightProcess = null;
4693        }
4694        boolean needRestart = false;
4695        if (app.pid > 0 && app.pid != MY_PID) {
4696            int pid = app.pid;
4697            synchronized (mPidsSelfLocked) {
4698                mPidsSelfLocked.remove(pid);
4699                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4700            }
4701            killUnneededProcessLocked(app, reason);
4702            handleAppDiedLocked(app, true, allowRestart);
4703            removeLruProcessLocked(app);
4704
4705            if (app.persistent && !app.isolated) {
4706                if (!callerWillRestart) {
4707                    addAppLocked(app.info, false);
4708                } else {
4709                    needRestart = true;
4710                }
4711            }
4712        } else {
4713            mRemovedProcesses.add(app);
4714        }
4715
4716        return needRestart;
4717    }
4718
4719    private final void processStartTimedOutLocked(ProcessRecord app) {
4720        final int pid = app.pid;
4721        boolean gone = false;
4722        synchronized (mPidsSelfLocked) {
4723            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4724            if (knownApp != null && knownApp.thread == null) {
4725                mPidsSelfLocked.remove(pid);
4726                gone = true;
4727            }
4728        }
4729
4730        if (gone) {
4731            Slog.w(TAG, "Process " + app + " failed to attach");
4732            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4733                    pid, app.uid, app.processName);
4734            mProcessNames.remove(app.processName, app.uid);
4735            mIsolatedProcesses.remove(app.uid);
4736            if (mHeavyWeightProcess == app) {
4737                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4738                        mHeavyWeightProcess.userId, 0));
4739                mHeavyWeightProcess = null;
4740            }
4741            // Take care of any launching providers waiting for this process.
4742            checkAppInLaunchingProvidersLocked(app, true);
4743            // Take care of any services that are waiting for the process.
4744            mServices.processStartTimedOutLocked(app);
4745            killUnneededProcessLocked(app, "start timeout");
4746            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4747                Slog.w(TAG, "Unattached app died before backup, skipping");
4748                try {
4749                    IBackupManager bm = IBackupManager.Stub.asInterface(
4750                            ServiceManager.getService(Context.BACKUP_SERVICE));
4751                    bm.agentDisconnected(app.info.packageName);
4752                } catch (RemoteException e) {
4753                    // Can't happen; the backup manager is local
4754                }
4755            }
4756            if (isPendingBroadcastProcessLocked(pid)) {
4757                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4758                skipPendingBroadcastLocked(pid);
4759            }
4760        } else {
4761            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4762        }
4763    }
4764
4765    private final boolean attachApplicationLocked(IApplicationThread thread,
4766            int pid) {
4767
4768        // Find the application record that is being attached...  either via
4769        // the pid if we are running in multiple processes, or just pull the
4770        // next app record if we are emulating process with anonymous threads.
4771        ProcessRecord app;
4772        if (pid != MY_PID && pid >= 0) {
4773            synchronized (mPidsSelfLocked) {
4774                app = mPidsSelfLocked.get(pid);
4775            }
4776        } else {
4777            app = null;
4778        }
4779
4780        if (app == null) {
4781            Slog.w(TAG, "No pending application record for pid " + pid
4782                    + " (IApplicationThread " + thread + "); dropping process");
4783            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4784            if (pid > 0 && pid != MY_PID) {
4785                Process.killProcessQuiet(pid);
4786            } else {
4787                try {
4788                    thread.scheduleExit();
4789                } catch (Exception e) {
4790                    // Ignore exceptions.
4791                }
4792            }
4793            return false;
4794        }
4795
4796        // If this application record is still attached to a previous
4797        // process, clean it up now.
4798        if (app.thread != null) {
4799            handleAppDiedLocked(app, true, true);
4800        }
4801
4802        // Tell the process all about itself.
4803
4804        if (localLOGV) Slog.v(
4805                TAG, "Binding process pid " + pid + " to record " + app);
4806
4807        final String processName = app.processName;
4808        try {
4809            AppDeathRecipient adr = new AppDeathRecipient(
4810                    app, pid, thread);
4811            thread.asBinder().linkToDeath(adr, 0);
4812            app.deathRecipient = adr;
4813        } catch (RemoteException e) {
4814            app.resetPackageList(mProcessStats);
4815            startProcessLocked(app, "link fail", processName);
4816            return false;
4817        }
4818
4819        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4820
4821        app.makeActive(thread, mProcessStats);
4822        app.curAdj = app.setAdj = -100;
4823        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4824        app.forcingToForeground = null;
4825        app.foregroundServices = false;
4826        app.hasShownUi = false;
4827        app.debugging = false;
4828        app.cached = false;
4829
4830        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4831
4832        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4833        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4834
4835        if (!normalMode) {
4836            Slog.i(TAG, "Launching preboot mode app: " + app);
4837        }
4838
4839        if (localLOGV) Slog.v(
4840            TAG, "New app record " + app
4841            + " thread=" + thread.asBinder() + " pid=" + pid);
4842        try {
4843            int testMode = IApplicationThread.DEBUG_OFF;
4844            if (mDebugApp != null && mDebugApp.equals(processName)) {
4845                testMode = mWaitForDebugger
4846                    ? IApplicationThread.DEBUG_WAIT
4847                    : IApplicationThread.DEBUG_ON;
4848                app.debugging = true;
4849                if (mDebugTransient) {
4850                    mDebugApp = mOrigDebugApp;
4851                    mWaitForDebugger = mOrigWaitForDebugger;
4852                }
4853            }
4854            String profileFile = app.instrumentationProfileFile;
4855            ParcelFileDescriptor profileFd = null;
4856            boolean profileAutoStop = false;
4857            if (mProfileApp != null && mProfileApp.equals(processName)) {
4858                mProfileProc = app;
4859                profileFile = mProfileFile;
4860                profileFd = mProfileFd;
4861                profileAutoStop = mAutoStopProfiler;
4862            }
4863            boolean enableOpenGlTrace = false;
4864            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4865                enableOpenGlTrace = true;
4866                mOpenGlTraceApp = null;
4867            }
4868
4869            // If the app is being launched for restore or full backup, set it up specially
4870            boolean isRestrictedBackupMode = false;
4871            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4872                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4873                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4874                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4875            }
4876
4877            ensurePackageDexOpt(app.instrumentationInfo != null
4878                    ? app.instrumentationInfo.packageName
4879                    : app.info.packageName);
4880            if (app.instrumentationClass != null) {
4881                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4882            }
4883            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4884                    + processName + " with config " + mConfiguration);
4885            ApplicationInfo appInfo = app.instrumentationInfo != null
4886                    ? app.instrumentationInfo : app.info;
4887            app.compat = compatibilityInfoForPackageLocked(appInfo);
4888            if (profileFd != null) {
4889                profileFd = profileFd.dup();
4890            }
4891            thread.bindApplication(processName, appInfo, providers,
4892                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4893                    app.instrumentationArguments, app.instrumentationWatcher,
4894                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4895                    isRestrictedBackupMode || !normalMode, app.persistent,
4896                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4897                    mCoreSettingsObserver.getCoreSettingsLocked());
4898            updateLruProcessLocked(app, false, null);
4899            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4900        } catch (Exception e) {
4901            // todo: Yikes!  What should we do?  For now we will try to
4902            // start another process, but that could easily get us in
4903            // an infinite loop of restarting processes...
4904            Slog.w(TAG, "Exception thrown during bind!", e);
4905
4906            app.resetPackageList(mProcessStats);
4907            app.unlinkDeathRecipient();
4908            startProcessLocked(app, "bind fail", processName);
4909            return false;
4910        }
4911
4912        // Remove this record from the list of starting applications.
4913        mPersistentStartingProcesses.remove(app);
4914        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4915                "Attach application locked removing on hold: " + app);
4916        mProcessesOnHold.remove(app);
4917
4918        boolean badApp = false;
4919        boolean didSomething = false;
4920
4921        // See if the top visible activity is waiting to run in this process...
4922        if (normalMode) {
4923            try {
4924                if (mStackSupervisor.attachApplicationLocked(app)) {
4925                    didSomething = true;
4926                }
4927            } catch (Exception e) {
4928                badApp = true;
4929            }
4930        }
4931
4932        // Find any services that should be running in this process...
4933        if (!badApp) {
4934            try {
4935                didSomething |= mServices.attachApplicationLocked(app, processName);
4936            } catch (Exception e) {
4937                badApp = true;
4938            }
4939        }
4940
4941        // Check if a next-broadcast receiver is in this process...
4942        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4943            try {
4944                didSomething |= sendPendingBroadcastsLocked(app);
4945            } catch (Exception e) {
4946                // If the app died trying to launch the receiver we declare it 'bad'
4947                badApp = true;
4948            }
4949        }
4950
4951        // Check whether the next backup agent is in this process...
4952        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4953            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4954            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4955            try {
4956                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4957                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4958                        mBackupTarget.backupMode);
4959            } catch (Exception e) {
4960                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4961                e.printStackTrace();
4962            }
4963        }
4964
4965        if (badApp) {
4966            // todo: Also need to kill application to deal with all
4967            // kinds of exceptions.
4968            handleAppDiedLocked(app, false, true);
4969            return false;
4970        }
4971
4972        if (!didSomething) {
4973            updateOomAdjLocked();
4974        }
4975
4976        return true;
4977    }
4978
4979    @Override
4980    public final void attachApplication(IApplicationThread thread) {
4981        synchronized (this) {
4982            int callingPid = Binder.getCallingPid();
4983            final long origId = Binder.clearCallingIdentity();
4984            attachApplicationLocked(thread, callingPid);
4985            Binder.restoreCallingIdentity(origId);
4986        }
4987    }
4988
4989    @Override
4990    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4991        final long origId = Binder.clearCallingIdentity();
4992        synchronized (this) {
4993            ActivityStack stack = ActivityRecord.getStackLocked(token);
4994            if (stack != null) {
4995                ActivityRecord r =
4996                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
4997                if (stopProfiling) {
4998                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
4999                        try {
5000                            mProfileFd.close();
5001                        } catch (IOException e) {
5002                        }
5003                        clearProfilerLocked();
5004                    }
5005                }
5006            }
5007        }
5008        Binder.restoreCallingIdentity(origId);
5009    }
5010
5011    void enableScreenAfterBoot() {
5012        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5013                SystemClock.uptimeMillis());
5014        mWindowManager.enableScreenAfterBoot();
5015
5016        synchronized (this) {
5017            updateEventDispatchingLocked();
5018        }
5019    }
5020
5021    @Override
5022    public void showBootMessage(final CharSequence msg, final boolean always) {
5023        enforceNotIsolatedCaller("showBootMessage");
5024        mWindowManager.showBootMessage(msg, always);
5025    }
5026
5027    @Override
5028    public void dismissKeyguardOnNextActivity() {
5029        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5030        final long token = Binder.clearCallingIdentity();
5031        try {
5032            synchronized (this) {
5033                if (DEBUG_LOCKSCREEN) logLockScreen("");
5034                if (mLockScreenShown) {
5035                    mLockScreenShown = false;
5036                    comeOutOfSleepIfNeededLocked();
5037                }
5038                mStackSupervisor.setDismissKeyguard(true);
5039            }
5040        } finally {
5041            Binder.restoreCallingIdentity(token);
5042        }
5043    }
5044
5045    final void finishBooting() {
5046        IntentFilter pkgFilter = new IntentFilter();
5047        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5048        pkgFilter.addDataScheme("package");
5049        mContext.registerReceiver(new BroadcastReceiver() {
5050            @Override
5051            public void onReceive(Context context, Intent intent) {
5052                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5053                if (pkgs != null) {
5054                    for (String pkg : pkgs) {
5055                        synchronized (ActivityManagerService.this) {
5056                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0,
5057                                    "finished booting")) {
5058                                setResultCode(Activity.RESULT_OK);
5059                                return;
5060                            }
5061                        }
5062                    }
5063                }
5064            }
5065        }, pkgFilter);
5066
5067        synchronized (this) {
5068            // Ensure that any processes we had put on hold are now started
5069            // up.
5070            final int NP = mProcessesOnHold.size();
5071            if (NP > 0) {
5072                ArrayList<ProcessRecord> procs =
5073                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5074                for (int ip=0; ip<NP; ip++) {
5075                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5076                            + procs.get(ip));
5077                    startProcessLocked(procs.get(ip), "on-hold", null);
5078                }
5079            }
5080
5081            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5082                // Start looking for apps that are abusing wake locks.
5083                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5084                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5085                // Tell anyone interested that we are done booting!
5086                SystemProperties.set("sys.boot_completed", "1");
5087                SystemProperties.set("dev.bootcomplete", "1");
5088                for (int i=0; i<mStartedUsers.size(); i++) {
5089                    UserStartedState uss = mStartedUsers.valueAt(i);
5090                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5091                        uss.mState = UserStartedState.STATE_RUNNING;
5092                        final int userId = mStartedUsers.keyAt(i);
5093                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5094                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5095                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5096                        broadcastIntentLocked(null, null, intent, null,
5097                                new IIntentReceiver.Stub() {
5098                                    @Override
5099                                    public void performReceive(Intent intent, int resultCode,
5100                                            String data, Bundle extras, boolean ordered,
5101                                            boolean sticky, int sendingUser) {
5102                                        synchronized (ActivityManagerService.this) {
5103                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5104                                                    true, false);
5105                                        }
5106                                    }
5107                                },
5108                                0, null, null,
5109                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5110                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5111                                userId);
5112                    }
5113                }
5114            }
5115        }
5116    }
5117
5118    final void ensureBootCompleted() {
5119        boolean booting;
5120        boolean enableScreen;
5121        synchronized (this) {
5122            booting = mBooting;
5123            mBooting = false;
5124            enableScreen = !mBooted;
5125            mBooted = true;
5126        }
5127
5128        if (booting) {
5129            finishBooting();
5130        }
5131
5132        if (enableScreen) {
5133            enableScreenAfterBoot();
5134        }
5135    }
5136
5137    @Override
5138    public final void activityResumed(IBinder token) {
5139        final long origId = Binder.clearCallingIdentity();
5140        synchronized(this) {
5141            ActivityStack stack = ActivityRecord.getStackLocked(token);
5142            if (stack != null) {
5143                ActivityRecord.activityResumedLocked(token);
5144            }
5145        }
5146        Binder.restoreCallingIdentity(origId);
5147    }
5148
5149    @Override
5150    public final void activityPaused(IBinder token) {
5151        final long origId = Binder.clearCallingIdentity();
5152        synchronized(this) {
5153            ActivityStack stack = ActivityRecord.getStackLocked(token);
5154            if (stack != null) {
5155                stack.activityPausedLocked(token, false);
5156            }
5157        }
5158        Binder.restoreCallingIdentity(origId);
5159    }
5160
5161    @Override
5162    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5163            CharSequence description) {
5164        if (localLOGV) Slog.v(
5165            TAG, "Activity stopped: token=" + token);
5166
5167        // Refuse possible leaked file descriptors
5168        if (icicle != null && icicle.hasFileDescriptors()) {
5169            throw new IllegalArgumentException("File descriptors passed in Bundle");
5170        }
5171
5172        ActivityRecord r = null;
5173
5174        final long origId = Binder.clearCallingIdentity();
5175
5176        synchronized (this) {
5177            r = ActivityRecord.isInStackLocked(token);
5178            if (r != null) {
5179                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5180            }
5181        }
5182
5183        if (r != null) {
5184            sendPendingThumbnail(r, null, null, null, false);
5185        }
5186
5187        trimApplications();
5188
5189        Binder.restoreCallingIdentity(origId);
5190    }
5191
5192    @Override
5193    public final void activityDestroyed(IBinder token) {
5194        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5195        synchronized (this) {
5196            ActivityStack stack = ActivityRecord.getStackLocked(token);
5197            if (stack != null) {
5198                stack.activityDestroyedLocked(token);
5199            }
5200        }
5201    }
5202
5203    @Override
5204    public String getCallingPackage(IBinder token) {
5205        synchronized (this) {
5206            ActivityRecord r = getCallingRecordLocked(token);
5207            return r != null ? r.info.packageName : null;
5208        }
5209    }
5210
5211    @Override
5212    public ComponentName getCallingActivity(IBinder token) {
5213        synchronized (this) {
5214            ActivityRecord r = getCallingRecordLocked(token);
5215            return r != null ? r.intent.getComponent() : null;
5216        }
5217    }
5218
5219    private ActivityRecord getCallingRecordLocked(IBinder token) {
5220        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5221        if (r == null) {
5222            return null;
5223        }
5224        return r.resultTo;
5225    }
5226
5227    @Override
5228    public ComponentName getActivityClassForToken(IBinder token) {
5229        synchronized(this) {
5230            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5231            if (r == null) {
5232                return null;
5233            }
5234            return r.intent.getComponent();
5235        }
5236    }
5237
5238    @Override
5239    public String getPackageForToken(IBinder token) {
5240        synchronized(this) {
5241            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5242            if (r == null) {
5243                return null;
5244            }
5245            return r.packageName;
5246        }
5247    }
5248
5249    @Override
5250    public IIntentSender getIntentSender(int type,
5251            String packageName, IBinder token, String resultWho,
5252            int requestCode, Intent[] intents, String[] resolvedTypes,
5253            int flags, Bundle options, int userId) {
5254        enforceNotIsolatedCaller("getIntentSender");
5255        // Refuse possible leaked file descriptors
5256        if (intents != null) {
5257            if (intents.length < 1) {
5258                throw new IllegalArgumentException("Intents array length must be >= 1");
5259            }
5260            for (int i=0; i<intents.length; i++) {
5261                Intent intent = intents[i];
5262                if (intent != null) {
5263                    if (intent.hasFileDescriptors()) {
5264                        throw new IllegalArgumentException("File descriptors passed in Intent");
5265                    }
5266                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5267                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5268                        throw new IllegalArgumentException(
5269                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5270                    }
5271                    intents[i] = new Intent(intent);
5272                }
5273            }
5274            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5275                throw new IllegalArgumentException(
5276                        "Intent array length does not match resolvedTypes length");
5277            }
5278        }
5279        if (options != null) {
5280            if (options.hasFileDescriptors()) {
5281                throw new IllegalArgumentException("File descriptors passed in options");
5282            }
5283        }
5284
5285        synchronized(this) {
5286            int callingUid = Binder.getCallingUid();
5287            int origUserId = userId;
5288            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5289                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5290                    "getIntentSender", null);
5291            if (origUserId == UserHandle.USER_CURRENT) {
5292                // We don't want to evaluate this until the pending intent is
5293                // actually executed.  However, we do want to always do the
5294                // security checking for it above.
5295                userId = UserHandle.USER_CURRENT;
5296            }
5297            try {
5298                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5299                    int uid = AppGlobals.getPackageManager()
5300                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5301                    if (!UserHandle.isSameApp(callingUid, uid)) {
5302                        String msg = "Permission Denial: getIntentSender() from pid="
5303                            + Binder.getCallingPid()
5304                            + ", uid=" + Binder.getCallingUid()
5305                            + ", (need uid=" + uid + ")"
5306                            + " is not allowed to send as package " + packageName;
5307                        Slog.w(TAG, msg);
5308                        throw new SecurityException(msg);
5309                    }
5310                }
5311
5312                return getIntentSenderLocked(type, packageName, callingUid, userId,
5313                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5314
5315            } catch (RemoteException e) {
5316                throw new SecurityException(e);
5317            }
5318        }
5319    }
5320
5321    IIntentSender getIntentSenderLocked(int type, String packageName,
5322            int callingUid, int userId, IBinder token, String resultWho,
5323            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5324            Bundle options) {
5325        if (DEBUG_MU)
5326            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5327        ActivityRecord activity = null;
5328        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5329            activity = ActivityRecord.isInStackLocked(token);
5330            if (activity == null) {
5331                return null;
5332            }
5333            if (activity.finishing) {
5334                return null;
5335            }
5336        }
5337
5338        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5339        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5340        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5341        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5342                |PendingIntent.FLAG_UPDATE_CURRENT);
5343
5344        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5345                type, packageName, activity, resultWho,
5346                requestCode, intents, resolvedTypes, flags, options, userId);
5347        WeakReference<PendingIntentRecord> ref;
5348        ref = mIntentSenderRecords.get(key);
5349        PendingIntentRecord rec = ref != null ? ref.get() : null;
5350        if (rec != null) {
5351            if (!cancelCurrent) {
5352                if (updateCurrent) {
5353                    if (rec.key.requestIntent != null) {
5354                        rec.key.requestIntent.replaceExtras(intents != null ?
5355                                intents[intents.length - 1] : null);
5356                    }
5357                    if (intents != null) {
5358                        intents[intents.length-1] = rec.key.requestIntent;
5359                        rec.key.allIntents = intents;
5360                        rec.key.allResolvedTypes = resolvedTypes;
5361                    } else {
5362                        rec.key.allIntents = null;
5363                        rec.key.allResolvedTypes = null;
5364                    }
5365                }
5366                return rec;
5367            }
5368            rec.canceled = true;
5369            mIntentSenderRecords.remove(key);
5370        }
5371        if (noCreate) {
5372            return rec;
5373        }
5374        rec = new PendingIntentRecord(this, key, callingUid);
5375        mIntentSenderRecords.put(key, rec.ref);
5376        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5377            if (activity.pendingResults == null) {
5378                activity.pendingResults
5379                        = new HashSet<WeakReference<PendingIntentRecord>>();
5380            }
5381            activity.pendingResults.add(rec.ref);
5382        }
5383        return rec;
5384    }
5385
5386    @Override
5387    public void cancelIntentSender(IIntentSender sender) {
5388        if (!(sender instanceof PendingIntentRecord)) {
5389            return;
5390        }
5391        synchronized(this) {
5392            PendingIntentRecord rec = (PendingIntentRecord)sender;
5393            try {
5394                int uid = AppGlobals.getPackageManager()
5395                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5396                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5397                    String msg = "Permission Denial: cancelIntentSender() from pid="
5398                        + Binder.getCallingPid()
5399                        + ", uid=" + Binder.getCallingUid()
5400                        + " is not allowed to cancel packges "
5401                        + rec.key.packageName;
5402                    Slog.w(TAG, msg);
5403                    throw new SecurityException(msg);
5404                }
5405            } catch (RemoteException e) {
5406                throw new SecurityException(e);
5407            }
5408            cancelIntentSenderLocked(rec, true);
5409        }
5410    }
5411
5412    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5413        rec.canceled = true;
5414        mIntentSenderRecords.remove(rec.key);
5415        if (cleanActivity && rec.key.activity != null) {
5416            rec.key.activity.pendingResults.remove(rec.ref);
5417        }
5418    }
5419
5420    @Override
5421    public String getPackageForIntentSender(IIntentSender pendingResult) {
5422        if (!(pendingResult instanceof PendingIntentRecord)) {
5423            return null;
5424        }
5425        try {
5426            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5427            return res.key.packageName;
5428        } catch (ClassCastException e) {
5429        }
5430        return null;
5431    }
5432
5433    @Override
5434    public int getUidForIntentSender(IIntentSender sender) {
5435        if (sender instanceof PendingIntentRecord) {
5436            try {
5437                PendingIntentRecord res = (PendingIntentRecord)sender;
5438                return res.uid;
5439            } catch (ClassCastException e) {
5440            }
5441        }
5442        return -1;
5443    }
5444
5445    @Override
5446    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5447        if (!(pendingResult instanceof PendingIntentRecord)) {
5448            return false;
5449        }
5450        try {
5451            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5452            if (res.key.allIntents == null) {
5453                return false;
5454            }
5455            for (int i=0; i<res.key.allIntents.length; i++) {
5456                Intent intent = res.key.allIntents[i];
5457                if (intent.getPackage() != null && intent.getComponent() != null) {
5458                    return false;
5459                }
5460            }
5461            return true;
5462        } catch (ClassCastException e) {
5463        }
5464        return false;
5465    }
5466
5467    @Override
5468    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5469        if (!(pendingResult instanceof PendingIntentRecord)) {
5470            return false;
5471        }
5472        try {
5473            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5474            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5475                return true;
5476            }
5477            return false;
5478        } catch (ClassCastException e) {
5479        }
5480        return false;
5481    }
5482
5483    @Override
5484    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5485        if (!(pendingResult instanceof PendingIntentRecord)) {
5486            return null;
5487        }
5488        try {
5489            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5490            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5491        } catch (ClassCastException e) {
5492        }
5493        return null;
5494    }
5495
5496    @Override
5497    public void setProcessLimit(int max) {
5498        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5499                "setProcessLimit()");
5500        synchronized (this) {
5501            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5502            mProcessLimitOverride = max;
5503        }
5504        trimApplications();
5505    }
5506
5507    @Override
5508    public int getProcessLimit() {
5509        synchronized (this) {
5510            return mProcessLimitOverride;
5511        }
5512    }
5513
5514    void foregroundTokenDied(ForegroundToken token) {
5515        synchronized (ActivityManagerService.this) {
5516            synchronized (mPidsSelfLocked) {
5517                ForegroundToken cur
5518                    = mForegroundProcesses.get(token.pid);
5519                if (cur != token) {
5520                    return;
5521                }
5522                mForegroundProcesses.remove(token.pid);
5523                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5524                if (pr == null) {
5525                    return;
5526                }
5527                pr.forcingToForeground = null;
5528                pr.foregroundServices = false;
5529            }
5530            updateOomAdjLocked();
5531        }
5532    }
5533
5534    @Override
5535    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5536        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5537                "setProcessForeground()");
5538        synchronized(this) {
5539            boolean changed = false;
5540
5541            synchronized (mPidsSelfLocked) {
5542                ProcessRecord pr = mPidsSelfLocked.get(pid);
5543                if (pr == null && isForeground) {
5544                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5545                    return;
5546                }
5547                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5548                if (oldToken != null) {
5549                    oldToken.token.unlinkToDeath(oldToken, 0);
5550                    mForegroundProcesses.remove(pid);
5551                    if (pr != null) {
5552                        pr.forcingToForeground = null;
5553                    }
5554                    changed = true;
5555                }
5556                if (isForeground && token != null) {
5557                    ForegroundToken newToken = new ForegroundToken() {
5558                        @Override
5559                        public void binderDied() {
5560                            foregroundTokenDied(this);
5561                        }
5562                    };
5563                    newToken.pid = pid;
5564                    newToken.token = token;
5565                    try {
5566                        token.linkToDeath(newToken, 0);
5567                        mForegroundProcesses.put(pid, newToken);
5568                        pr.forcingToForeground = token;
5569                        changed = true;
5570                    } catch (RemoteException e) {
5571                        // If the process died while doing this, we will later
5572                        // do the cleanup with the process death link.
5573                    }
5574                }
5575            }
5576
5577            if (changed) {
5578                updateOomAdjLocked();
5579            }
5580        }
5581    }
5582
5583    // =========================================================
5584    // PERMISSIONS
5585    // =========================================================
5586
5587    static class PermissionController extends IPermissionController.Stub {
5588        ActivityManagerService mActivityManagerService;
5589        PermissionController(ActivityManagerService activityManagerService) {
5590            mActivityManagerService = activityManagerService;
5591        }
5592
5593        @Override
5594        public boolean checkPermission(String permission, int pid, int uid) {
5595            return mActivityManagerService.checkPermission(permission, pid,
5596                    uid) == PackageManager.PERMISSION_GRANTED;
5597        }
5598    }
5599
5600    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5601        @Override
5602        public int checkComponentPermission(String permission, int pid, int uid,
5603                int owningUid, boolean exported) {
5604            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5605                    owningUid, exported);
5606        }
5607
5608        @Override
5609        public Object getAMSLock() {
5610            return ActivityManagerService.this;
5611        }
5612    }
5613
5614    /**
5615     * This can be called with or without the global lock held.
5616     */
5617    int checkComponentPermission(String permission, int pid, int uid,
5618            int owningUid, boolean exported) {
5619        // We might be performing an operation on behalf of an indirect binder
5620        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5621        // client identity accordingly before proceeding.
5622        Identity tlsIdentity = sCallerIdentity.get();
5623        if (tlsIdentity != null) {
5624            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5625                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5626            uid = tlsIdentity.uid;
5627            pid = tlsIdentity.pid;
5628        }
5629
5630        if (pid == MY_PID) {
5631            return PackageManager.PERMISSION_GRANTED;
5632        }
5633
5634        return ActivityManager.checkComponentPermission(permission, uid,
5635                owningUid, exported);
5636    }
5637
5638    /**
5639     * As the only public entry point for permissions checking, this method
5640     * can enforce the semantic that requesting a check on a null global
5641     * permission is automatically denied.  (Internally a null permission
5642     * string is used when calling {@link #checkComponentPermission} in cases
5643     * when only uid-based security is needed.)
5644     *
5645     * This can be called with or without the global lock held.
5646     */
5647    @Override
5648    public int checkPermission(String permission, int pid, int uid) {
5649        if (permission == null) {
5650            return PackageManager.PERMISSION_DENIED;
5651        }
5652        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5653    }
5654
5655    /**
5656     * Binder IPC calls go through the public entry point.
5657     * This can be called with or without the global lock held.
5658     */
5659    int checkCallingPermission(String permission) {
5660        return checkPermission(permission,
5661                Binder.getCallingPid(),
5662                UserHandle.getAppId(Binder.getCallingUid()));
5663    }
5664
5665    /**
5666     * This can be called with or without the global lock held.
5667     */
5668    void enforceCallingPermission(String permission, String func) {
5669        if (checkCallingPermission(permission)
5670                == PackageManager.PERMISSION_GRANTED) {
5671            return;
5672        }
5673
5674        String msg = "Permission Denial: " + func + " from pid="
5675                + Binder.getCallingPid()
5676                + ", uid=" + Binder.getCallingUid()
5677                + " requires " + permission;
5678        Slog.w(TAG, msg);
5679        throw new SecurityException(msg);
5680    }
5681
5682    /**
5683     * Determine if UID is holding permissions required to access {@link Uri} in
5684     * the given {@link ProviderInfo}. Final permission checking is always done
5685     * in {@link ContentProvider}.
5686     */
5687    private final boolean checkHoldingPermissionsLocked(
5688            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5689        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5690                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5691
5692        if (pi.applicationInfo.uid == uid) {
5693            return true;
5694        } else if (!pi.exported) {
5695            return false;
5696        }
5697
5698        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5699        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5700        try {
5701            // check if target holds top-level <provider> permissions
5702            if (!readMet && pi.readPermission != null
5703                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5704                readMet = true;
5705            }
5706            if (!writeMet && pi.writePermission != null
5707                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5708                writeMet = true;
5709            }
5710
5711            // track if unprotected read/write is allowed; any denied
5712            // <path-permission> below removes this ability
5713            boolean allowDefaultRead = pi.readPermission == null;
5714            boolean allowDefaultWrite = pi.writePermission == null;
5715
5716            // check if target holds any <path-permission> that match uri
5717            final PathPermission[] pps = pi.pathPermissions;
5718            if (pps != null) {
5719                final String path = uri.getPath();
5720                int i = pps.length;
5721                while (i > 0 && (!readMet || !writeMet)) {
5722                    i--;
5723                    PathPermission pp = pps[i];
5724                    if (pp.match(path)) {
5725                        if (!readMet) {
5726                            final String pprperm = pp.getReadPermission();
5727                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5728                                    + pprperm + " for " + pp.getPath()
5729                                    + ": match=" + pp.match(path)
5730                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5731                            if (pprperm != null) {
5732                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5733                                    readMet = true;
5734                                } else {
5735                                    allowDefaultRead = false;
5736                                }
5737                            }
5738                        }
5739                        if (!writeMet) {
5740                            final String ppwperm = pp.getWritePermission();
5741                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5742                                    + ppwperm + " for " + pp.getPath()
5743                                    + ": match=" + pp.match(path)
5744                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5745                            if (ppwperm != null) {
5746                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5747                                    writeMet = true;
5748                                } else {
5749                                    allowDefaultWrite = false;
5750                                }
5751                            }
5752                        }
5753                    }
5754                }
5755            }
5756
5757            // grant unprotected <provider> read/write, if not blocked by
5758            // <path-permission> above
5759            if (allowDefaultRead) readMet = true;
5760            if (allowDefaultWrite) writeMet = true;
5761
5762        } catch (RemoteException e) {
5763            return false;
5764        }
5765
5766        return readMet && writeMet;
5767    }
5768
5769    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5770        ProviderInfo pi = null;
5771        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5772        if (cpr != null) {
5773            pi = cpr.info;
5774        } else {
5775            try {
5776                pi = AppGlobals.getPackageManager().resolveContentProvider(
5777                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5778            } catch (RemoteException ex) {
5779            }
5780        }
5781        return pi;
5782    }
5783
5784    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5785        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5786        if (targetUris != null) {
5787            return targetUris.get(uri);
5788        } else {
5789            return null;
5790        }
5791    }
5792
5793    private UriPermission findOrCreateUriPermissionLocked(
5794            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5795        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5796        if (targetUris == null) {
5797            targetUris = Maps.newArrayMap();
5798            mGrantedUriPermissions.put(targetUid, targetUris);
5799        }
5800
5801        UriPermission perm = targetUris.get(uri);
5802        if (perm == null) {
5803            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5804            targetUris.put(uri, perm);
5805        }
5806
5807        return perm;
5808    }
5809
5810    private final boolean checkUriPermissionLocked(
5811            Uri uri, int uid, int modeFlags, int minStrength) {
5812        // Root gets to do everything.
5813        if (uid == 0) {
5814            return true;
5815        }
5816        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5817        if (perms == null) return false;
5818        UriPermission perm = perms.get(uri);
5819        if (perm == null) return false;
5820        return perm.getStrength(modeFlags) >= minStrength;
5821    }
5822
5823    @Override
5824    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5825        enforceNotIsolatedCaller("checkUriPermission");
5826
5827        // Another redirected-binder-call permissions check as in
5828        // {@link checkComponentPermission}.
5829        Identity tlsIdentity = sCallerIdentity.get();
5830        if (tlsIdentity != null) {
5831            uid = tlsIdentity.uid;
5832            pid = tlsIdentity.pid;
5833        }
5834
5835        // Our own process gets to do everything.
5836        if (pid == MY_PID) {
5837            return PackageManager.PERMISSION_GRANTED;
5838        }
5839        synchronized(this) {
5840            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5841                    ? PackageManager.PERMISSION_GRANTED
5842                    : PackageManager.PERMISSION_DENIED;
5843        }
5844    }
5845
5846    /**
5847     * Check if the targetPkg can be granted permission to access uri by
5848     * the callingUid using the given modeFlags.  Throws a security exception
5849     * if callingUid is not allowed to do this.  Returns the uid of the target
5850     * if the URI permission grant should be performed; returns -1 if it is not
5851     * needed (for example targetPkg already has permission to access the URI).
5852     * If you already know the uid of the target, you can supply it in
5853     * lastTargetUid else set that to -1.
5854     */
5855    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5856            Uri uri, int modeFlags, int lastTargetUid) {
5857        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5858        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5859                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5860        if (modeFlags == 0) {
5861            return -1;
5862        }
5863
5864        if (targetPkg != null) {
5865            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5866                    "Checking grant " + targetPkg + " permission to " + uri);
5867        }
5868
5869        final IPackageManager pm = AppGlobals.getPackageManager();
5870
5871        // If this is not a content: uri, we can't do anything with it.
5872        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5873            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5874                    "Can't grant URI permission for non-content URI: " + uri);
5875            return -1;
5876        }
5877
5878        final String authority = uri.getAuthority();
5879        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5880        if (pi == null) {
5881            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5882            return -1;
5883        }
5884
5885        int targetUid = lastTargetUid;
5886        if (targetUid < 0 && targetPkg != null) {
5887            try {
5888                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5889                if (targetUid < 0) {
5890                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5891                            "Can't grant URI permission no uid for: " + targetPkg);
5892                    return -1;
5893                }
5894            } catch (RemoteException ex) {
5895                return -1;
5896            }
5897        }
5898
5899        if (targetUid >= 0) {
5900            // First...  does the target actually need this permission?
5901            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5902                // No need to grant the target this permission.
5903                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5904                        "Target " + targetPkg + " already has full permission to " + uri);
5905                return -1;
5906            }
5907        } else {
5908            // First...  there is no target package, so can anyone access it?
5909            boolean allowed = pi.exported;
5910            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5911                if (pi.readPermission != null) {
5912                    allowed = false;
5913                }
5914            }
5915            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5916                if (pi.writePermission != null) {
5917                    allowed = false;
5918                }
5919            }
5920            if (allowed) {
5921                return -1;
5922            }
5923        }
5924
5925        // Second...  is the provider allowing granting of URI permissions?
5926        if (!pi.grantUriPermissions) {
5927            throw new SecurityException("Provider " + pi.packageName
5928                    + "/" + pi.name
5929                    + " does not allow granting of Uri permissions (uri "
5930                    + uri + ")");
5931        }
5932        if (pi.uriPermissionPatterns != null) {
5933            final int N = pi.uriPermissionPatterns.length;
5934            boolean allowed = false;
5935            for (int i=0; i<N; i++) {
5936                if (pi.uriPermissionPatterns[i] != null
5937                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5938                    allowed = true;
5939                    break;
5940                }
5941            }
5942            if (!allowed) {
5943                throw new SecurityException("Provider " + pi.packageName
5944                        + "/" + pi.name
5945                        + " does not allow granting of permission to path of Uri "
5946                        + uri);
5947            }
5948        }
5949
5950        // Third...  does the caller itself have permission to access
5951        // this uri?
5952        if (callingUid != Process.myUid()) {
5953            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5954                // Require they hold a strong enough Uri permission
5955                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
5956                        : UriPermission.STRENGTH_OWNED;
5957                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
5958                    throw new SecurityException("Uid " + callingUid
5959                            + " does not have permission to uri " + uri);
5960                }
5961            }
5962        }
5963
5964        return targetUid;
5965    }
5966
5967    @Override
5968    public int checkGrantUriPermission(int callingUid, String targetPkg,
5969            Uri uri, int modeFlags) {
5970        enforceNotIsolatedCaller("checkGrantUriPermission");
5971        synchronized(this) {
5972            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5973        }
5974    }
5975
5976    void grantUriPermissionUncheckedLocked(
5977            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
5978        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5979        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5980                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5981        if (modeFlags == 0) {
5982            return;
5983        }
5984
5985        // So here we are: the caller has the assumed permission
5986        // to the uri, and the target doesn't.  Let's now give this to
5987        // the target.
5988
5989        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5990                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5991
5992        final String authority = uri.getAuthority();
5993        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
5994        if (pi == null) {
5995            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
5996            return;
5997        }
5998
5999        final UriPermission perm = findOrCreateUriPermissionLocked(
6000                pi.packageName, targetPkg, targetUid, uri);
6001        perm.grantModes(modeFlags, persistable, owner);
6002    }
6003
6004    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6005            int modeFlags, UriPermissionOwner owner) {
6006        if (targetPkg == null) {
6007            throw new NullPointerException("targetPkg");
6008        }
6009
6010        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6011        if (targetUid < 0) {
6012            return;
6013        }
6014
6015        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6016    }
6017
6018    static class NeededUriGrants extends ArrayList<Uri> {
6019        final String targetPkg;
6020        final int targetUid;
6021        final int flags;
6022
6023        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6024            this.targetPkg = targetPkg;
6025            this.targetUid = targetUid;
6026            this.flags = flags;
6027        }
6028    }
6029
6030    /**
6031     * Like checkGrantUriPermissionLocked, but takes an Intent.
6032     */
6033    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6034            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6035        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6036                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6037                + " clip=" + (intent != null ? intent.getClipData() : null)
6038                + " from " + intent + "; flags=0x"
6039                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6040
6041        if (targetPkg == null) {
6042            throw new NullPointerException("targetPkg");
6043        }
6044
6045        if (intent == null) {
6046            return null;
6047        }
6048        Uri data = intent.getData();
6049        ClipData clip = intent.getClipData();
6050        if (data == null && clip == null) {
6051            return null;
6052        }
6053
6054        if (data != null) {
6055            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6056                mode, needed != null ? needed.targetUid : -1);
6057            if (targetUid > 0) {
6058                if (needed == null) {
6059                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6060                }
6061                needed.add(data);
6062            }
6063        }
6064        if (clip != null) {
6065            for (int i=0; i<clip.getItemCount(); i++) {
6066                Uri uri = clip.getItemAt(i).getUri();
6067                if (uri != null) {
6068                    int targetUid = -1;
6069                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6070                            mode, needed != null ? needed.targetUid : -1);
6071                    if (targetUid > 0) {
6072                        if (needed == null) {
6073                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6074                        }
6075                        needed.add(uri);
6076                    }
6077                } else {
6078                    Intent clipIntent = clip.getItemAt(i).getIntent();
6079                    if (clipIntent != null) {
6080                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6081                                callingUid, targetPkg, clipIntent, mode, needed);
6082                        if (newNeeded != null) {
6083                            needed = newNeeded;
6084                        }
6085                    }
6086                }
6087            }
6088        }
6089
6090        return needed;
6091    }
6092
6093    /**
6094     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6095     */
6096    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6097            UriPermissionOwner owner) {
6098        if (needed != null) {
6099            for (int i=0; i<needed.size(); i++) {
6100                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6101                        needed.get(i), needed.flags, owner);
6102            }
6103        }
6104    }
6105
6106    void grantUriPermissionFromIntentLocked(int callingUid,
6107            String targetPkg, Intent intent, UriPermissionOwner owner) {
6108        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6109                intent, intent != null ? intent.getFlags() : 0, null);
6110        if (needed == null) {
6111            return;
6112        }
6113
6114        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6115    }
6116
6117    @Override
6118    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6119            Uri uri, int modeFlags) {
6120        enforceNotIsolatedCaller("grantUriPermission");
6121        synchronized(this) {
6122            final ProcessRecord r = getRecordForAppLocked(caller);
6123            if (r == null) {
6124                throw new SecurityException("Unable to find app for caller "
6125                        + caller
6126                        + " when granting permission to uri " + uri);
6127            }
6128            if (targetPkg == null) {
6129                throw new IllegalArgumentException("null target");
6130            }
6131            if (uri == null) {
6132                throw new IllegalArgumentException("null uri");
6133            }
6134
6135            // Persistable only supported through Intents
6136            Preconditions.checkFlagsArgument(modeFlags,
6137                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6138
6139            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6140                    null);
6141        }
6142    }
6143
6144    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6145        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6146                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6147            ArrayMap<Uri, UriPermission> perms
6148                    = mGrantedUriPermissions.get(perm.targetUid);
6149            if (perms != null) {
6150                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6151                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6152                perms.remove(perm.uri);
6153                if (perms.size() == 0) {
6154                    mGrantedUriPermissions.remove(perm.targetUid);
6155                }
6156            }
6157        }
6158    }
6159
6160    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6161        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6162
6163        final IPackageManager pm = AppGlobals.getPackageManager();
6164        final String authority = uri.getAuthority();
6165        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6166        if (pi == null) {
6167            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6168            return;
6169        }
6170
6171        // Does the caller have this permission on the URI?
6172        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6173            // Right now, if you are not the original owner of the permission,
6174            // you are not allowed to revoke it.
6175            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6176                throw new SecurityException("Uid " + callingUid
6177                        + " does not have permission to uri " + uri);
6178            //}
6179        }
6180
6181        boolean persistChanged = false;
6182
6183        // Go through all of the permissions and remove any that match.
6184        final List<String> SEGMENTS = uri.getPathSegments();
6185        if (SEGMENTS != null) {
6186            final int NS = SEGMENTS.size();
6187            int N = mGrantedUriPermissions.size();
6188            for (int i=0; i<N; i++) {
6189                ArrayMap<Uri, UriPermission> perms
6190                        = mGrantedUriPermissions.valueAt(i);
6191                Iterator<UriPermission> it = perms.values().iterator();
6192            toploop:
6193                while (it.hasNext()) {
6194                    UriPermission perm = it.next();
6195                    Uri targetUri = perm.uri;
6196                    if (!authority.equals(targetUri.getAuthority())) {
6197                        continue;
6198                    }
6199                    List<String> targetSegments = targetUri.getPathSegments();
6200                    if (targetSegments == null) {
6201                        continue;
6202                    }
6203                    if (targetSegments.size() < NS) {
6204                        continue;
6205                    }
6206                    for (int j=0; j<NS; j++) {
6207                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6208                            continue toploop;
6209                        }
6210                    }
6211                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6212                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6213                    persistChanged |= perm.clearModes(modeFlags, true);
6214                    if (perm.modeFlags == 0) {
6215                        it.remove();
6216                    }
6217                }
6218                if (perms.size() == 0) {
6219                    mGrantedUriPermissions.remove(
6220                            mGrantedUriPermissions.keyAt(i));
6221                    N--;
6222                    i--;
6223                }
6224            }
6225        }
6226
6227        if (persistChanged) {
6228            schedulePersistUriGrants();
6229        }
6230    }
6231
6232    @Override
6233    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6234            int modeFlags) {
6235        enforceNotIsolatedCaller("revokeUriPermission");
6236        synchronized(this) {
6237            final ProcessRecord r = getRecordForAppLocked(caller);
6238            if (r == null) {
6239                throw new SecurityException("Unable to find app for caller "
6240                        + caller
6241                        + " when revoking permission to uri " + uri);
6242            }
6243            if (uri == null) {
6244                Slog.w(TAG, "revokeUriPermission: null uri");
6245                return;
6246            }
6247
6248            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6249                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6250            if (modeFlags == 0) {
6251                return;
6252            }
6253
6254            final IPackageManager pm = AppGlobals.getPackageManager();
6255            final String authority = uri.getAuthority();
6256            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6257            if (pi == null) {
6258                Slog.w(TAG, "No content provider found for permission revoke: "
6259                        + uri.toSafeString());
6260                return;
6261            }
6262
6263            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6264        }
6265    }
6266
6267    /**
6268     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6269     * given package.
6270     *
6271     * @param packageName Package name to match, or {@code null} to apply to all
6272     *            packages.
6273     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6274     *            to all users.
6275     * @param persistable If persistable grants should be removed.
6276     */
6277    private void removeUriPermissionsForPackageLocked(
6278            String packageName, int userHandle, boolean persistable) {
6279        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6280            throw new IllegalArgumentException("Must narrow by either package or user");
6281        }
6282
6283        boolean persistChanged = false;
6284
6285        final int size = mGrantedUriPermissions.size();
6286        for (int i = 0; i < size; i++) {
6287            // Only inspect grants matching user
6288            if (userHandle == UserHandle.USER_ALL
6289                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6290                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6291                        .values().iterator();
6292                while (it.hasNext()) {
6293                    final UriPermission perm = it.next();
6294
6295                    // Only inspect grants matching package
6296                    if (packageName == null || perm.sourcePkg.equals(packageName)
6297                            || perm.targetPkg.equals(packageName)) {
6298                        persistChanged |= perm.clearModes(~0, persistable);
6299
6300                        // Only remove when no modes remain; any persisted grants
6301                        // will keep this alive.
6302                        if (perm.modeFlags == 0) {
6303                            it.remove();
6304                        }
6305                    }
6306                }
6307            }
6308        }
6309
6310        if (persistChanged) {
6311            schedulePersistUriGrants();
6312        }
6313    }
6314
6315    @Override
6316    public IBinder newUriPermissionOwner(String name) {
6317        enforceNotIsolatedCaller("newUriPermissionOwner");
6318        synchronized(this) {
6319            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6320            return owner.getExternalTokenLocked();
6321        }
6322    }
6323
6324    @Override
6325    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6326            Uri uri, int modeFlags) {
6327        synchronized(this) {
6328            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6329            if (owner == null) {
6330                throw new IllegalArgumentException("Unknown owner: " + token);
6331            }
6332            if (fromUid != Binder.getCallingUid()) {
6333                if (Binder.getCallingUid() != Process.myUid()) {
6334                    // Only system code can grant URI permissions on behalf
6335                    // of other users.
6336                    throw new SecurityException("nice try");
6337                }
6338            }
6339            if (targetPkg == null) {
6340                throw new IllegalArgumentException("null target");
6341            }
6342            if (uri == null) {
6343                throw new IllegalArgumentException("null uri");
6344            }
6345
6346            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6347        }
6348    }
6349
6350    @Override
6351    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6352        synchronized(this) {
6353            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6354            if (owner == null) {
6355                throw new IllegalArgumentException("Unknown owner: " + token);
6356            }
6357
6358            if (uri == null) {
6359                owner.removeUriPermissionsLocked(mode);
6360            } else {
6361                owner.removeUriPermissionLocked(uri, mode);
6362            }
6363        }
6364    }
6365
6366    private void schedulePersistUriGrants() {
6367        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6368            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6369                    10 * DateUtils.SECOND_IN_MILLIS);
6370        }
6371    }
6372
6373    private void writeGrantedUriPermissions() {
6374        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6375
6376        // Snapshot permissions so we can persist without lock
6377        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6378        synchronized (this) {
6379            final int size = mGrantedUriPermissions.size();
6380            for (int i = 0 ; i < size; i++) {
6381                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6382                    if (perm.persistedModeFlags != 0) {
6383                        persist.add(perm.snapshot());
6384                    }
6385                }
6386            }
6387        }
6388
6389        FileOutputStream fos = null;
6390        try {
6391            fos = mGrantFile.startWrite();
6392
6393            XmlSerializer out = new FastXmlSerializer();
6394            out.setOutput(fos, "utf-8");
6395            out.startDocument(null, true);
6396            out.startTag(null, TAG_URI_GRANTS);
6397            for (UriPermission.Snapshot perm : persist) {
6398                out.startTag(null, TAG_URI_GRANT);
6399                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6400                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6401                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6402                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6403                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6404                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6405                out.endTag(null, TAG_URI_GRANT);
6406            }
6407            out.endTag(null, TAG_URI_GRANTS);
6408            out.endDocument();
6409
6410            mGrantFile.finishWrite(fos);
6411        } catch (IOException e) {
6412            if (fos != null) {
6413                mGrantFile.failWrite(fos);
6414            }
6415        }
6416    }
6417
6418    private void readGrantedUriPermissionsLocked() {
6419        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6420
6421        final long now = System.currentTimeMillis();
6422
6423        FileInputStream fis = null;
6424        try {
6425            fis = mGrantFile.openRead();
6426            final XmlPullParser in = Xml.newPullParser();
6427            in.setInput(fis, null);
6428
6429            int type;
6430            while ((type = in.next()) != END_DOCUMENT) {
6431                final String tag = in.getName();
6432                if (type == START_TAG) {
6433                    if (TAG_URI_GRANT.equals(tag)) {
6434                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6435                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6436                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6437                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6438                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6439                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6440
6441                        // Sanity check that provider still belongs to source package
6442                        final ProviderInfo pi = getProviderInfoLocked(
6443                                uri.getAuthority(), userHandle);
6444                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6445                            int targetUid = -1;
6446                            try {
6447                                targetUid = AppGlobals.getPackageManager()
6448                                        .getPackageUid(targetPkg, userHandle);
6449                            } catch (RemoteException e) {
6450                            }
6451                            if (targetUid != -1) {
6452                                final UriPermission perm = findOrCreateUriPermissionLocked(
6453                                        sourcePkg, targetPkg, targetUid, uri);
6454                                perm.initPersistedModes(modeFlags, createdTime);
6455                            }
6456                        } else {
6457                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6458                                    + " but instead found " + pi);
6459                        }
6460                    }
6461                }
6462            }
6463        } catch (FileNotFoundException e) {
6464            // Missing grants is okay
6465        } catch (IOException e) {
6466            Log.wtf(TAG, "Failed reading Uri grants", e);
6467        } catch (XmlPullParserException e) {
6468            Log.wtf(TAG, "Failed reading Uri grants", e);
6469        } finally {
6470            IoUtils.closeQuietly(fis);
6471        }
6472    }
6473
6474    @Override
6475    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6476        enforceNotIsolatedCaller("takePersistableUriPermission");
6477
6478        Preconditions.checkFlagsArgument(modeFlags,
6479                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6480
6481        synchronized (this) {
6482            final int callingUid = Binder.getCallingUid();
6483            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6484            if (perm == null) {
6485                throw new SecurityException("No permission grant found for UID " + callingUid
6486                        + " and Uri " + uri.toSafeString());
6487            }
6488
6489            boolean persistChanged = perm.takePersistableModes(modeFlags);
6490            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6491
6492            if (persistChanged) {
6493                schedulePersistUriGrants();
6494            }
6495        }
6496    }
6497
6498    @Override
6499    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6500        enforceNotIsolatedCaller("releasePersistableUriPermission");
6501
6502        Preconditions.checkFlagsArgument(modeFlags,
6503                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6504
6505        synchronized (this) {
6506            final int callingUid = Binder.getCallingUid();
6507
6508            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6509            if (perm == null) {
6510                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6511                        + uri.toSafeString());
6512                return;
6513            }
6514
6515            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6516            removeUriPermissionIfNeededLocked(perm);
6517            if (persistChanged) {
6518                schedulePersistUriGrants();
6519            }
6520        }
6521    }
6522
6523    /**
6524     * Prune any older {@link UriPermission} for the given UID until outstanding
6525     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6526     *
6527     * @return if any mutations occured that require persisting.
6528     */
6529    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6530        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6531        if (perms == null) return false;
6532        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6533
6534        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6535        for (UriPermission perm : perms.values()) {
6536            if (perm.persistedModeFlags != 0) {
6537                persisted.add(perm);
6538            }
6539        }
6540
6541        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6542        if (trimCount <= 0) return false;
6543
6544        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6545        for (int i = 0; i < trimCount; i++) {
6546            final UriPermission perm = persisted.get(i);
6547
6548            if (DEBUG_URI_PERMISSION) {
6549                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6550            }
6551
6552            perm.releasePersistableModes(~0);
6553            removeUriPermissionIfNeededLocked(perm);
6554        }
6555
6556        return true;
6557    }
6558
6559    @Override
6560    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6561            String packageName, boolean incoming) {
6562        enforceNotIsolatedCaller("getPersistedUriPermissions");
6563        Preconditions.checkNotNull(packageName, "packageName");
6564
6565        final int callingUid = Binder.getCallingUid();
6566        final IPackageManager pm = AppGlobals.getPackageManager();
6567        try {
6568            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6569            if (packageUid != callingUid) {
6570                throw new SecurityException(
6571                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6572            }
6573        } catch (RemoteException e) {
6574            throw new SecurityException("Failed to verify package name ownership");
6575        }
6576
6577        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6578        synchronized (this) {
6579            if (incoming) {
6580                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6581                if (perms == null) {
6582                    Slog.w(TAG, "No permission grants found for " + packageName);
6583                } else {
6584                    final int size = perms.size();
6585                    for (int i = 0; i < size; i++) {
6586                        final UriPermission perm = perms.valueAt(i);
6587                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6588                            result.add(perm.buildPersistedPublicApiObject());
6589                        }
6590                    }
6591                }
6592            } else {
6593                final int size = mGrantedUriPermissions.size();
6594                for (int i = 0; i < size; i++) {
6595                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6596                    final int permsSize = perms.size();
6597                    for (int j = 0; j < permsSize; j++) {
6598                        final UriPermission perm = perms.valueAt(j);
6599                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6600                            result.add(perm.buildPersistedPublicApiObject());
6601                        }
6602                    }
6603                }
6604            }
6605        }
6606        return new ParceledListSlice<android.content.UriPermission>(result);
6607    }
6608
6609    @Override
6610    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6611        synchronized (this) {
6612            ProcessRecord app =
6613                who != null ? getRecordForAppLocked(who) : null;
6614            if (app == null) return;
6615
6616            Message msg = Message.obtain();
6617            msg.what = WAIT_FOR_DEBUGGER_MSG;
6618            msg.obj = app;
6619            msg.arg1 = waiting ? 1 : 0;
6620            mHandler.sendMessage(msg);
6621        }
6622    }
6623
6624    @Override
6625    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6626        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6627        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6628        outInfo.availMem = Process.getFreeMemory();
6629        outInfo.totalMem = Process.getTotalMemory();
6630        outInfo.threshold = homeAppMem;
6631        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6632        outInfo.hiddenAppThreshold = cachedAppMem;
6633        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6634                ProcessList.SERVICE_ADJ);
6635        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6636                ProcessList.VISIBLE_APP_ADJ);
6637        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6638                ProcessList.FOREGROUND_APP_ADJ);
6639    }
6640
6641    // =========================================================
6642    // TASK MANAGEMENT
6643    // =========================================================
6644
6645    @Override
6646    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6647                         IThumbnailReceiver receiver) {
6648        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6649
6650        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6651        ActivityRecord topRecord = null;
6652
6653        synchronized(this) {
6654            if (localLOGV) Slog.v(
6655                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6656                + ", receiver=" + receiver);
6657
6658            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6659                    != PackageManager.PERMISSION_GRANTED) {
6660                if (receiver != null) {
6661                    // If the caller wants to wait for pending thumbnails,
6662                    // it ain't gonna get them.
6663                    try {
6664                        receiver.finished();
6665                    } catch (RemoteException ex) {
6666                    }
6667                }
6668                String msg = "Permission Denial: getTasks() from pid="
6669                        + Binder.getCallingPid()
6670                        + ", uid=" + Binder.getCallingUid()
6671                        + " requires " + android.Manifest.permission.GET_TASKS;
6672                Slog.w(TAG, msg);
6673                throw new SecurityException(msg);
6674            }
6675
6676            // TODO: Improve with MRU list from all ActivityStacks.
6677            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6678
6679            if (!pending.pendingRecords.isEmpty()) {
6680                mPendingThumbnails.add(pending);
6681            }
6682        }
6683
6684        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6685
6686        if (topRecord != null) {
6687            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6688            try {
6689                IApplicationThread topThumbnail = topRecord.app.thread;
6690                topThumbnail.requestThumbnail(topRecord.appToken);
6691            } catch (Exception e) {
6692                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6693                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6694            }
6695        }
6696
6697        if (pending == null && receiver != null) {
6698            // In this case all thumbnails were available and the client
6699            // is being asked to be told when the remaining ones come in...
6700            // which is unusually, since the top-most currently running
6701            // activity should never have a canned thumbnail!  Oh well.
6702            try {
6703                receiver.finished();
6704            } catch (RemoteException ex) {
6705            }
6706        }
6707
6708        return list;
6709    }
6710
6711    TaskRecord getMostRecentTask() {
6712        return mRecentTasks.get(0);
6713    }
6714
6715    @Override
6716    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6717            int flags, int userId) {
6718        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6719                false, true, "getRecentTasks", null);
6720
6721        synchronized (this) {
6722            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6723                    "getRecentTasks()");
6724            final boolean detailed = checkCallingPermission(
6725                    android.Manifest.permission.GET_DETAILED_TASKS)
6726                    == PackageManager.PERMISSION_GRANTED;
6727
6728            IPackageManager pm = AppGlobals.getPackageManager();
6729
6730            final int N = mRecentTasks.size();
6731            ArrayList<ActivityManager.RecentTaskInfo> res
6732                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6733                            maxNum < N ? maxNum : N);
6734            for (int i=0; i<N && maxNum > 0; i++) {
6735                TaskRecord tr = mRecentTasks.get(i);
6736                // Only add calling user's recent tasks
6737                if (tr.userId != userId) continue;
6738                // Return the entry if desired by the caller.  We always return
6739                // the first entry, because callers always expect this to be the
6740                // foreground app.  We may filter others if the caller has
6741                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6742                // we should exclude the entry.
6743
6744                if (i == 0
6745                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6746                        || (tr.intent == null)
6747                        || ((tr.intent.getFlags()
6748                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6749                    ActivityManager.RecentTaskInfo rti
6750                            = new ActivityManager.RecentTaskInfo();
6751                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6752                    rti.persistentId = tr.taskId;
6753                    rti.baseIntent = new Intent(
6754                            tr.intent != null ? tr.intent : tr.affinityIntent);
6755                    if (!detailed) {
6756                        rti.baseIntent.replaceExtras((Bundle)null);
6757                    }
6758                    rti.origActivity = tr.origActivity;
6759                    rti.description = tr.lastDescription;
6760                    rti.stackId = tr.stack.mStackId;
6761
6762                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6763                        // Check whether this activity is currently available.
6764                        try {
6765                            if (rti.origActivity != null) {
6766                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6767                                        == null) {
6768                                    continue;
6769                                }
6770                            } else if (rti.baseIntent != null) {
6771                                if (pm.queryIntentActivities(rti.baseIntent,
6772                                        null, 0, userId) == null) {
6773                                    continue;
6774                                }
6775                            }
6776                        } catch (RemoteException e) {
6777                            // Will never happen.
6778                        }
6779                    }
6780
6781                    res.add(rti);
6782                    maxNum--;
6783                }
6784            }
6785            return res;
6786        }
6787    }
6788
6789    private TaskRecord recentTaskForIdLocked(int id) {
6790        final int N = mRecentTasks.size();
6791            for (int i=0; i<N; i++) {
6792                TaskRecord tr = mRecentTasks.get(i);
6793                if (tr.taskId == id) {
6794                    return tr;
6795                }
6796            }
6797            return null;
6798    }
6799
6800    @Override
6801    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6802        synchronized (this) {
6803            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6804                    "getTaskThumbnails()");
6805            TaskRecord tr = recentTaskForIdLocked(id);
6806            if (tr != null) {
6807                return tr.getTaskThumbnailsLocked();
6808            }
6809        }
6810        return null;
6811    }
6812
6813    @Override
6814    public Bitmap getTaskTopThumbnail(int id) {
6815        synchronized (this) {
6816            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6817                    "getTaskTopThumbnail()");
6818            TaskRecord tr = recentTaskForIdLocked(id);
6819            if (tr != null) {
6820                return tr.getTaskTopThumbnailLocked();
6821            }
6822        }
6823        return null;
6824    }
6825
6826    @Override
6827    public boolean removeSubTask(int taskId, int subTaskIndex) {
6828        synchronized (this) {
6829            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6830                    "removeSubTask()");
6831            long ident = Binder.clearCallingIdentity();
6832            try {
6833                TaskRecord tr = recentTaskForIdLocked(taskId);
6834                if (tr != null) {
6835                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6836                }
6837                return false;
6838            } finally {
6839                Binder.restoreCallingIdentity(ident);
6840            }
6841        }
6842    }
6843
6844    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6845        if (!pr.killedByAm) {
6846            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6847            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6848                    pr.processName, pr.setAdj, reason);
6849            pr.killedByAm = true;
6850            Process.killProcessQuiet(pr.pid);
6851        }
6852    }
6853
6854    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6855        tr.disposeThumbnail();
6856        mRecentTasks.remove(tr);
6857        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6858        Intent baseIntent = new Intent(
6859                tr.intent != null ? tr.intent : tr.affinityIntent);
6860        ComponentName component = baseIntent.getComponent();
6861        if (component == null) {
6862            Slog.w(TAG, "Now component for base intent of task: " + tr);
6863            return;
6864        }
6865
6866        // Find any running services associated with this app.
6867        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6868
6869        if (killProcesses) {
6870            // Find any running processes associated with this app.
6871            final String pkg = component.getPackageName();
6872            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6873            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6874            for (int i=0; i<pmap.size(); i++) {
6875                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6876                for (int j=0; j<uids.size(); j++) {
6877                    ProcessRecord proc = uids.valueAt(j);
6878                    if (proc.userId != tr.userId) {
6879                        continue;
6880                    }
6881                    if (!proc.pkgList.containsKey(pkg)) {
6882                        continue;
6883                    }
6884                    procs.add(proc);
6885                }
6886            }
6887
6888            // Kill the running processes.
6889            for (int i=0; i<procs.size(); i++) {
6890                ProcessRecord pr = procs.get(i);
6891                if (pr == mHomeProcess) {
6892                    // Don't kill the home process along with tasks from the same package.
6893                    continue;
6894                }
6895                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6896                    killUnneededProcessLocked(pr, "remove task");
6897                } else {
6898                    pr.waitingToKill = "remove task";
6899                }
6900            }
6901        }
6902    }
6903
6904    @Override
6905    public boolean removeTask(int taskId, int flags) {
6906        synchronized (this) {
6907            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6908                    "removeTask()");
6909            long ident = Binder.clearCallingIdentity();
6910            try {
6911                TaskRecord tr = recentTaskForIdLocked(taskId);
6912                if (tr != null) {
6913                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
6914                    if (r != null) {
6915                        cleanUpRemovedTaskLocked(tr, flags);
6916                        return true;
6917                    }
6918                    if (tr.mActivities.size() == 0) {
6919                        // Caller is just removing a recent task that is
6920                        // not actively running.  That is easy!
6921                        cleanUpRemovedTaskLocked(tr, flags);
6922                        return true;
6923                    }
6924                    Slog.w(TAG, "removeTask: task " + taskId
6925                            + " does not have activities to remove, "
6926                            + " but numActivities=" + tr.numActivities
6927                            + ": " + tr);
6928                }
6929            } finally {
6930                Binder.restoreCallingIdentity(ident);
6931            }
6932        }
6933        return false;
6934    }
6935
6936    /**
6937     * TODO: Add mController hook
6938     */
6939    @Override
6940    public void moveTaskToFront(int task, int flags, Bundle options) {
6941        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6942                "moveTaskToFront()");
6943
6944        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
6945        synchronized(this) {
6946            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6947                    Binder.getCallingUid(), "Task to front")) {
6948                ActivityOptions.abort(options);
6949                return;
6950            }
6951            final long origId = Binder.clearCallingIdentity();
6952            try {
6953                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
6954            } finally {
6955                Binder.restoreCallingIdentity(origId);
6956            }
6957            ActivityOptions.abort(options);
6958        }
6959    }
6960
6961    @Override
6962    public void moveTaskToBack(int taskId) {
6963        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6964                "moveTaskToBack()");
6965
6966        synchronized(this) {
6967            TaskRecord tr = recentTaskForIdLocked(taskId);
6968            if (tr != null) {
6969                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
6970                ActivityStack stack = tr.stack;
6971                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
6972                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6973                            Binder.getCallingUid(), "Task to back")) {
6974                        return;
6975                    }
6976                }
6977                final long origId = Binder.clearCallingIdentity();
6978                try {
6979                    stack.moveTaskToBackLocked(taskId, null);
6980                } finally {
6981                    Binder.restoreCallingIdentity(origId);
6982                }
6983            }
6984        }
6985    }
6986
6987    /**
6988     * Moves an activity, and all of the other activities within the same task, to the bottom
6989     * of the history stack.  The activity's order within the task is unchanged.
6990     *
6991     * @param token A reference to the activity we wish to move
6992     * @param nonRoot If false then this only works if the activity is the root
6993     *                of a task; if true it will work for any activity in a task.
6994     * @return Returns true if the move completed, false if not.
6995     */
6996    @Override
6997    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6998        enforceNotIsolatedCaller("moveActivityTaskToBack");
6999        synchronized(this) {
7000            final long origId = Binder.clearCallingIdentity();
7001            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7002            if (taskId >= 0) {
7003                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7004            }
7005            Binder.restoreCallingIdentity(origId);
7006        }
7007        return false;
7008    }
7009
7010    @Override
7011    public void moveTaskBackwards(int task) {
7012        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7013                "moveTaskBackwards()");
7014
7015        synchronized(this) {
7016            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7017                    Binder.getCallingUid(), "Task backwards")) {
7018                return;
7019            }
7020            final long origId = Binder.clearCallingIdentity();
7021            moveTaskBackwardsLocked(task);
7022            Binder.restoreCallingIdentity(origId);
7023        }
7024    }
7025
7026    private final void moveTaskBackwardsLocked(int task) {
7027        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7028    }
7029
7030    @Override
7031    public IBinder getHomeActivityToken() throws RemoteException {
7032        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7033                "getHomeActivityToken()");
7034        synchronized (this) {
7035            return mStackSupervisor.getHomeActivityToken();
7036        }
7037    }
7038
7039    @Override
7040    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7041            IActivityContainerCallback callback) throws RemoteException {
7042        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7043                "createActivityContainer()");
7044        synchronized (this) {
7045            if (parentActivityToken == null) {
7046                throw new IllegalArgumentException("parent token must not be null");
7047            }
7048            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7049            if (r == null) {
7050                return null;
7051            }
7052            if (callback == null) {
7053                throw new IllegalArgumentException("callback must not be null");
7054            }
7055            return mStackSupervisor.createActivityContainer(r, callback);
7056        }
7057    }
7058
7059    @Override
7060    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7061        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7062                "deleteActivityContainer()");
7063        synchronized (this) {
7064            mStackSupervisor.deleteActivityContainer(container);
7065        }
7066    }
7067
7068    @Override
7069    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7070            throws RemoteException {
7071        synchronized (this) {
7072            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7073            if (stack != null) {
7074                return stack.mActivityContainer;
7075            }
7076            return null;
7077        }
7078    }
7079
7080    @Override
7081    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7082        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7083                "moveTaskToStack()");
7084        if (stackId == HOME_STACK_ID) {
7085            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7086                    new RuntimeException("here").fillInStackTrace());
7087        }
7088        synchronized (this) {
7089            long ident = Binder.clearCallingIdentity();
7090            try {
7091                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7092                        + stackId + " toTop=" + toTop);
7093                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7094            } finally {
7095                Binder.restoreCallingIdentity(ident);
7096            }
7097        }
7098    }
7099
7100    @Override
7101    public void resizeStack(int stackBoxId, Rect bounds) {
7102        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7103                "resizeStackBox()");
7104        long ident = Binder.clearCallingIdentity();
7105        try {
7106            mWindowManager.resizeStack(stackBoxId, bounds);
7107        } finally {
7108            Binder.restoreCallingIdentity(ident);
7109        }
7110    }
7111
7112    @Override
7113    public List<StackInfo> getAllStackInfos() {
7114        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7115                "getAllStackInfos()");
7116        long ident = Binder.clearCallingIdentity();
7117        try {
7118            synchronized (this) {
7119                return mStackSupervisor.getAllStackInfosLocked();
7120            }
7121        } finally {
7122            Binder.restoreCallingIdentity(ident);
7123        }
7124    }
7125
7126    @Override
7127    public StackInfo getStackInfo(int stackId) {
7128        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7129                "getStackInfo()");
7130        long ident = Binder.clearCallingIdentity();
7131        try {
7132            synchronized (this) {
7133                return mStackSupervisor.getStackInfoLocked(stackId);
7134            }
7135        } finally {
7136            Binder.restoreCallingIdentity(ident);
7137        }
7138    }
7139
7140    @Override
7141    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7142        synchronized(this) {
7143            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7144        }
7145    }
7146
7147    // =========================================================
7148    // THUMBNAILS
7149    // =========================================================
7150
7151    public void reportThumbnail(IBinder token,
7152            Bitmap thumbnail, CharSequence description) {
7153        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7154        final long origId = Binder.clearCallingIdentity();
7155        sendPendingThumbnail(null, token, thumbnail, description, true);
7156        Binder.restoreCallingIdentity(origId);
7157    }
7158
7159    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7160            Bitmap thumbnail, CharSequence description, boolean always) {
7161        TaskRecord task;
7162        ArrayList<PendingThumbnailsRecord> receivers = null;
7163
7164        //System.out.println("Send pending thumbnail: " + r);
7165
7166        synchronized(this) {
7167            if (r == null) {
7168                r = ActivityRecord.isInStackLocked(token);
7169                if (r == null) {
7170                    return;
7171                }
7172            }
7173            if (thumbnail == null && r.thumbHolder != null) {
7174                thumbnail = r.thumbHolder.lastThumbnail;
7175                description = r.thumbHolder.lastDescription;
7176            }
7177            if (thumbnail == null && !always) {
7178                // If there is no thumbnail, and this entry is not actually
7179                // going away, then abort for now and pick up the next
7180                // thumbnail we get.
7181                return;
7182            }
7183            task = r.task;
7184
7185            int N = mPendingThumbnails.size();
7186            int i=0;
7187            while (i<N) {
7188                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7189                //System.out.println("Looking in " + pr.pendingRecords);
7190                if (pr.pendingRecords.remove(r)) {
7191                    if (receivers == null) {
7192                        receivers = new ArrayList<PendingThumbnailsRecord>();
7193                    }
7194                    receivers.add(pr);
7195                    if (pr.pendingRecords.size() == 0) {
7196                        pr.finished = true;
7197                        mPendingThumbnails.remove(i);
7198                        N--;
7199                        continue;
7200                    }
7201                }
7202                i++;
7203            }
7204        }
7205
7206        if (receivers != null) {
7207            final int N = receivers.size();
7208            for (int i=0; i<N; i++) {
7209                try {
7210                    PendingThumbnailsRecord pr = receivers.get(i);
7211                    pr.receiver.newThumbnail(
7212                        task != null ? task.taskId : -1, thumbnail, description);
7213                    if (pr.finished) {
7214                        pr.receiver.finished();
7215                    }
7216                } catch (Exception e) {
7217                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7218                }
7219            }
7220        }
7221    }
7222
7223    // =========================================================
7224    // CONTENT PROVIDERS
7225    // =========================================================
7226
7227    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7228        List<ProviderInfo> providers = null;
7229        try {
7230            providers = AppGlobals.getPackageManager().
7231                queryContentProviders(app.processName, app.uid,
7232                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7233        } catch (RemoteException ex) {
7234        }
7235        if (DEBUG_MU)
7236            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7237        int userId = app.userId;
7238        if (providers != null) {
7239            int N = providers.size();
7240            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7241            for (int i=0; i<N; i++) {
7242                ProviderInfo cpi =
7243                    (ProviderInfo)providers.get(i);
7244                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7245                        cpi.name, cpi.flags);
7246                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7247                    // This is a singleton provider, but a user besides the
7248                    // default user is asking to initialize a process it runs
7249                    // in...  well, no, it doesn't actually run in this process,
7250                    // it runs in the process of the default user.  Get rid of it.
7251                    providers.remove(i);
7252                    N--;
7253                    i--;
7254                    continue;
7255                }
7256
7257                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7258                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7259                if (cpr == null) {
7260                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7261                    mProviderMap.putProviderByClass(comp, cpr);
7262                }
7263                if (DEBUG_MU)
7264                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7265                app.pubProviders.put(cpi.name, cpr);
7266                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7267                    // Don't add this if it is a platform component that is marked
7268                    // to run in multiple processes, because this is actually
7269                    // part of the framework so doesn't make sense to track as a
7270                    // separate apk in the process.
7271                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7272                }
7273                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7274            }
7275        }
7276        return providers;
7277    }
7278
7279    /**
7280     * Check if {@link ProcessRecord} has a possible chance at accessing the
7281     * given {@link ProviderInfo}. Final permission checking is always done
7282     * in {@link ContentProvider}.
7283     */
7284    private final String checkContentProviderPermissionLocked(
7285            ProviderInfo cpi, ProcessRecord r) {
7286        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7287        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7288        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7289                cpi.applicationInfo.uid, cpi.exported)
7290                == PackageManager.PERMISSION_GRANTED) {
7291            return null;
7292        }
7293        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7294                cpi.applicationInfo.uid, cpi.exported)
7295                == PackageManager.PERMISSION_GRANTED) {
7296            return null;
7297        }
7298
7299        PathPermission[] pps = cpi.pathPermissions;
7300        if (pps != null) {
7301            int i = pps.length;
7302            while (i > 0) {
7303                i--;
7304                PathPermission pp = pps[i];
7305                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7306                        cpi.applicationInfo.uid, cpi.exported)
7307                        == PackageManager.PERMISSION_GRANTED) {
7308                    return null;
7309                }
7310                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7311                        cpi.applicationInfo.uid, cpi.exported)
7312                        == PackageManager.PERMISSION_GRANTED) {
7313                    return null;
7314                }
7315            }
7316        }
7317
7318        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7319        if (perms != null) {
7320            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7321                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7322                    return null;
7323                }
7324            }
7325        }
7326
7327        String msg;
7328        if (!cpi.exported) {
7329            msg = "Permission Denial: opening provider " + cpi.name
7330                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7331                    + ", uid=" + callingUid + ") that is not exported from uid "
7332                    + cpi.applicationInfo.uid;
7333        } else {
7334            msg = "Permission Denial: opening provider " + cpi.name
7335                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7336                    + ", uid=" + callingUid + ") requires "
7337                    + cpi.readPermission + " or " + cpi.writePermission;
7338        }
7339        Slog.w(TAG, msg);
7340        return msg;
7341    }
7342
7343    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7344            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7345        if (r != null) {
7346            for (int i=0; i<r.conProviders.size(); i++) {
7347                ContentProviderConnection conn = r.conProviders.get(i);
7348                if (conn.provider == cpr) {
7349                    if (DEBUG_PROVIDER) Slog.v(TAG,
7350                            "Adding provider requested by "
7351                            + r.processName + " from process "
7352                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7353                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7354                    if (stable) {
7355                        conn.stableCount++;
7356                        conn.numStableIncs++;
7357                    } else {
7358                        conn.unstableCount++;
7359                        conn.numUnstableIncs++;
7360                    }
7361                    return conn;
7362                }
7363            }
7364            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7365            if (stable) {
7366                conn.stableCount = 1;
7367                conn.numStableIncs = 1;
7368            } else {
7369                conn.unstableCount = 1;
7370                conn.numUnstableIncs = 1;
7371            }
7372            cpr.connections.add(conn);
7373            r.conProviders.add(conn);
7374            return conn;
7375        }
7376        cpr.addExternalProcessHandleLocked(externalProcessToken);
7377        return null;
7378    }
7379
7380    boolean decProviderCountLocked(ContentProviderConnection conn,
7381            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7382        if (conn != null) {
7383            cpr = conn.provider;
7384            if (DEBUG_PROVIDER) Slog.v(TAG,
7385                    "Removing provider requested by "
7386                    + conn.client.processName + " from process "
7387                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7388                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7389            if (stable) {
7390                conn.stableCount--;
7391            } else {
7392                conn.unstableCount--;
7393            }
7394            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7395                cpr.connections.remove(conn);
7396                conn.client.conProviders.remove(conn);
7397                return true;
7398            }
7399            return false;
7400        }
7401        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7402        return false;
7403    }
7404
7405    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7406            String name, IBinder token, boolean stable, int userId) {
7407        ContentProviderRecord cpr;
7408        ContentProviderConnection conn = null;
7409        ProviderInfo cpi = null;
7410
7411        synchronized(this) {
7412            ProcessRecord r = null;
7413            if (caller != null) {
7414                r = getRecordForAppLocked(caller);
7415                if (r == null) {
7416                    throw new SecurityException(
7417                            "Unable to find app for caller " + caller
7418                          + " (pid=" + Binder.getCallingPid()
7419                          + ") when getting content provider " + name);
7420                }
7421            }
7422
7423            // First check if this content provider has been published...
7424            cpr = mProviderMap.getProviderByName(name, userId);
7425            boolean providerRunning = cpr != null;
7426            if (providerRunning) {
7427                cpi = cpr.info;
7428                String msg;
7429                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7430                    throw new SecurityException(msg);
7431                }
7432
7433                if (r != null && cpr.canRunHere(r)) {
7434                    // This provider has been published or is in the process
7435                    // of being published...  but it is also allowed to run
7436                    // in the caller's process, so don't make a connection
7437                    // and just let the caller instantiate its own instance.
7438                    ContentProviderHolder holder = cpr.newHolder(null);
7439                    // don't give caller the provider object, it needs
7440                    // to make its own.
7441                    holder.provider = null;
7442                    return holder;
7443                }
7444
7445                final long origId = Binder.clearCallingIdentity();
7446
7447                // In this case the provider instance already exists, so we can
7448                // return it right away.
7449                conn = incProviderCountLocked(r, cpr, token, stable);
7450                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7451                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7452                        // If this is a perceptible app accessing the provider,
7453                        // make sure to count it as being accessed and thus
7454                        // back up on the LRU list.  This is good because
7455                        // content providers are often expensive to start.
7456                        updateLruProcessLocked(cpr.proc, false, null);
7457                    }
7458                }
7459
7460                if (cpr.proc != null) {
7461                    if (false) {
7462                        if (cpr.name.flattenToShortString().equals(
7463                                "com.android.providers.calendar/.CalendarProvider2")) {
7464                            Slog.v(TAG, "****************** KILLING "
7465                                + cpr.name.flattenToShortString());
7466                            Process.killProcess(cpr.proc.pid);
7467                        }
7468                    }
7469                    boolean success = updateOomAdjLocked(cpr.proc);
7470                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7471                    // NOTE: there is still a race here where a signal could be
7472                    // pending on the process even though we managed to update its
7473                    // adj level.  Not sure what to do about this, but at least
7474                    // the race is now smaller.
7475                    if (!success) {
7476                        // Uh oh...  it looks like the provider's process
7477                        // has been killed on us.  We need to wait for a new
7478                        // process to be started, and make sure its death
7479                        // doesn't kill our process.
7480                        Slog.i(TAG,
7481                                "Existing provider " + cpr.name.flattenToShortString()
7482                                + " is crashing; detaching " + r);
7483                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7484                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7485                        if (!lastRef) {
7486                            // This wasn't the last ref our process had on
7487                            // the provider...  we have now been killed, bail.
7488                            return null;
7489                        }
7490                        providerRunning = false;
7491                        conn = null;
7492                    }
7493                }
7494
7495                Binder.restoreCallingIdentity(origId);
7496            }
7497
7498            boolean singleton;
7499            if (!providerRunning) {
7500                try {
7501                    cpi = AppGlobals.getPackageManager().
7502                        resolveContentProvider(name,
7503                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7504                } catch (RemoteException ex) {
7505                }
7506                if (cpi == null) {
7507                    return null;
7508                }
7509                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7510                        cpi.name, cpi.flags);
7511                if (singleton) {
7512                    userId = 0;
7513                }
7514                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7515
7516                String msg;
7517                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7518                    throw new SecurityException(msg);
7519                }
7520
7521                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7522                        && !cpi.processName.equals("system")) {
7523                    // If this content provider does not run in the system
7524                    // process, and the system is not yet ready to run other
7525                    // processes, then fail fast instead of hanging.
7526                    throw new IllegalArgumentException(
7527                            "Attempt to launch content provider before system ready");
7528                }
7529
7530                // Make sure that the user who owns this provider is started.  If not,
7531                // we don't want to allow it to run.
7532                if (mStartedUsers.get(userId) == null) {
7533                    Slog.w(TAG, "Unable to launch app "
7534                            + cpi.applicationInfo.packageName + "/"
7535                            + cpi.applicationInfo.uid + " for provider "
7536                            + name + ": user " + userId + " is stopped");
7537                    return null;
7538                }
7539
7540                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7541                cpr = mProviderMap.getProviderByClass(comp, userId);
7542                final boolean firstClass = cpr == null;
7543                if (firstClass) {
7544                    try {
7545                        ApplicationInfo ai =
7546                            AppGlobals.getPackageManager().
7547                                getApplicationInfo(
7548                                        cpi.applicationInfo.packageName,
7549                                        STOCK_PM_FLAGS, userId);
7550                        if (ai == null) {
7551                            Slog.w(TAG, "No package info for content provider "
7552                                    + cpi.name);
7553                            return null;
7554                        }
7555                        ai = getAppInfoForUser(ai, userId);
7556                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7557                    } catch (RemoteException ex) {
7558                        // pm is in same process, this will never happen.
7559                    }
7560                }
7561
7562                if (r != null && cpr.canRunHere(r)) {
7563                    // If this is a multiprocess provider, then just return its
7564                    // info and allow the caller to instantiate it.  Only do
7565                    // this if the provider is the same user as the caller's
7566                    // process, or can run as root (so can be in any process).
7567                    return cpr.newHolder(null);
7568                }
7569
7570                if (DEBUG_PROVIDER) {
7571                    RuntimeException e = new RuntimeException("here");
7572                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7573                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7574                }
7575
7576                // This is single process, and our app is now connecting to it.
7577                // See if we are already in the process of launching this
7578                // provider.
7579                final int N = mLaunchingProviders.size();
7580                int i;
7581                for (i=0; i<N; i++) {
7582                    if (mLaunchingProviders.get(i) == cpr) {
7583                        break;
7584                    }
7585                }
7586
7587                // If the provider is not already being launched, then get it
7588                // started.
7589                if (i >= N) {
7590                    final long origId = Binder.clearCallingIdentity();
7591
7592                    try {
7593                        // Content provider is now in use, its package can't be stopped.
7594                        try {
7595                            AppGlobals.getPackageManager().setPackageStoppedState(
7596                                    cpr.appInfo.packageName, false, userId);
7597                        } catch (RemoteException e) {
7598                        } catch (IllegalArgumentException e) {
7599                            Slog.w(TAG, "Failed trying to unstop package "
7600                                    + cpr.appInfo.packageName + ": " + e);
7601                        }
7602
7603                        // Use existing process if already started
7604                        ProcessRecord proc = getProcessRecordLocked(
7605                                cpi.processName, cpr.appInfo.uid, false);
7606                        if (proc != null && proc.thread != null) {
7607                            if (DEBUG_PROVIDER) {
7608                                Slog.d(TAG, "Installing in existing process " + proc);
7609                            }
7610                            proc.pubProviders.put(cpi.name, cpr);
7611                            try {
7612                                proc.thread.scheduleInstallProvider(cpi);
7613                            } catch (RemoteException e) {
7614                            }
7615                        } else {
7616                            proc = startProcessLocked(cpi.processName,
7617                                    cpr.appInfo, false, 0, "content provider",
7618                                    new ComponentName(cpi.applicationInfo.packageName,
7619                                            cpi.name), false, false, false);
7620                            if (proc == null) {
7621                                Slog.w(TAG, "Unable to launch app "
7622                                        + cpi.applicationInfo.packageName + "/"
7623                                        + cpi.applicationInfo.uid + " for provider "
7624                                        + name + ": process is bad");
7625                                return null;
7626                            }
7627                        }
7628                        cpr.launchingApp = proc;
7629                        mLaunchingProviders.add(cpr);
7630                    } finally {
7631                        Binder.restoreCallingIdentity(origId);
7632                    }
7633                }
7634
7635                // Make sure the provider is published (the same provider class
7636                // may be published under multiple names).
7637                if (firstClass) {
7638                    mProviderMap.putProviderByClass(comp, cpr);
7639                }
7640
7641                mProviderMap.putProviderByName(name, cpr);
7642                conn = incProviderCountLocked(r, cpr, token, stable);
7643                if (conn != null) {
7644                    conn.waiting = true;
7645                }
7646            }
7647        }
7648
7649        // Wait for the provider to be published...
7650        synchronized (cpr) {
7651            while (cpr.provider == null) {
7652                if (cpr.launchingApp == null) {
7653                    Slog.w(TAG, "Unable to launch app "
7654                            + cpi.applicationInfo.packageName + "/"
7655                            + cpi.applicationInfo.uid + " for provider "
7656                            + name + ": launching app became null");
7657                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7658                            UserHandle.getUserId(cpi.applicationInfo.uid),
7659                            cpi.applicationInfo.packageName,
7660                            cpi.applicationInfo.uid, name);
7661                    return null;
7662                }
7663                try {
7664                    if (DEBUG_MU) {
7665                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7666                                + cpr.launchingApp);
7667                    }
7668                    if (conn != null) {
7669                        conn.waiting = true;
7670                    }
7671                    cpr.wait();
7672                } catch (InterruptedException ex) {
7673                } finally {
7674                    if (conn != null) {
7675                        conn.waiting = false;
7676                    }
7677                }
7678            }
7679        }
7680        return cpr != null ? cpr.newHolder(conn) : null;
7681    }
7682
7683    public final ContentProviderHolder getContentProvider(
7684            IApplicationThread caller, String name, int userId, boolean stable) {
7685        enforceNotIsolatedCaller("getContentProvider");
7686        if (caller == null) {
7687            String msg = "null IApplicationThread when getting content provider "
7688                    + name;
7689            Slog.w(TAG, msg);
7690            throw new SecurityException(msg);
7691        }
7692
7693        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7694                false, true, "getContentProvider", null);
7695        return getContentProviderImpl(caller, name, null, stable, userId);
7696    }
7697
7698    public ContentProviderHolder getContentProviderExternal(
7699            String name, int userId, IBinder token) {
7700        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7701            "Do not have permission in call getContentProviderExternal()");
7702        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7703                false, true, "getContentProvider", null);
7704        return getContentProviderExternalUnchecked(name, token, userId);
7705    }
7706
7707    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7708            IBinder token, int userId) {
7709        return getContentProviderImpl(null, name, token, true, userId);
7710    }
7711
7712    /**
7713     * Drop a content provider from a ProcessRecord's bookkeeping
7714     */
7715    public void removeContentProvider(IBinder connection, boolean stable) {
7716        enforceNotIsolatedCaller("removeContentProvider");
7717        synchronized (this) {
7718            ContentProviderConnection conn;
7719            try {
7720                conn = (ContentProviderConnection)connection;
7721            } catch (ClassCastException e) {
7722                String msg ="removeContentProvider: " + connection
7723                        + " not a ContentProviderConnection";
7724                Slog.w(TAG, msg);
7725                throw new IllegalArgumentException(msg);
7726            }
7727            if (conn == null) {
7728                throw new NullPointerException("connection is null");
7729            }
7730            if (decProviderCountLocked(conn, null, null, stable)) {
7731                updateOomAdjLocked();
7732            }
7733        }
7734    }
7735
7736    public void removeContentProviderExternal(String name, IBinder token) {
7737        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7738            "Do not have permission in call removeContentProviderExternal()");
7739        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7740    }
7741
7742    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7743        synchronized (this) {
7744            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7745            if(cpr == null) {
7746                //remove from mProvidersByClass
7747                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7748                return;
7749            }
7750
7751            //update content provider record entry info
7752            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7753            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7754            if (localCpr.hasExternalProcessHandles()) {
7755                if (localCpr.removeExternalProcessHandleLocked(token)) {
7756                    updateOomAdjLocked();
7757                } else {
7758                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7759                            + " with no external reference for token: "
7760                            + token + ".");
7761                }
7762            } else {
7763                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7764                        + " with no external references.");
7765            }
7766        }
7767    }
7768
7769    public final void publishContentProviders(IApplicationThread caller,
7770            List<ContentProviderHolder> providers) {
7771        if (providers == null) {
7772            return;
7773        }
7774
7775        enforceNotIsolatedCaller("publishContentProviders");
7776        synchronized (this) {
7777            final ProcessRecord r = getRecordForAppLocked(caller);
7778            if (DEBUG_MU)
7779                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7780            if (r == null) {
7781                throw new SecurityException(
7782                        "Unable to find app for caller " + caller
7783                      + " (pid=" + Binder.getCallingPid()
7784                      + ") when publishing content providers");
7785            }
7786
7787            final long origId = Binder.clearCallingIdentity();
7788
7789            final int N = providers.size();
7790            for (int i=0; i<N; i++) {
7791                ContentProviderHolder src = providers.get(i);
7792                if (src == null || src.info == null || src.provider == null) {
7793                    continue;
7794                }
7795                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7796                if (DEBUG_MU)
7797                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7798                if (dst != null) {
7799                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7800                    mProviderMap.putProviderByClass(comp, dst);
7801                    String names[] = dst.info.authority.split(";");
7802                    for (int j = 0; j < names.length; j++) {
7803                        mProviderMap.putProviderByName(names[j], dst);
7804                    }
7805
7806                    int NL = mLaunchingProviders.size();
7807                    int j;
7808                    for (j=0; j<NL; j++) {
7809                        if (mLaunchingProviders.get(j) == dst) {
7810                            mLaunchingProviders.remove(j);
7811                            j--;
7812                            NL--;
7813                        }
7814                    }
7815                    synchronized (dst) {
7816                        dst.provider = src.provider;
7817                        dst.proc = r;
7818                        dst.notifyAll();
7819                    }
7820                    updateOomAdjLocked(r);
7821                }
7822            }
7823
7824            Binder.restoreCallingIdentity(origId);
7825        }
7826    }
7827
7828    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7829        ContentProviderConnection conn;
7830        try {
7831            conn = (ContentProviderConnection)connection;
7832        } catch (ClassCastException e) {
7833            String msg ="refContentProvider: " + connection
7834                    + " not a ContentProviderConnection";
7835            Slog.w(TAG, msg);
7836            throw new IllegalArgumentException(msg);
7837        }
7838        if (conn == null) {
7839            throw new NullPointerException("connection is null");
7840        }
7841
7842        synchronized (this) {
7843            if (stable > 0) {
7844                conn.numStableIncs += stable;
7845            }
7846            stable = conn.stableCount + stable;
7847            if (stable < 0) {
7848                throw new IllegalStateException("stableCount < 0: " + stable);
7849            }
7850
7851            if (unstable > 0) {
7852                conn.numUnstableIncs += unstable;
7853            }
7854            unstable = conn.unstableCount + unstable;
7855            if (unstable < 0) {
7856                throw new IllegalStateException("unstableCount < 0: " + unstable);
7857            }
7858
7859            if ((stable+unstable) <= 0) {
7860                throw new IllegalStateException("ref counts can't go to zero here: stable="
7861                        + stable + " unstable=" + unstable);
7862            }
7863            conn.stableCount = stable;
7864            conn.unstableCount = unstable;
7865            return !conn.dead;
7866        }
7867    }
7868
7869    public void unstableProviderDied(IBinder connection) {
7870        ContentProviderConnection conn;
7871        try {
7872            conn = (ContentProviderConnection)connection;
7873        } catch (ClassCastException e) {
7874            String msg ="refContentProvider: " + connection
7875                    + " not a ContentProviderConnection";
7876            Slog.w(TAG, msg);
7877            throw new IllegalArgumentException(msg);
7878        }
7879        if (conn == null) {
7880            throw new NullPointerException("connection is null");
7881        }
7882
7883        // Safely retrieve the content provider associated with the connection.
7884        IContentProvider provider;
7885        synchronized (this) {
7886            provider = conn.provider.provider;
7887        }
7888
7889        if (provider == null) {
7890            // Um, yeah, we're way ahead of you.
7891            return;
7892        }
7893
7894        // Make sure the caller is being honest with us.
7895        if (provider.asBinder().pingBinder()) {
7896            // Er, no, still looks good to us.
7897            synchronized (this) {
7898                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7899                        + " says " + conn + " died, but we don't agree");
7900                return;
7901            }
7902        }
7903
7904        // Well look at that!  It's dead!
7905        synchronized (this) {
7906            if (conn.provider.provider != provider) {
7907                // But something changed...  good enough.
7908                return;
7909            }
7910
7911            ProcessRecord proc = conn.provider.proc;
7912            if (proc == null || proc.thread == null) {
7913                // Seems like the process is already cleaned up.
7914                return;
7915            }
7916
7917            // As far as we're concerned, this is just like receiving a
7918            // death notification...  just a bit prematurely.
7919            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
7920                    + ") early provider death");
7921            final long ident = Binder.clearCallingIdentity();
7922            try {
7923                appDiedLocked(proc, proc.pid, proc.thread);
7924            } finally {
7925                Binder.restoreCallingIdentity(ident);
7926            }
7927        }
7928    }
7929
7930    @Override
7931    public void appNotRespondingViaProvider(IBinder connection) {
7932        enforceCallingPermission(
7933                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
7934
7935        final ContentProviderConnection conn = (ContentProviderConnection) connection;
7936        if (conn == null) {
7937            Slog.w(TAG, "ContentProviderConnection is null");
7938            return;
7939        }
7940
7941        final ProcessRecord host = conn.provider.proc;
7942        if (host == null) {
7943            Slog.w(TAG, "Failed to find hosting ProcessRecord");
7944            return;
7945        }
7946
7947        final long token = Binder.clearCallingIdentity();
7948        try {
7949            appNotResponding(host, null, null, false, "ContentProvider not responding");
7950        } finally {
7951            Binder.restoreCallingIdentity(token);
7952        }
7953    }
7954
7955    public final void installSystemProviders() {
7956        List<ProviderInfo> providers;
7957        synchronized (this) {
7958            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
7959            providers = generateApplicationProvidersLocked(app);
7960            if (providers != null) {
7961                for (int i=providers.size()-1; i>=0; i--) {
7962                    ProviderInfo pi = (ProviderInfo)providers.get(i);
7963                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7964                        Slog.w(TAG, "Not installing system proc provider " + pi.name
7965                                + ": not system .apk");
7966                        providers.remove(i);
7967                    }
7968                }
7969            }
7970        }
7971        if (providers != null) {
7972            mSystemThread.installSystemProviders(providers);
7973        }
7974
7975        mCoreSettingsObserver = new CoreSettingsObserver(this);
7976
7977        mUsageStatsService.monitorPackages();
7978    }
7979
7980    /**
7981     * Allows app to retrieve the MIME type of a URI without having permission
7982     * to access its content provider.
7983     *
7984     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
7985     *
7986     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
7987     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
7988     */
7989    public String getProviderMimeType(Uri uri, int userId) {
7990        enforceNotIsolatedCaller("getProviderMimeType");
7991        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7992                userId, false, true, "getProviderMimeType", null);
7993        final String name = uri.getAuthority();
7994        final long ident = Binder.clearCallingIdentity();
7995        ContentProviderHolder holder = null;
7996
7997        try {
7998            holder = getContentProviderExternalUnchecked(name, null, userId);
7999            if (holder != null) {
8000                return holder.provider.getType(uri);
8001            }
8002        } catch (RemoteException e) {
8003            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8004            return null;
8005        } finally {
8006            if (holder != null) {
8007                removeContentProviderExternalUnchecked(name, null, userId);
8008            }
8009            Binder.restoreCallingIdentity(ident);
8010        }
8011
8012        return null;
8013    }
8014
8015    // =========================================================
8016    // GLOBAL MANAGEMENT
8017    // =========================================================
8018
8019    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8020            boolean isolated) {
8021        String proc = customProcess != null ? customProcess : info.processName;
8022        BatteryStatsImpl.Uid.Proc ps = null;
8023        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8024        int uid = info.uid;
8025        if (isolated) {
8026            int userId = UserHandle.getUserId(uid);
8027            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8028            while (true) {
8029                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8030                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8031                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8032                }
8033                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8034                mNextIsolatedProcessUid++;
8035                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8036                    // No process for this uid, use it.
8037                    break;
8038                }
8039                stepsLeft--;
8040                if (stepsLeft <= 0) {
8041                    return null;
8042                }
8043            }
8044        }
8045        return new ProcessRecord(stats, info, proc, uid);
8046    }
8047
8048    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8049        ProcessRecord app;
8050        if (!isolated) {
8051            app = getProcessRecordLocked(info.processName, info.uid, true);
8052        } else {
8053            app = null;
8054        }
8055
8056        if (app == null) {
8057            app = newProcessRecordLocked(info, null, isolated);
8058            mProcessNames.put(info.processName, app.uid, app);
8059            if (isolated) {
8060                mIsolatedProcesses.put(app.uid, app);
8061            }
8062            updateLruProcessLocked(app, false, null);
8063            updateOomAdjLocked();
8064        }
8065
8066        // This package really, really can not be stopped.
8067        try {
8068            AppGlobals.getPackageManager().setPackageStoppedState(
8069                    info.packageName, false, UserHandle.getUserId(app.uid));
8070        } catch (RemoteException e) {
8071        } catch (IllegalArgumentException e) {
8072            Slog.w(TAG, "Failed trying to unstop package "
8073                    + info.packageName + ": " + e);
8074        }
8075
8076        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8077                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8078            app.persistent = true;
8079            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8080        }
8081        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8082            mPersistentStartingProcesses.add(app);
8083            startProcessLocked(app, "added application", app.processName);
8084        }
8085
8086        return app;
8087    }
8088
8089    public void unhandledBack() {
8090        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8091                "unhandledBack()");
8092
8093        synchronized(this) {
8094            final long origId = Binder.clearCallingIdentity();
8095            try {
8096                getFocusedStack().unhandledBackLocked();
8097            } finally {
8098                Binder.restoreCallingIdentity(origId);
8099            }
8100        }
8101    }
8102
8103    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8104        enforceNotIsolatedCaller("openContentUri");
8105        final int userId = UserHandle.getCallingUserId();
8106        String name = uri.getAuthority();
8107        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8108        ParcelFileDescriptor pfd = null;
8109        if (cph != null) {
8110            // We record the binder invoker's uid in thread-local storage before
8111            // going to the content provider to open the file.  Later, in the code
8112            // that handles all permissions checks, we look for this uid and use
8113            // that rather than the Activity Manager's own uid.  The effect is that
8114            // we do the check against the caller's permissions even though it looks
8115            // to the content provider like the Activity Manager itself is making
8116            // the request.
8117            sCallerIdentity.set(new Identity(
8118                    Binder.getCallingPid(), Binder.getCallingUid()));
8119            try {
8120                pfd = cph.provider.openFile(null, uri, "r", null);
8121            } catch (FileNotFoundException e) {
8122                // do nothing; pfd will be returned null
8123            } finally {
8124                // Ensure that whatever happens, we clean up the identity state
8125                sCallerIdentity.remove();
8126            }
8127
8128            // We've got the fd now, so we're done with the provider.
8129            removeContentProviderExternalUnchecked(name, null, userId);
8130        } else {
8131            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8132        }
8133        return pfd;
8134    }
8135
8136    // Actually is sleeping or shutting down or whatever else in the future
8137    // is an inactive state.
8138    public boolean isSleepingOrShuttingDown() {
8139        return mSleeping || mShuttingDown;
8140    }
8141
8142    void goingToSleep() {
8143        synchronized(this) {
8144            mWentToSleep = true;
8145            updateEventDispatchingLocked();
8146
8147            if (!mSleeping) {
8148                mSleeping = true;
8149                mStackSupervisor.goingToSleepLocked();
8150
8151                // Initialize the wake times of all processes.
8152                checkExcessivePowerUsageLocked(false);
8153                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8154                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8155                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8156            }
8157        }
8158    }
8159
8160    @Override
8161    public boolean shutdown(int timeout) {
8162        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8163                != PackageManager.PERMISSION_GRANTED) {
8164            throw new SecurityException("Requires permission "
8165                    + android.Manifest.permission.SHUTDOWN);
8166        }
8167
8168        boolean timedout = false;
8169
8170        synchronized(this) {
8171            mShuttingDown = true;
8172            updateEventDispatchingLocked();
8173            timedout = mStackSupervisor.shutdownLocked(timeout);
8174        }
8175
8176        mAppOpsService.shutdown();
8177        mUsageStatsService.shutdown();
8178        mBatteryStatsService.shutdown();
8179        synchronized (this) {
8180            mProcessStats.shutdownLocked();
8181        }
8182
8183        return timedout;
8184    }
8185
8186    public final void activitySlept(IBinder token) {
8187        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8188
8189        final long origId = Binder.clearCallingIdentity();
8190
8191        synchronized (this) {
8192            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8193            if (r != null) {
8194                mStackSupervisor.activitySleptLocked(r);
8195            }
8196        }
8197
8198        Binder.restoreCallingIdentity(origId);
8199    }
8200
8201    void logLockScreen(String msg) {
8202        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8203                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8204                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8205                mStackSupervisor.mDismissKeyguardOnNextActivity);
8206    }
8207
8208    private void comeOutOfSleepIfNeededLocked() {
8209        if (!mWentToSleep && !mLockScreenShown) {
8210            if (mSleeping) {
8211                mSleeping = false;
8212                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8213            }
8214        }
8215    }
8216
8217    void wakingUp() {
8218        synchronized(this) {
8219            mWentToSleep = false;
8220            updateEventDispatchingLocked();
8221            comeOutOfSleepIfNeededLocked();
8222        }
8223    }
8224
8225    private void updateEventDispatchingLocked() {
8226        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8227    }
8228
8229    public void setLockScreenShown(boolean shown) {
8230        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8231                != PackageManager.PERMISSION_GRANTED) {
8232            throw new SecurityException("Requires permission "
8233                    + android.Manifest.permission.DEVICE_POWER);
8234        }
8235
8236        synchronized(this) {
8237            long ident = Binder.clearCallingIdentity();
8238            try {
8239                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8240                mLockScreenShown = shown;
8241                comeOutOfSleepIfNeededLocked();
8242            } finally {
8243                Binder.restoreCallingIdentity(ident);
8244            }
8245        }
8246    }
8247
8248    @Override
8249    public void stopAppSwitches() {
8250        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8251                != PackageManager.PERMISSION_GRANTED) {
8252            throw new SecurityException("Requires permission "
8253                    + android.Manifest.permission.STOP_APP_SWITCHES);
8254        }
8255
8256        synchronized(this) {
8257            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8258                    + APP_SWITCH_DELAY_TIME;
8259            mDidAppSwitch = false;
8260            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8261            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8262            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8263        }
8264    }
8265
8266    public void resumeAppSwitches() {
8267        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8268                != PackageManager.PERMISSION_GRANTED) {
8269            throw new SecurityException("Requires permission "
8270                    + android.Manifest.permission.STOP_APP_SWITCHES);
8271        }
8272
8273        synchronized(this) {
8274            // Note that we don't execute any pending app switches... we will
8275            // let those wait until either the timeout, or the next start
8276            // activity request.
8277            mAppSwitchesAllowedTime = 0;
8278        }
8279    }
8280
8281    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8282            String name) {
8283        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8284            return true;
8285        }
8286
8287        final int perm = checkComponentPermission(
8288                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8289                callingUid, -1, true);
8290        if (perm == PackageManager.PERMISSION_GRANTED) {
8291            return true;
8292        }
8293
8294        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8295        return false;
8296    }
8297
8298    public void setDebugApp(String packageName, boolean waitForDebugger,
8299            boolean persistent) {
8300        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8301                "setDebugApp()");
8302
8303        long ident = Binder.clearCallingIdentity();
8304        try {
8305            // Note that this is not really thread safe if there are multiple
8306            // callers into it at the same time, but that's not a situation we
8307            // care about.
8308            if (persistent) {
8309                final ContentResolver resolver = mContext.getContentResolver();
8310                Settings.Global.putString(
8311                    resolver, Settings.Global.DEBUG_APP,
8312                    packageName);
8313                Settings.Global.putInt(
8314                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8315                    waitForDebugger ? 1 : 0);
8316            }
8317
8318            synchronized (this) {
8319                if (!persistent) {
8320                    mOrigDebugApp = mDebugApp;
8321                    mOrigWaitForDebugger = mWaitForDebugger;
8322                }
8323                mDebugApp = packageName;
8324                mWaitForDebugger = waitForDebugger;
8325                mDebugTransient = !persistent;
8326                if (packageName != null) {
8327                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8328                            UserHandle.USER_ALL, "set debug app");
8329                }
8330            }
8331        } finally {
8332            Binder.restoreCallingIdentity(ident);
8333        }
8334    }
8335
8336    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8337        synchronized (this) {
8338            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8339            if (!isDebuggable) {
8340                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8341                    throw new SecurityException("Process not debuggable: " + app.packageName);
8342                }
8343            }
8344
8345            mOpenGlTraceApp = processName;
8346        }
8347    }
8348
8349    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8350            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8351        synchronized (this) {
8352            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8353            if (!isDebuggable) {
8354                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8355                    throw new SecurityException("Process not debuggable: " + app.packageName);
8356                }
8357            }
8358            mProfileApp = processName;
8359            mProfileFile = profileFile;
8360            if (mProfileFd != null) {
8361                try {
8362                    mProfileFd.close();
8363                } catch (IOException e) {
8364                }
8365                mProfileFd = null;
8366            }
8367            mProfileFd = profileFd;
8368            mProfileType = 0;
8369            mAutoStopProfiler = autoStopProfiler;
8370        }
8371    }
8372
8373    @Override
8374    public void setAlwaysFinish(boolean enabled) {
8375        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8376                "setAlwaysFinish()");
8377
8378        Settings.Global.putInt(
8379                mContext.getContentResolver(),
8380                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8381
8382        synchronized (this) {
8383            mAlwaysFinishActivities = enabled;
8384        }
8385    }
8386
8387    @Override
8388    public void setActivityController(IActivityController controller) {
8389        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8390                "setActivityController()");
8391        synchronized (this) {
8392            mController = controller;
8393            Watchdog.getInstance().setActivityController(controller);
8394        }
8395    }
8396
8397    @Override
8398    public void setUserIsMonkey(boolean userIsMonkey) {
8399        synchronized (this) {
8400            synchronized (mPidsSelfLocked) {
8401                final int callingPid = Binder.getCallingPid();
8402                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8403                if (precessRecord == null) {
8404                    throw new SecurityException("Unknown process: " + callingPid);
8405                }
8406                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8407                    throw new SecurityException("Only an instrumentation process "
8408                            + "with a UiAutomation can call setUserIsMonkey");
8409                }
8410            }
8411            mUserIsMonkey = userIsMonkey;
8412        }
8413    }
8414
8415    @Override
8416    public boolean isUserAMonkey() {
8417        synchronized (this) {
8418            // If there is a controller also implies the user is a monkey.
8419            return (mUserIsMonkey || mController != null);
8420        }
8421    }
8422
8423    public void requestBugReport() {
8424        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8425        SystemProperties.set("ctl.start", "bugreport");
8426    }
8427
8428    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8429        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8430    }
8431
8432    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8433        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8434            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8435        }
8436        return KEY_DISPATCHING_TIMEOUT;
8437    }
8438
8439    @Override
8440    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8441        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8442                != PackageManager.PERMISSION_GRANTED) {
8443            throw new SecurityException("Requires permission "
8444                    + android.Manifest.permission.FILTER_EVENTS);
8445        }
8446        ProcessRecord proc;
8447        long timeout;
8448        synchronized (this) {
8449            synchronized (mPidsSelfLocked) {
8450                proc = mPidsSelfLocked.get(pid);
8451            }
8452            timeout = getInputDispatchingTimeoutLocked(proc);
8453        }
8454
8455        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8456            return -1;
8457        }
8458
8459        return timeout;
8460    }
8461
8462    /**
8463     * Handle input dispatching timeouts.
8464     * Returns whether input dispatching should be aborted or not.
8465     */
8466    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8467            final ActivityRecord activity, final ActivityRecord parent,
8468            final boolean aboveSystem, String reason) {
8469        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8470                != PackageManager.PERMISSION_GRANTED) {
8471            throw new SecurityException("Requires permission "
8472                    + android.Manifest.permission.FILTER_EVENTS);
8473        }
8474
8475        final String annotation;
8476        if (reason == null) {
8477            annotation = "Input dispatching timed out";
8478        } else {
8479            annotation = "Input dispatching timed out (" + reason + ")";
8480        }
8481
8482        if (proc != null) {
8483            synchronized (this) {
8484                if (proc.debugging) {
8485                    return false;
8486                }
8487
8488                if (mDidDexOpt) {
8489                    // Give more time since we were dexopting.
8490                    mDidDexOpt = false;
8491                    return false;
8492                }
8493
8494                if (proc.instrumentationClass != null) {
8495                    Bundle info = new Bundle();
8496                    info.putString("shortMsg", "keyDispatchingTimedOut");
8497                    info.putString("longMsg", annotation);
8498                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8499                    return true;
8500                }
8501            }
8502            mHandler.post(new Runnable() {
8503                @Override
8504                public void run() {
8505                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8506                }
8507            });
8508        }
8509
8510        return true;
8511    }
8512
8513    public Bundle getAssistContextExtras(int requestType) {
8514        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8515                "getAssistContextExtras()");
8516        PendingAssistExtras pae;
8517        Bundle extras = new Bundle();
8518        synchronized (this) {
8519            ActivityRecord activity = getFocusedStack().mResumedActivity;
8520            if (activity == null) {
8521                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8522                return null;
8523            }
8524            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8525            if (activity.app == null || activity.app.thread == null) {
8526                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8527                return extras;
8528            }
8529            if (activity.app.pid == Binder.getCallingPid()) {
8530                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8531                return extras;
8532            }
8533            pae = new PendingAssistExtras(activity);
8534            try {
8535                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8536                        requestType);
8537                mPendingAssistExtras.add(pae);
8538                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8539            } catch (RemoteException e) {
8540                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8541                return extras;
8542            }
8543        }
8544        synchronized (pae) {
8545            while (!pae.haveResult) {
8546                try {
8547                    pae.wait();
8548                } catch (InterruptedException e) {
8549                }
8550            }
8551            if (pae.result != null) {
8552                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8553            }
8554        }
8555        synchronized (this) {
8556            mPendingAssistExtras.remove(pae);
8557            mHandler.removeCallbacks(pae);
8558        }
8559        return extras;
8560    }
8561
8562    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8563        PendingAssistExtras pae = (PendingAssistExtras)token;
8564        synchronized (pae) {
8565            pae.result = extras;
8566            pae.haveResult = true;
8567            pae.notifyAll();
8568        }
8569    }
8570
8571    public void registerProcessObserver(IProcessObserver observer) {
8572        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8573                "registerProcessObserver()");
8574        synchronized (this) {
8575            mProcessObservers.register(observer);
8576        }
8577    }
8578
8579    @Override
8580    public void unregisterProcessObserver(IProcessObserver observer) {
8581        synchronized (this) {
8582            mProcessObservers.unregister(observer);
8583        }
8584    }
8585
8586    @Override
8587    public boolean convertFromTranslucent(IBinder token) {
8588        final long origId = Binder.clearCallingIdentity();
8589        try {
8590            synchronized (this) {
8591                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8592                if (r == null) {
8593                    return false;
8594                }
8595                if (r.changeWindowTranslucency(true)) {
8596                    mWindowManager.setAppFullscreen(token, true);
8597                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8598                    return true;
8599                }
8600                return false;
8601            }
8602        } finally {
8603            Binder.restoreCallingIdentity(origId);
8604        }
8605    }
8606
8607    @Override
8608    public boolean convertToTranslucent(IBinder token) {
8609        final long origId = Binder.clearCallingIdentity();
8610        try {
8611            synchronized (this) {
8612                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8613                if (r == null) {
8614                    return false;
8615                }
8616                if (r.changeWindowTranslucency(false)) {
8617                    r.task.stack.convertToTranslucent(r);
8618                    mWindowManager.setAppFullscreen(token, false);
8619                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8620                    return true;
8621                }
8622                return false;
8623            }
8624        } finally {
8625            Binder.restoreCallingIdentity(origId);
8626        }
8627    }
8628
8629    @Override
8630    public void setImmersive(IBinder token, boolean immersive) {
8631        synchronized(this) {
8632            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8633            if (r == null) {
8634                throw new IllegalArgumentException();
8635            }
8636            r.immersive = immersive;
8637
8638            // update associated state if we're frontmost
8639            if (r == mFocusedActivity) {
8640                if (DEBUG_IMMERSIVE) {
8641                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8642                }
8643                applyUpdateLockStateLocked(r);
8644            }
8645        }
8646    }
8647
8648    @Override
8649    public boolean isImmersive(IBinder token) {
8650        synchronized (this) {
8651            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8652            if (r == null) {
8653                throw new IllegalArgumentException();
8654            }
8655            return r.immersive;
8656        }
8657    }
8658
8659    public boolean isTopActivityImmersive() {
8660        enforceNotIsolatedCaller("startActivity");
8661        synchronized (this) {
8662            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8663            return (r != null) ? r.immersive : false;
8664        }
8665    }
8666
8667    public final void enterSafeMode() {
8668        synchronized(this) {
8669            // It only makes sense to do this before the system is ready
8670            // and started launching other packages.
8671            if (!mSystemReady) {
8672                try {
8673                    AppGlobals.getPackageManager().enterSafeMode();
8674                } catch (RemoteException e) {
8675                }
8676            }
8677        }
8678    }
8679
8680    public final void showSafeModeOverlay() {
8681        View v = LayoutInflater.from(mContext).inflate(
8682                com.android.internal.R.layout.safe_mode, null);
8683        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8684        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8685        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8686        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8687        lp.gravity = Gravity.BOTTOM | Gravity.START;
8688        lp.format = v.getBackground().getOpacity();
8689        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8690                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8691        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8692        ((WindowManager)mContext.getSystemService(
8693                Context.WINDOW_SERVICE)).addView(v, lp);
8694    }
8695
8696    public void noteWakeupAlarm(IIntentSender sender) {
8697        if (!(sender instanceof PendingIntentRecord)) {
8698            return;
8699        }
8700        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8701        synchronized (stats) {
8702            if (mBatteryStatsService.isOnBattery()) {
8703                mBatteryStatsService.enforceCallingPermission();
8704                PendingIntentRecord rec = (PendingIntentRecord)sender;
8705                int MY_UID = Binder.getCallingUid();
8706                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8707                BatteryStatsImpl.Uid.Pkg pkg =
8708                    stats.getPackageStatsLocked(uid, rec.key.packageName);
8709                pkg.incWakeupsLocked();
8710            }
8711        }
8712    }
8713
8714    public boolean killPids(int[] pids, String pReason, boolean secure) {
8715        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8716            throw new SecurityException("killPids only available to the system");
8717        }
8718        String reason = (pReason == null) ? "Unknown" : pReason;
8719        // XXX Note: don't acquire main activity lock here, because the window
8720        // manager calls in with its locks held.
8721
8722        boolean killed = false;
8723        synchronized (mPidsSelfLocked) {
8724            int[] types = new int[pids.length];
8725            int worstType = 0;
8726            for (int i=0; i<pids.length; i++) {
8727                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8728                if (proc != null) {
8729                    int type = proc.setAdj;
8730                    types[i] = type;
8731                    if (type > worstType) {
8732                        worstType = type;
8733                    }
8734                }
8735            }
8736
8737            // If the worst oom_adj is somewhere in the cached proc LRU range,
8738            // then constrain it so we will kill all cached procs.
8739            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8740                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8741                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8742            }
8743
8744            // If this is not a secure call, don't let it kill processes that
8745            // are important.
8746            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8747                worstType = ProcessList.SERVICE_ADJ;
8748            }
8749
8750            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8751            for (int i=0; i<pids.length; i++) {
8752                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8753                if (proc == null) {
8754                    continue;
8755                }
8756                int adj = proc.setAdj;
8757                if (adj >= worstType && !proc.killedByAm) {
8758                    killUnneededProcessLocked(proc, reason);
8759                    killed = true;
8760                }
8761            }
8762        }
8763        return killed;
8764    }
8765
8766    @Override
8767    public void killUid(int uid, String reason) {
8768        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8769            throw new SecurityException("killUid only available to the system");
8770        }
8771        synchronized (this) {
8772            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8773                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8774                    reason != null ? reason : "kill uid");
8775        }
8776    }
8777
8778    @Override
8779    public boolean killProcessesBelowForeground(String reason) {
8780        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8781            throw new SecurityException("killProcessesBelowForeground() only available to system");
8782        }
8783
8784        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8785    }
8786
8787    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8788        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8789            throw new SecurityException("killProcessesBelowAdj() only available to system");
8790        }
8791
8792        boolean killed = false;
8793        synchronized (mPidsSelfLocked) {
8794            final int size = mPidsSelfLocked.size();
8795            for (int i = 0; i < size; i++) {
8796                final int pid = mPidsSelfLocked.keyAt(i);
8797                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8798                if (proc == null) continue;
8799
8800                final int adj = proc.setAdj;
8801                if (adj > belowAdj && !proc.killedByAm) {
8802                    killUnneededProcessLocked(proc, reason);
8803                    killed = true;
8804                }
8805            }
8806        }
8807        return killed;
8808    }
8809
8810    @Override
8811    public void hang(final IBinder who, boolean allowRestart) {
8812        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8813                != PackageManager.PERMISSION_GRANTED) {
8814            throw new SecurityException("Requires permission "
8815                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8816        }
8817
8818        final IBinder.DeathRecipient death = new DeathRecipient() {
8819            @Override
8820            public void binderDied() {
8821                synchronized (this) {
8822                    notifyAll();
8823                }
8824            }
8825        };
8826
8827        try {
8828            who.linkToDeath(death, 0);
8829        } catch (RemoteException e) {
8830            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8831            return;
8832        }
8833
8834        synchronized (this) {
8835            Watchdog.getInstance().setAllowRestart(allowRestart);
8836            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8837            synchronized (death) {
8838                while (who.isBinderAlive()) {
8839                    try {
8840                        death.wait();
8841                    } catch (InterruptedException e) {
8842                    }
8843                }
8844            }
8845            Watchdog.getInstance().setAllowRestart(true);
8846        }
8847    }
8848
8849    @Override
8850    public void restart() {
8851        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8852                != PackageManager.PERMISSION_GRANTED) {
8853            throw new SecurityException("Requires permission "
8854                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8855        }
8856
8857        Log.i(TAG, "Sending shutdown broadcast...");
8858
8859        BroadcastReceiver br = new BroadcastReceiver() {
8860            @Override public void onReceive(Context context, Intent intent) {
8861                // Now the broadcast is done, finish up the low-level shutdown.
8862                Log.i(TAG, "Shutting down activity manager...");
8863                shutdown(10000);
8864                Log.i(TAG, "Shutdown complete, restarting!");
8865                Process.killProcess(Process.myPid());
8866                System.exit(10);
8867            }
8868        };
8869
8870        // First send the high-level shut down broadcast.
8871        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8872        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8873        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8874        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8875        mContext.sendOrderedBroadcastAsUser(intent,
8876                UserHandle.ALL, null, br, mHandler, 0, null, null);
8877        */
8878        br.onReceive(mContext, intent);
8879    }
8880
8881    private long getLowRamTimeSinceIdle(long now) {
8882        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8883    }
8884
8885    @Override
8886    public void performIdleMaintenance() {
8887        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8888                != PackageManager.PERMISSION_GRANTED) {
8889            throw new SecurityException("Requires permission "
8890                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8891        }
8892
8893        synchronized (this) {
8894            final long now = SystemClock.uptimeMillis();
8895            final long timeSinceLastIdle = now - mLastIdleTime;
8896            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
8897            mLastIdleTime = now;
8898            mLowRamTimeSinceLastIdle = 0;
8899            if (mLowRamStartTime != 0) {
8900                mLowRamStartTime = now;
8901            }
8902
8903            StringBuilder sb = new StringBuilder(128);
8904            sb.append("Idle maintenance over ");
8905            TimeUtils.formatDuration(timeSinceLastIdle, sb);
8906            sb.append(" low RAM for ");
8907            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
8908            Slog.i(TAG, sb.toString());
8909
8910            // If at least 1/3 of our time since the last idle period has been spent
8911            // with RAM low, then we want to kill processes.
8912            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
8913
8914            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
8915                ProcessRecord proc = mLruProcesses.get(i);
8916                if (proc.notCachedSinceIdle) {
8917                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
8918                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
8919                        if (doKilling && proc.initialIdlePss != 0
8920                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
8921                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
8922                                    + " from " + proc.initialIdlePss + ")");
8923                        }
8924                    }
8925                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
8926                    proc.notCachedSinceIdle = true;
8927                    proc.initialIdlePss = 0;
8928                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
8929                            mSleeping, now);
8930                }
8931            }
8932
8933            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
8934            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
8935        }
8936    }
8937
8938    private void retrieveSettings() {
8939        final ContentResolver resolver = mContext.getContentResolver();
8940        String debugApp = Settings.Global.getString(
8941            resolver, Settings.Global.DEBUG_APP);
8942        boolean waitForDebugger = Settings.Global.getInt(
8943            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
8944        boolean alwaysFinishActivities = Settings.Global.getInt(
8945            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
8946        boolean forceRtl = Settings.Global.getInt(
8947                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
8948        // Transfer any global setting for forcing RTL layout, into a System Property
8949        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
8950
8951        Configuration configuration = new Configuration();
8952        Settings.System.getConfiguration(resolver, configuration);
8953        if (forceRtl) {
8954            // This will take care of setting the correct layout direction flags
8955            configuration.setLayoutDirection(configuration.locale);
8956        }
8957
8958        synchronized (this) {
8959            mDebugApp = mOrigDebugApp = debugApp;
8960            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
8961            mAlwaysFinishActivities = alwaysFinishActivities;
8962            // This happens before any activities are started, so we can
8963            // change mConfiguration in-place.
8964            updateConfigurationLocked(configuration, null, false, true);
8965            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
8966        }
8967    }
8968
8969    public boolean testIsSystemReady() {
8970        // no need to synchronize(this) just to read & return the value
8971        return mSystemReady;
8972    }
8973
8974    private static File getCalledPreBootReceiversFile() {
8975        File dataDir = Environment.getDataDirectory();
8976        File systemDir = new File(dataDir, "system");
8977        File fname = new File(systemDir, "called_pre_boots.dat");
8978        return fname;
8979    }
8980
8981    static final int LAST_DONE_VERSION = 10000;
8982
8983    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
8984        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
8985        File file = getCalledPreBootReceiversFile();
8986        FileInputStream fis = null;
8987        try {
8988            fis = new FileInputStream(file);
8989            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
8990            int fvers = dis.readInt();
8991            if (fvers == LAST_DONE_VERSION) {
8992                String vers = dis.readUTF();
8993                String codename = dis.readUTF();
8994                String build = dis.readUTF();
8995                if (android.os.Build.VERSION.RELEASE.equals(vers)
8996                        && android.os.Build.VERSION.CODENAME.equals(codename)
8997                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
8998                    int num = dis.readInt();
8999                    while (num > 0) {
9000                        num--;
9001                        String pkg = dis.readUTF();
9002                        String cls = dis.readUTF();
9003                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9004                    }
9005                }
9006            }
9007        } catch (FileNotFoundException e) {
9008        } catch (IOException e) {
9009            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9010        } finally {
9011            if (fis != null) {
9012                try {
9013                    fis.close();
9014                } catch (IOException e) {
9015                }
9016            }
9017        }
9018        return lastDoneReceivers;
9019    }
9020
9021    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9022        File file = getCalledPreBootReceiversFile();
9023        FileOutputStream fos = null;
9024        DataOutputStream dos = null;
9025        try {
9026            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9027            fos = new FileOutputStream(file);
9028            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9029            dos.writeInt(LAST_DONE_VERSION);
9030            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9031            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9032            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9033            dos.writeInt(list.size());
9034            for (int i=0; i<list.size(); i++) {
9035                dos.writeUTF(list.get(i).getPackageName());
9036                dos.writeUTF(list.get(i).getClassName());
9037            }
9038        } catch (IOException e) {
9039            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9040            file.delete();
9041        } finally {
9042            FileUtils.sync(fos);
9043            if (dos != null) {
9044                try {
9045                    dos.close();
9046                } catch (IOException e) {
9047                    // TODO Auto-generated catch block
9048                    e.printStackTrace();
9049                }
9050            }
9051        }
9052    }
9053
9054    public void systemReady(final Runnable goingCallback) {
9055        synchronized(this) {
9056            if (mSystemReady) {
9057                if (goingCallback != null) goingCallback.run();
9058                return;
9059            }
9060
9061            // Check to see if there are any update receivers to run.
9062            if (!mDidUpdate) {
9063                if (mWaitingUpdate) {
9064                    return;
9065                }
9066                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9067                List<ResolveInfo> ris = null;
9068                try {
9069                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9070                            intent, null, 0, 0);
9071                } catch (RemoteException e) {
9072                }
9073                if (ris != null) {
9074                    for (int i=ris.size()-1; i>=0; i--) {
9075                        if ((ris.get(i).activityInfo.applicationInfo.flags
9076                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9077                            ris.remove(i);
9078                        }
9079                    }
9080                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9081
9082                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9083
9084                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9085                    for (int i=0; i<ris.size(); i++) {
9086                        ActivityInfo ai = ris.get(i).activityInfo;
9087                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9088                        if (lastDoneReceivers.contains(comp)) {
9089                            // We already did the pre boot receiver for this app with the current
9090                            // platform version, so don't do it again...
9091                            ris.remove(i);
9092                            i--;
9093                            // ...however, do keep it as one that has been done, so we don't
9094                            // forget about it when rewriting the file of last done receivers.
9095                            doneReceivers.add(comp);
9096                        }
9097                    }
9098
9099                    final int[] users = getUsersLocked();
9100                    for (int i=0; i<ris.size(); i++) {
9101                        ActivityInfo ai = ris.get(i).activityInfo;
9102                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9103                        doneReceivers.add(comp);
9104                        intent.setComponent(comp);
9105                        for (int j=0; j<users.length; j++) {
9106                            IIntentReceiver finisher = null;
9107                            if (i == ris.size()-1 && j == users.length-1) {
9108                                finisher = new IIntentReceiver.Stub() {
9109                                    public void performReceive(Intent intent, int resultCode,
9110                                            String data, Bundle extras, boolean ordered,
9111                                            boolean sticky, int sendingUser) {
9112                                        // The raw IIntentReceiver interface is called
9113                                        // with the AM lock held, so redispatch to
9114                                        // execute our code without the lock.
9115                                        mHandler.post(new Runnable() {
9116                                            public void run() {
9117                                                synchronized (ActivityManagerService.this) {
9118                                                    mDidUpdate = true;
9119                                                }
9120                                                writeLastDonePreBootReceivers(doneReceivers);
9121                                                showBootMessage(mContext.getText(
9122                                                        R.string.android_upgrading_complete),
9123                                                        false);
9124                                                systemReady(goingCallback);
9125                                            }
9126                                        });
9127                                    }
9128                                };
9129                            }
9130                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9131                                    + " for user " + users[j]);
9132                            broadcastIntentLocked(null, null, intent, null, finisher,
9133                                    0, null, null, null, AppOpsManager.OP_NONE,
9134                                    true, false, MY_PID, Process.SYSTEM_UID,
9135                                    users[j]);
9136                            if (finisher != null) {
9137                                mWaitingUpdate = true;
9138                            }
9139                        }
9140                    }
9141                }
9142                if (mWaitingUpdate) {
9143                    return;
9144                }
9145                mDidUpdate = true;
9146            }
9147
9148            mAppOpsService.systemReady();
9149            mSystemReady = true;
9150        }
9151
9152        ArrayList<ProcessRecord> procsToKill = null;
9153        synchronized(mPidsSelfLocked) {
9154            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9155                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9156                if (!isAllowedWhileBooting(proc.info)){
9157                    if (procsToKill == null) {
9158                        procsToKill = new ArrayList<ProcessRecord>();
9159                    }
9160                    procsToKill.add(proc);
9161                }
9162            }
9163        }
9164
9165        synchronized(this) {
9166            if (procsToKill != null) {
9167                for (int i=procsToKill.size()-1; i>=0; i--) {
9168                    ProcessRecord proc = procsToKill.get(i);
9169                    Slog.i(TAG, "Removing system update proc: " + proc);
9170                    removeProcessLocked(proc, true, false, "system update done");
9171                }
9172            }
9173
9174            // Now that we have cleaned up any update processes, we
9175            // are ready to start launching real processes and know that
9176            // we won't trample on them any more.
9177            mProcessesReady = true;
9178        }
9179
9180        Slog.i(TAG, "System now ready");
9181        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9182            SystemClock.uptimeMillis());
9183
9184        synchronized(this) {
9185            // Make sure we have no pre-ready processes sitting around.
9186
9187            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9188                ResolveInfo ri = mContext.getPackageManager()
9189                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9190                                STOCK_PM_FLAGS);
9191                CharSequence errorMsg = null;
9192                if (ri != null) {
9193                    ActivityInfo ai = ri.activityInfo;
9194                    ApplicationInfo app = ai.applicationInfo;
9195                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9196                        mTopAction = Intent.ACTION_FACTORY_TEST;
9197                        mTopData = null;
9198                        mTopComponent = new ComponentName(app.packageName,
9199                                ai.name);
9200                    } else {
9201                        errorMsg = mContext.getResources().getText(
9202                                com.android.internal.R.string.factorytest_not_system);
9203                    }
9204                } else {
9205                    errorMsg = mContext.getResources().getText(
9206                            com.android.internal.R.string.factorytest_no_action);
9207                }
9208                if (errorMsg != null) {
9209                    mTopAction = null;
9210                    mTopData = null;
9211                    mTopComponent = null;
9212                    Message msg = Message.obtain();
9213                    msg.what = SHOW_FACTORY_ERROR_MSG;
9214                    msg.getData().putCharSequence("msg", errorMsg);
9215                    mHandler.sendMessage(msg);
9216                }
9217            }
9218        }
9219
9220        retrieveSettings();
9221
9222        synchronized (this) {
9223            readGrantedUriPermissionsLocked();
9224        }
9225
9226        if (goingCallback != null) goingCallback.run();
9227
9228        synchronized (this) {
9229            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9230                try {
9231                    List apps = AppGlobals.getPackageManager().
9232                        getPersistentApplications(STOCK_PM_FLAGS);
9233                    if (apps != null) {
9234                        int N = apps.size();
9235                        int i;
9236                        for (i=0; i<N; i++) {
9237                            ApplicationInfo info
9238                                = (ApplicationInfo)apps.get(i);
9239                            if (info != null &&
9240                                    !info.packageName.equals("android")) {
9241                                addAppLocked(info, false);
9242                            }
9243                        }
9244                    }
9245                } catch (RemoteException ex) {
9246                    // pm is in same process, this will never happen.
9247                }
9248            }
9249
9250            // Start up initial activity.
9251            mBooting = true;
9252
9253            try {
9254                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9255                    Message msg = Message.obtain();
9256                    msg.what = SHOW_UID_ERROR_MSG;
9257                    mHandler.sendMessage(msg);
9258                }
9259            } catch (RemoteException e) {
9260            }
9261
9262            long ident = Binder.clearCallingIdentity();
9263            try {
9264                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9265                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9266                        | Intent.FLAG_RECEIVER_FOREGROUND);
9267                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9268                broadcastIntentLocked(null, null, intent,
9269                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9270                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9271                intent = new Intent(Intent.ACTION_USER_STARTING);
9272                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9273                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9274                broadcastIntentLocked(null, null, intent,
9275                        null, new IIntentReceiver.Stub() {
9276                            @Override
9277                            public void performReceive(Intent intent, int resultCode, String data,
9278                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9279                                    throws RemoteException {
9280                            }
9281                        }, 0, null, null,
9282                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9283                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9284            } finally {
9285                Binder.restoreCallingIdentity(ident);
9286            }
9287            mStackSupervisor.resumeTopActivitiesLocked();
9288            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9289        }
9290    }
9291
9292    private boolean makeAppCrashingLocked(ProcessRecord app,
9293            String shortMsg, String longMsg, String stackTrace) {
9294        app.crashing = true;
9295        app.crashingReport = generateProcessError(app,
9296                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9297        startAppProblemLocked(app);
9298        app.stopFreezingAllLocked();
9299        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9300    }
9301
9302    private void makeAppNotRespondingLocked(ProcessRecord app,
9303            String activity, String shortMsg, String longMsg) {
9304        app.notResponding = true;
9305        app.notRespondingReport = generateProcessError(app,
9306                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9307                activity, shortMsg, longMsg, null);
9308        startAppProblemLocked(app);
9309        app.stopFreezingAllLocked();
9310    }
9311
9312    /**
9313     * Generate a process error record, suitable for attachment to a ProcessRecord.
9314     *
9315     * @param app The ProcessRecord in which the error occurred.
9316     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9317     *                      ActivityManager.AppErrorStateInfo
9318     * @param activity The activity associated with the crash, if known.
9319     * @param shortMsg Short message describing the crash.
9320     * @param longMsg Long message describing the crash.
9321     * @param stackTrace Full crash stack trace, may be null.
9322     *
9323     * @return Returns a fully-formed AppErrorStateInfo record.
9324     */
9325    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9326            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9327        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9328
9329        report.condition = condition;
9330        report.processName = app.processName;
9331        report.pid = app.pid;
9332        report.uid = app.info.uid;
9333        report.tag = activity;
9334        report.shortMsg = shortMsg;
9335        report.longMsg = longMsg;
9336        report.stackTrace = stackTrace;
9337
9338        return report;
9339    }
9340
9341    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9342        synchronized (this) {
9343            app.crashing = false;
9344            app.crashingReport = null;
9345            app.notResponding = false;
9346            app.notRespondingReport = null;
9347            if (app.anrDialog == fromDialog) {
9348                app.anrDialog = null;
9349            }
9350            if (app.waitDialog == fromDialog) {
9351                app.waitDialog = null;
9352            }
9353            if (app.pid > 0 && app.pid != MY_PID) {
9354                handleAppCrashLocked(app, null, null, null);
9355                killUnneededProcessLocked(app, "user request after error");
9356            }
9357        }
9358    }
9359
9360    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9361            String stackTrace) {
9362        long now = SystemClock.uptimeMillis();
9363
9364        Long crashTime;
9365        if (!app.isolated) {
9366            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9367        } else {
9368            crashTime = null;
9369        }
9370        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9371            // This process loses!
9372            Slog.w(TAG, "Process " + app.info.processName
9373                    + " has crashed too many times: killing!");
9374            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9375                    app.userId, app.info.processName, app.uid);
9376            mStackSupervisor.handleAppCrashLocked(app);
9377            if (!app.persistent) {
9378                // We don't want to start this process again until the user
9379                // explicitly does so...  but for persistent process, we really
9380                // need to keep it running.  If a persistent process is actually
9381                // repeatedly crashing, then badness for everyone.
9382                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9383                        app.info.processName);
9384                if (!app.isolated) {
9385                    // XXX We don't have a way to mark isolated processes
9386                    // as bad, since they don't have a peristent identity.
9387                    mBadProcesses.put(app.info.processName, app.uid,
9388                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9389                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9390                }
9391                app.bad = true;
9392                app.removed = true;
9393                // Don't let services in this process be restarted and potentially
9394                // annoy the user repeatedly.  Unless it is persistent, since those
9395                // processes run critical code.
9396                removeProcessLocked(app, false, false, "crash");
9397                mStackSupervisor.resumeTopActivitiesLocked();
9398                return false;
9399            }
9400            mStackSupervisor.resumeTopActivitiesLocked();
9401        } else {
9402            mStackSupervisor.finishTopRunningActivityLocked(app);
9403        }
9404
9405        // Bump up the crash count of any services currently running in the proc.
9406        for (int i=app.services.size()-1; i>=0; i--) {
9407            // Any services running in the application need to be placed
9408            // back in the pending list.
9409            ServiceRecord sr = app.services.valueAt(i);
9410            sr.crashCount++;
9411        }
9412
9413        // If the crashing process is what we consider to be the "home process" and it has been
9414        // replaced by a third-party app, clear the package preferred activities from packages
9415        // with a home activity running in the process to prevent a repeatedly crashing app
9416        // from blocking the user to manually clear the list.
9417        final ArrayList<ActivityRecord> activities = app.activities;
9418        if (app == mHomeProcess && activities.size() > 0
9419                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9420            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9421                final ActivityRecord r = activities.get(activityNdx);
9422                if (r.isHomeActivity()) {
9423                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9424                    try {
9425                        ActivityThread.getPackageManager()
9426                                .clearPackagePreferredActivities(r.packageName);
9427                    } catch (RemoteException c) {
9428                        // pm is in same process, this will never happen.
9429                    }
9430                }
9431            }
9432        }
9433
9434        if (!app.isolated) {
9435            // XXX Can't keep track of crash times for isolated processes,
9436            // because they don't have a perisistent identity.
9437            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9438        }
9439
9440        return true;
9441    }
9442
9443    void startAppProblemLocked(ProcessRecord app) {
9444        if (app.userId == mCurrentUserId) {
9445            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9446                    mContext, app.info.packageName, app.info.flags);
9447        } else {
9448            // If this app is not running under the current user, then we
9449            // can't give it a report button because that would require
9450            // launching the report UI under a different user.
9451            app.errorReportReceiver = null;
9452        }
9453        skipCurrentReceiverLocked(app);
9454    }
9455
9456    void skipCurrentReceiverLocked(ProcessRecord app) {
9457        for (BroadcastQueue queue : mBroadcastQueues) {
9458            queue.skipCurrentReceiverLocked(app);
9459        }
9460    }
9461
9462    /**
9463     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9464     * The application process will exit immediately after this call returns.
9465     * @param app object of the crashing app, null for the system server
9466     * @param crashInfo describing the exception
9467     */
9468    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9469        ProcessRecord r = findAppProcess(app, "Crash");
9470        final String processName = app == null ? "system_server"
9471                : (r == null ? "unknown" : r.processName);
9472
9473        handleApplicationCrashInner("crash", r, processName, crashInfo);
9474    }
9475
9476    /* Native crash reporting uses this inner version because it needs to be somewhat
9477     * decoupled from the AM-managed cleanup lifecycle
9478     */
9479    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9480            ApplicationErrorReport.CrashInfo crashInfo) {
9481        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9482                UserHandle.getUserId(Binder.getCallingUid()), processName,
9483                r == null ? -1 : r.info.flags,
9484                crashInfo.exceptionClassName,
9485                crashInfo.exceptionMessage,
9486                crashInfo.throwFileName,
9487                crashInfo.throwLineNumber);
9488
9489        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9490
9491        crashApplication(r, crashInfo);
9492    }
9493
9494    public void handleApplicationStrictModeViolation(
9495            IBinder app,
9496            int violationMask,
9497            StrictMode.ViolationInfo info) {
9498        ProcessRecord r = findAppProcess(app, "StrictMode");
9499        if (r == null) {
9500            return;
9501        }
9502
9503        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9504            Integer stackFingerprint = info.hashCode();
9505            boolean logIt = true;
9506            synchronized (mAlreadyLoggedViolatedStacks) {
9507                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9508                    logIt = false;
9509                    // TODO: sub-sample into EventLog for these, with
9510                    // the info.durationMillis?  Then we'd get
9511                    // the relative pain numbers, without logging all
9512                    // the stack traces repeatedly.  We'd want to do
9513                    // likewise in the client code, which also does
9514                    // dup suppression, before the Binder call.
9515                } else {
9516                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9517                        mAlreadyLoggedViolatedStacks.clear();
9518                    }
9519                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9520                }
9521            }
9522            if (logIt) {
9523                logStrictModeViolationToDropBox(r, info);
9524            }
9525        }
9526
9527        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9528            AppErrorResult result = new AppErrorResult();
9529            synchronized (this) {
9530                final long origId = Binder.clearCallingIdentity();
9531
9532                Message msg = Message.obtain();
9533                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9534                HashMap<String, Object> data = new HashMap<String, Object>();
9535                data.put("result", result);
9536                data.put("app", r);
9537                data.put("violationMask", violationMask);
9538                data.put("info", info);
9539                msg.obj = data;
9540                mHandler.sendMessage(msg);
9541
9542                Binder.restoreCallingIdentity(origId);
9543            }
9544            int res = result.get();
9545            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9546        }
9547    }
9548
9549    // Depending on the policy in effect, there could be a bunch of
9550    // these in quick succession so we try to batch these together to
9551    // minimize disk writes, number of dropbox entries, and maximize
9552    // compression, by having more fewer, larger records.
9553    private void logStrictModeViolationToDropBox(
9554            ProcessRecord process,
9555            StrictMode.ViolationInfo info) {
9556        if (info == null) {
9557            return;
9558        }
9559        final boolean isSystemApp = process == null ||
9560                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9561                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9562        final String processName = process == null ? "unknown" : process.processName;
9563        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9564        final DropBoxManager dbox = (DropBoxManager)
9565                mContext.getSystemService(Context.DROPBOX_SERVICE);
9566
9567        // Exit early if the dropbox isn't configured to accept this report type.
9568        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9569
9570        boolean bufferWasEmpty;
9571        boolean needsFlush;
9572        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9573        synchronized (sb) {
9574            bufferWasEmpty = sb.length() == 0;
9575            appendDropBoxProcessHeaders(process, processName, sb);
9576            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9577            sb.append("System-App: ").append(isSystemApp).append("\n");
9578            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9579            if (info.violationNumThisLoop != 0) {
9580                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9581            }
9582            if (info.numAnimationsRunning != 0) {
9583                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9584            }
9585            if (info.broadcastIntentAction != null) {
9586                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9587            }
9588            if (info.durationMillis != -1) {
9589                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9590            }
9591            if (info.numInstances != -1) {
9592                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9593            }
9594            if (info.tags != null) {
9595                for (String tag : info.tags) {
9596                    sb.append("Span-Tag: ").append(tag).append("\n");
9597                }
9598            }
9599            sb.append("\n");
9600            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9601                sb.append(info.crashInfo.stackTrace);
9602            }
9603            sb.append("\n");
9604
9605            // Only buffer up to ~64k.  Various logging bits truncate
9606            // things at 128k.
9607            needsFlush = (sb.length() > 64 * 1024);
9608        }
9609
9610        // Flush immediately if the buffer's grown too large, or this
9611        // is a non-system app.  Non-system apps are isolated with a
9612        // different tag & policy and not batched.
9613        //
9614        // Batching is useful during internal testing with
9615        // StrictMode settings turned up high.  Without batching,
9616        // thousands of separate files could be created on boot.
9617        if (!isSystemApp || needsFlush) {
9618            new Thread("Error dump: " + dropboxTag) {
9619                @Override
9620                public void run() {
9621                    String report;
9622                    synchronized (sb) {
9623                        report = sb.toString();
9624                        sb.delete(0, sb.length());
9625                        sb.trimToSize();
9626                    }
9627                    if (report.length() != 0) {
9628                        dbox.addText(dropboxTag, report);
9629                    }
9630                }
9631            }.start();
9632            return;
9633        }
9634
9635        // System app batching:
9636        if (!bufferWasEmpty) {
9637            // An existing dropbox-writing thread is outstanding, so
9638            // we don't need to start it up.  The existing thread will
9639            // catch the buffer appends we just did.
9640            return;
9641        }
9642
9643        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9644        // (After this point, we shouldn't access AMS internal data structures.)
9645        new Thread("Error dump: " + dropboxTag) {
9646            @Override
9647            public void run() {
9648                // 5 second sleep to let stacks arrive and be batched together
9649                try {
9650                    Thread.sleep(5000);  // 5 seconds
9651                } catch (InterruptedException e) {}
9652
9653                String errorReport;
9654                synchronized (mStrictModeBuffer) {
9655                    errorReport = mStrictModeBuffer.toString();
9656                    if (errorReport.length() == 0) {
9657                        return;
9658                    }
9659                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9660                    mStrictModeBuffer.trimToSize();
9661                }
9662                dbox.addText(dropboxTag, errorReport);
9663            }
9664        }.start();
9665    }
9666
9667    /**
9668     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9669     * @param app object of the crashing app, null for the system server
9670     * @param tag reported by the caller
9671     * @param crashInfo describing the context of the error
9672     * @return true if the process should exit immediately (WTF is fatal)
9673     */
9674    public boolean handleApplicationWtf(IBinder app, String tag,
9675            ApplicationErrorReport.CrashInfo crashInfo) {
9676        ProcessRecord r = findAppProcess(app, "WTF");
9677        final String processName = app == null ? "system_server"
9678                : (r == null ? "unknown" : r.processName);
9679
9680        EventLog.writeEvent(EventLogTags.AM_WTF,
9681                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9682                processName,
9683                r == null ? -1 : r.info.flags,
9684                tag, crashInfo.exceptionMessage);
9685
9686        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9687
9688        if (r != null && r.pid != Process.myPid() &&
9689                Settings.Global.getInt(mContext.getContentResolver(),
9690                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9691            crashApplication(r, crashInfo);
9692            return true;
9693        } else {
9694            return false;
9695        }
9696    }
9697
9698    /**
9699     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9700     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9701     */
9702    private ProcessRecord findAppProcess(IBinder app, String reason) {
9703        if (app == null) {
9704            return null;
9705        }
9706
9707        synchronized (this) {
9708            final int NP = mProcessNames.getMap().size();
9709            for (int ip=0; ip<NP; ip++) {
9710                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9711                final int NA = apps.size();
9712                for (int ia=0; ia<NA; ia++) {
9713                    ProcessRecord p = apps.valueAt(ia);
9714                    if (p.thread != null && p.thread.asBinder() == app) {
9715                        return p;
9716                    }
9717                }
9718            }
9719
9720            Slog.w(TAG, "Can't find mystery application for " + reason
9721                    + " from pid=" + Binder.getCallingPid()
9722                    + " uid=" + Binder.getCallingUid() + ": " + app);
9723            return null;
9724        }
9725    }
9726
9727    /**
9728     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9729     * to append various headers to the dropbox log text.
9730     */
9731    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9732            StringBuilder sb) {
9733        // Watchdog thread ends up invoking this function (with
9734        // a null ProcessRecord) to add the stack file to dropbox.
9735        // Do not acquire a lock on this (am) in such cases, as it
9736        // could cause a potential deadlock, if and when watchdog
9737        // is invoked due to unavailability of lock on am and it
9738        // would prevent watchdog from killing system_server.
9739        if (process == null) {
9740            sb.append("Process: ").append(processName).append("\n");
9741            return;
9742        }
9743        // Note: ProcessRecord 'process' is guarded by the service
9744        // instance.  (notably process.pkgList, which could otherwise change
9745        // concurrently during execution of this method)
9746        synchronized (this) {
9747            sb.append("Process: ").append(processName).append("\n");
9748            int flags = process.info.flags;
9749            IPackageManager pm = AppGlobals.getPackageManager();
9750            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9751            for (int ip=0; ip<process.pkgList.size(); ip++) {
9752                String pkg = process.pkgList.keyAt(ip);
9753                sb.append("Package: ").append(pkg);
9754                try {
9755                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9756                    if (pi != null) {
9757                        sb.append(" v").append(pi.versionCode);
9758                        if (pi.versionName != null) {
9759                            sb.append(" (").append(pi.versionName).append(")");
9760                        }
9761                    }
9762                } catch (RemoteException e) {
9763                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9764                }
9765                sb.append("\n");
9766            }
9767        }
9768    }
9769
9770    private static String processClass(ProcessRecord process) {
9771        if (process == null || process.pid == MY_PID) {
9772            return "system_server";
9773        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9774            return "system_app";
9775        } else {
9776            return "data_app";
9777        }
9778    }
9779
9780    /**
9781     * Write a description of an error (crash, WTF, ANR) to the drop box.
9782     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9783     * @param process which caused the error, null means the system server
9784     * @param activity which triggered the error, null if unknown
9785     * @param parent activity related to the error, null if unknown
9786     * @param subject line related to the error, null if absent
9787     * @param report in long form describing the error, null if absent
9788     * @param logFile to include in the report, null if none
9789     * @param crashInfo giving an application stack trace, null if absent
9790     */
9791    public void addErrorToDropBox(String eventType,
9792            ProcessRecord process, String processName, ActivityRecord activity,
9793            ActivityRecord parent, String subject,
9794            final String report, final File logFile,
9795            final ApplicationErrorReport.CrashInfo crashInfo) {
9796        // NOTE -- this must never acquire the ActivityManagerService lock,
9797        // otherwise the watchdog may be prevented from resetting the system.
9798
9799        final String dropboxTag = processClass(process) + "_" + eventType;
9800        final DropBoxManager dbox = (DropBoxManager)
9801                mContext.getSystemService(Context.DROPBOX_SERVICE);
9802
9803        // Exit early if the dropbox isn't configured to accept this report type.
9804        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9805
9806        final StringBuilder sb = new StringBuilder(1024);
9807        appendDropBoxProcessHeaders(process, processName, sb);
9808        if (activity != null) {
9809            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9810        }
9811        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9812            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9813        }
9814        if (parent != null && parent != activity) {
9815            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9816        }
9817        if (subject != null) {
9818            sb.append("Subject: ").append(subject).append("\n");
9819        }
9820        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9821        if (Debug.isDebuggerConnected()) {
9822            sb.append("Debugger: Connected\n");
9823        }
9824        sb.append("\n");
9825
9826        // Do the rest in a worker thread to avoid blocking the caller on I/O
9827        // (After this point, we shouldn't access AMS internal data structures.)
9828        Thread worker = new Thread("Error dump: " + dropboxTag) {
9829            @Override
9830            public void run() {
9831                if (report != null) {
9832                    sb.append(report);
9833                }
9834                if (logFile != null) {
9835                    try {
9836                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9837                                    "\n\n[[TRUNCATED]]"));
9838                    } catch (IOException e) {
9839                        Slog.e(TAG, "Error reading " + logFile, e);
9840                    }
9841                }
9842                if (crashInfo != null && crashInfo.stackTrace != null) {
9843                    sb.append(crashInfo.stackTrace);
9844                }
9845
9846                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9847                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9848                if (lines > 0) {
9849                    sb.append("\n");
9850
9851                    // Merge several logcat streams, and take the last N lines
9852                    InputStreamReader input = null;
9853                    try {
9854                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9855                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9856                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9857
9858                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9859                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9860                        input = new InputStreamReader(logcat.getInputStream());
9861
9862                        int num;
9863                        char[] buf = new char[8192];
9864                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9865                    } catch (IOException e) {
9866                        Slog.e(TAG, "Error running logcat", e);
9867                    } finally {
9868                        if (input != null) try { input.close(); } catch (IOException e) {}
9869                    }
9870                }
9871
9872                dbox.addText(dropboxTag, sb.toString());
9873            }
9874        };
9875
9876        if (process == null) {
9877            // If process is null, we are being called from some internal code
9878            // and may be about to die -- run this synchronously.
9879            worker.run();
9880        } else {
9881            worker.start();
9882        }
9883    }
9884
9885    /**
9886     * Bring up the "unexpected error" dialog box for a crashing app.
9887     * Deal with edge cases (intercepts from instrumented applications,
9888     * ActivityController, error intent receivers, that sort of thing).
9889     * @param r the application crashing
9890     * @param crashInfo describing the failure
9891     */
9892    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
9893        long timeMillis = System.currentTimeMillis();
9894        String shortMsg = crashInfo.exceptionClassName;
9895        String longMsg = crashInfo.exceptionMessage;
9896        String stackTrace = crashInfo.stackTrace;
9897        if (shortMsg != null && longMsg != null) {
9898            longMsg = shortMsg + ": " + longMsg;
9899        } else if (shortMsg != null) {
9900            longMsg = shortMsg;
9901        }
9902
9903        AppErrorResult result = new AppErrorResult();
9904        synchronized (this) {
9905            if (mController != null) {
9906                try {
9907                    String name = r != null ? r.processName : null;
9908                    int pid = r != null ? r.pid : Binder.getCallingPid();
9909                    if (!mController.appCrashed(name, pid,
9910                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
9911                        Slog.w(TAG, "Force-killing crashed app " + name
9912                                + " at watcher's request");
9913                        Process.killProcess(pid);
9914                        return;
9915                    }
9916                } catch (RemoteException e) {
9917                    mController = null;
9918                    Watchdog.getInstance().setActivityController(null);
9919                }
9920            }
9921
9922            final long origId = Binder.clearCallingIdentity();
9923
9924            // If this process is running instrumentation, finish it.
9925            if (r != null && r.instrumentationClass != null) {
9926                Slog.w(TAG, "Error in app " + r.processName
9927                      + " running instrumentation " + r.instrumentationClass + ":");
9928                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
9929                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
9930                Bundle info = new Bundle();
9931                info.putString("shortMsg", shortMsg);
9932                info.putString("longMsg", longMsg);
9933                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
9934                Binder.restoreCallingIdentity(origId);
9935                return;
9936            }
9937
9938            // If we can't identify the process or it's already exceeded its crash quota,
9939            // quit right away without showing a crash dialog.
9940            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
9941                Binder.restoreCallingIdentity(origId);
9942                return;
9943            }
9944
9945            Message msg = Message.obtain();
9946            msg.what = SHOW_ERROR_MSG;
9947            HashMap data = new HashMap();
9948            data.put("result", result);
9949            data.put("app", r);
9950            msg.obj = data;
9951            mHandler.sendMessage(msg);
9952
9953            Binder.restoreCallingIdentity(origId);
9954        }
9955
9956        int res = result.get();
9957
9958        Intent appErrorIntent = null;
9959        synchronized (this) {
9960            if (r != null && !r.isolated) {
9961                // XXX Can't keep track of crash time for isolated processes,
9962                // since they don't have a persistent identity.
9963                mProcessCrashTimes.put(r.info.processName, r.uid,
9964                        SystemClock.uptimeMillis());
9965            }
9966            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
9967                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
9968            }
9969        }
9970
9971        if (appErrorIntent != null) {
9972            try {
9973                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
9974            } catch (ActivityNotFoundException e) {
9975                Slog.w(TAG, "bug report receiver dissappeared", e);
9976            }
9977        }
9978    }
9979
9980    Intent createAppErrorIntentLocked(ProcessRecord r,
9981            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
9982        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
9983        if (report == null) {
9984            return null;
9985        }
9986        Intent result = new Intent(Intent.ACTION_APP_ERROR);
9987        result.setComponent(r.errorReportReceiver);
9988        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
9989        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9990        return result;
9991    }
9992
9993    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
9994            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
9995        if (r.errorReportReceiver == null) {
9996            return null;
9997        }
9998
9999        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10000            return null;
10001        }
10002
10003        ApplicationErrorReport report = new ApplicationErrorReport();
10004        report.packageName = r.info.packageName;
10005        report.installerPackageName = r.errorReportReceiver.getPackageName();
10006        report.processName = r.processName;
10007        report.time = timeMillis;
10008        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10009
10010        if (r.crashing || r.forceCrashReport) {
10011            report.type = ApplicationErrorReport.TYPE_CRASH;
10012            report.crashInfo = crashInfo;
10013        } else if (r.notResponding) {
10014            report.type = ApplicationErrorReport.TYPE_ANR;
10015            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10016
10017            report.anrInfo.activity = r.notRespondingReport.tag;
10018            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10019            report.anrInfo.info = r.notRespondingReport.longMsg;
10020        }
10021
10022        return report;
10023    }
10024
10025    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10026        enforceNotIsolatedCaller("getProcessesInErrorState");
10027        // assume our apps are happy - lazy create the list
10028        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10029
10030        final boolean allUsers = ActivityManager.checkUidPermission(
10031                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10032                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10033        int userId = UserHandle.getUserId(Binder.getCallingUid());
10034
10035        synchronized (this) {
10036
10037            // iterate across all processes
10038            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10039                ProcessRecord app = mLruProcesses.get(i);
10040                if (!allUsers && app.userId != userId) {
10041                    continue;
10042                }
10043                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10044                    // This one's in trouble, so we'll generate a report for it
10045                    // crashes are higher priority (in case there's a crash *and* an anr)
10046                    ActivityManager.ProcessErrorStateInfo report = null;
10047                    if (app.crashing) {
10048                        report = app.crashingReport;
10049                    } else if (app.notResponding) {
10050                        report = app.notRespondingReport;
10051                    }
10052
10053                    if (report != null) {
10054                        if (errList == null) {
10055                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10056                        }
10057                        errList.add(report);
10058                    } else {
10059                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10060                                " crashing = " + app.crashing +
10061                                " notResponding = " + app.notResponding);
10062                    }
10063                }
10064            }
10065        }
10066
10067        return errList;
10068    }
10069
10070    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10071        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10072            if (currApp != null) {
10073                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10074            }
10075            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10076        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10077            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10078        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10079            if (currApp != null) {
10080                currApp.lru = 0;
10081            }
10082            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10083        } else if (adj >= ProcessList.SERVICE_ADJ) {
10084            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10085        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10086            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10087        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10088            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10089        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10090            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10091        } else {
10092            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10093        }
10094    }
10095
10096    private void fillInProcMemInfo(ProcessRecord app,
10097            ActivityManager.RunningAppProcessInfo outInfo) {
10098        outInfo.pid = app.pid;
10099        outInfo.uid = app.info.uid;
10100        if (mHeavyWeightProcess == app) {
10101            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10102        }
10103        if (app.persistent) {
10104            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10105        }
10106        if (app.activities.size() > 0) {
10107            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10108        }
10109        outInfo.lastTrimLevel = app.trimMemoryLevel;
10110        int adj = app.curAdj;
10111        outInfo.importance = oomAdjToImportance(adj, outInfo);
10112        outInfo.importanceReasonCode = app.adjTypeCode;
10113    }
10114
10115    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10116        enforceNotIsolatedCaller("getRunningAppProcesses");
10117        // Lazy instantiation of list
10118        List<ActivityManager.RunningAppProcessInfo> runList = null;
10119        final boolean allUsers = ActivityManager.checkUidPermission(
10120                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10121                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10122        int userId = UserHandle.getUserId(Binder.getCallingUid());
10123        synchronized (this) {
10124            // Iterate across all processes
10125            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10126                ProcessRecord app = mLruProcesses.get(i);
10127                if (!allUsers && app.userId != userId) {
10128                    continue;
10129                }
10130                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10131                    // Generate process state info for running application
10132                    ActivityManager.RunningAppProcessInfo currApp =
10133                        new ActivityManager.RunningAppProcessInfo(app.processName,
10134                                app.pid, app.getPackageList());
10135                    fillInProcMemInfo(app, currApp);
10136                    if (app.adjSource instanceof ProcessRecord) {
10137                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10138                        currApp.importanceReasonImportance = oomAdjToImportance(
10139                                app.adjSourceOom, null);
10140                    } else if (app.adjSource instanceof ActivityRecord) {
10141                        ActivityRecord r = (ActivityRecord)app.adjSource;
10142                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10143                    }
10144                    if (app.adjTarget instanceof ComponentName) {
10145                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10146                    }
10147                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10148                    //        + " lru=" + currApp.lru);
10149                    if (runList == null) {
10150                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10151                    }
10152                    runList.add(currApp);
10153                }
10154            }
10155        }
10156        return runList;
10157    }
10158
10159    public List<ApplicationInfo> getRunningExternalApplications() {
10160        enforceNotIsolatedCaller("getRunningExternalApplications");
10161        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10162        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10163        if (runningApps != null && runningApps.size() > 0) {
10164            Set<String> extList = new HashSet<String>();
10165            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10166                if (app.pkgList != null) {
10167                    for (String pkg : app.pkgList) {
10168                        extList.add(pkg);
10169                    }
10170                }
10171            }
10172            IPackageManager pm = AppGlobals.getPackageManager();
10173            for (String pkg : extList) {
10174                try {
10175                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10176                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10177                        retList.add(info);
10178                    }
10179                } catch (RemoteException e) {
10180                }
10181            }
10182        }
10183        return retList;
10184    }
10185
10186    @Override
10187    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10188        enforceNotIsolatedCaller("getMyMemoryState");
10189        synchronized (this) {
10190            ProcessRecord proc;
10191            synchronized (mPidsSelfLocked) {
10192                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10193            }
10194            fillInProcMemInfo(proc, outInfo);
10195        }
10196    }
10197
10198    @Override
10199    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10200        if (checkCallingPermission(android.Manifest.permission.DUMP)
10201                != PackageManager.PERMISSION_GRANTED) {
10202            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10203                    + Binder.getCallingPid()
10204                    + ", uid=" + Binder.getCallingUid()
10205                    + " without permission "
10206                    + android.Manifest.permission.DUMP);
10207            return;
10208        }
10209
10210        boolean dumpAll = false;
10211        boolean dumpClient = false;
10212        String dumpPackage = null;
10213
10214        int opti = 0;
10215        while (opti < args.length) {
10216            String opt = args[opti];
10217            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10218                break;
10219            }
10220            opti++;
10221            if ("-a".equals(opt)) {
10222                dumpAll = true;
10223            } else if ("-c".equals(opt)) {
10224                dumpClient = true;
10225            } else if ("-h".equals(opt)) {
10226                pw.println("Activity manager dump options:");
10227                pw.println("  [-a] [-c] [-h] [cmd] ...");
10228                pw.println("  cmd may be one of:");
10229                pw.println("    a[ctivities]: activity stack state");
10230                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10231                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10232                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10233                pw.println("    o[om]: out of memory management");
10234                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10235                pw.println("    provider [COMP_SPEC]: provider client-side state");
10236                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10237                pw.println("    service [COMP_SPEC]: service client-side state");
10238                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10239                pw.println("    all: dump all activities");
10240                pw.println("    top: dump the top activity");
10241                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10242                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10243                pw.println("    a partial substring in a component name, a");
10244                pw.println("    hex object identifier.");
10245                pw.println("  -a: include all available server state.");
10246                pw.println("  -c: include client state.");
10247                return;
10248            } else {
10249                pw.println("Unknown argument: " + opt + "; use -h for help");
10250            }
10251        }
10252
10253        long origId = Binder.clearCallingIdentity();
10254        boolean more = false;
10255        // Is the caller requesting to dump a particular piece of data?
10256        if (opti < args.length) {
10257            String cmd = args[opti];
10258            opti++;
10259            if ("activities".equals(cmd) || "a".equals(cmd)) {
10260                synchronized (this) {
10261                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10262                }
10263            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10264                String[] newArgs;
10265                String name;
10266                if (opti >= args.length) {
10267                    name = null;
10268                    newArgs = EMPTY_STRING_ARRAY;
10269                } else {
10270                    name = args[opti];
10271                    opti++;
10272                    newArgs = new String[args.length - opti];
10273                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10274                            args.length - opti);
10275                }
10276                synchronized (this) {
10277                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10278                }
10279            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10280                String[] newArgs;
10281                String name;
10282                if (opti >= args.length) {
10283                    name = null;
10284                    newArgs = EMPTY_STRING_ARRAY;
10285                } else {
10286                    name = args[opti];
10287                    opti++;
10288                    newArgs = new String[args.length - opti];
10289                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10290                            args.length - opti);
10291                }
10292                synchronized (this) {
10293                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10294                }
10295            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10296                String[] newArgs;
10297                String name;
10298                if (opti >= args.length) {
10299                    name = null;
10300                    newArgs = EMPTY_STRING_ARRAY;
10301                } else {
10302                    name = args[opti];
10303                    opti++;
10304                    newArgs = new String[args.length - opti];
10305                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10306                            args.length - opti);
10307                }
10308                synchronized (this) {
10309                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10310                }
10311            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10312                synchronized (this) {
10313                    dumpOomLocked(fd, pw, args, opti, true);
10314                }
10315            } else if ("provider".equals(cmd)) {
10316                String[] newArgs;
10317                String name;
10318                if (opti >= args.length) {
10319                    name = null;
10320                    newArgs = EMPTY_STRING_ARRAY;
10321                } else {
10322                    name = args[opti];
10323                    opti++;
10324                    newArgs = new String[args.length - opti];
10325                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10326                }
10327                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10328                    pw.println("No providers match: " + name);
10329                    pw.println("Use -h for help.");
10330                }
10331            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10332                synchronized (this) {
10333                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10334                }
10335            } else if ("service".equals(cmd)) {
10336                String[] newArgs;
10337                String name;
10338                if (opti >= args.length) {
10339                    name = null;
10340                    newArgs = EMPTY_STRING_ARRAY;
10341                } else {
10342                    name = args[opti];
10343                    opti++;
10344                    newArgs = new String[args.length - opti];
10345                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10346                            args.length - opti);
10347                }
10348                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10349                    pw.println("No services match: " + name);
10350                    pw.println("Use -h for help.");
10351                }
10352            } else if ("package".equals(cmd)) {
10353                String[] newArgs;
10354                if (opti >= args.length) {
10355                    pw.println("package: no package name specified");
10356                    pw.println("Use -h for help.");
10357                } else {
10358                    dumpPackage = args[opti];
10359                    opti++;
10360                    newArgs = new String[args.length - opti];
10361                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10362                            args.length - opti);
10363                    args = newArgs;
10364                    opti = 0;
10365                    more = true;
10366                }
10367            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10368                synchronized (this) {
10369                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10370                }
10371            } else {
10372                // Dumping a single activity?
10373                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10374                    pw.println("Bad activity command, or no activities match: " + cmd);
10375                    pw.println("Use -h for help.");
10376                }
10377            }
10378            if (!more) {
10379                Binder.restoreCallingIdentity(origId);
10380                return;
10381            }
10382        }
10383
10384        // No piece of data specified, dump everything.
10385        synchronized (this) {
10386            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10387            pw.println();
10388            if (dumpAll) {
10389                pw.println("-------------------------------------------------------------------------------");
10390            }
10391            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10392            pw.println();
10393            if (dumpAll) {
10394                pw.println("-------------------------------------------------------------------------------");
10395            }
10396            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10397            pw.println();
10398            if (dumpAll) {
10399                pw.println("-------------------------------------------------------------------------------");
10400            }
10401            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10402            pw.println();
10403            if (dumpAll) {
10404                pw.println("-------------------------------------------------------------------------------");
10405            }
10406            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10407            pw.println();
10408            if (dumpAll) {
10409                pw.println("-------------------------------------------------------------------------------");
10410            }
10411            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10412        }
10413        Binder.restoreCallingIdentity(origId);
10414    }
10415
10416    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10417            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10418        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10419
10420        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10421                dumpPackage);
10422        boolean needSep = printedAnything;
10423
10424        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10425                dumpPackage, needSep, "  mFocusedActivity: ");
10426        if (printed) {
10427            printedAnything = true;
10428            needSep = false;
10429        }
10430
10431        if (dumpPackage == null) {
10432            if (needSep) {
10433                pw.println();
10434            }
10435            needSep = true;
10436            printedAnything = true;
10437            mStackSupervisor.dump(pw, "  ");
10438        }
10439
10440        if (mRecentTasks.size() > 0) {
10441            boolean printedHeader = false;
10442
10443            final int N = mRecentTasks.size();
10444            for (int i=0; i<N; i++) {
10445                TaskRecord tr = mRecentTasks.get(i);
10446                if (dumpPackage != null) {
10447                    if (tr.realActivity == null ||
10448                            !dumpPackage.equals(tr.realActivity)) {
10449                        continue;
10450                    }
10451                }
10452                if (!printedHeader) {
10453                    if (needSep) {
10454                        pw.println();
10455                    }
10456                    pw.println("  Recent tasks:");
10457                    printedHeader = true;
10458                    printedAnything = true;
10459                }
10460                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10461                        pw.println(tr);
10462                if (dumpAll) {
10463                    mRecentTasks.get(i).dump(pw, "    ");
10464                }
10465            }
10466        }
10467
10468        if (!printedAnything) {
10469            pw.println("  (nothing)");
10470        }
10471    }
10472
10473    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10474            int opti, boolean dumpAll, String dumpPackage) {
10475        boolean needSep = false;
10476        boolean printedAnything = false;
10477        int numPers = 0;
10478
10479        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10480
10481        if (dumpAll) {
10482            final int NP = mProcessNames.getMap().size();
10483            for (int ip=0; ip<NP; ip++) {
10484                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10485                final int NA = procs.size();
10486                for (int ia=0; ia<NA; ia++) {
10487                    ProcessRecord r = procs.valueAt(ia);
10488                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10489                        continue;
10490                    }
10491                    if (!needSep) {
10492                        pw.println("  All known processes:");
10493                        needSep = true;
10494                        printedAnything = true;
10495                    }
10496                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10497                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10498                        pw.print(" "); pw.println(r);
10499                    r.dump(pw, "    ");
10500                    if (r.persistent) {
10501                        numPers++;
10502                    }
10503                }
10504            }
10505        }
10506
10507        if (mIsolatedProcesses.size() > 0) {
10508            boolean printed = false;
10509            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10510                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10511                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10512                    continue;
10513                }
10514                if (!printed) {
10515                    if (needSep) {
10516                        pw.println();
10517                    }
10518                    pw.println("  Isolated process list (sorted by uid):");
10519                    printedAnything = true;
10520                    printed = true;
10521                    needSep = true;
10522                }
10523                pw.println(String.format("%sIsolated #%2d: %s",
10524                        "    ", i, r.toString()));
10525            }
10526        }
10527
10528        if (mLruProcesses.size() > 0) {
10529            if (needSep) {
10530                pw.println();
10531            }
10532            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10533                    pw.print(" total, non-act at ");
10534                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10535                    pw.print(", non-svc at ");
10536                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10537                    pw.println("):");
10538            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10539            needSep = true;
10540            printedAnything = true;
10541        }
10542
10543        if (dumpAll || dumpPackage != null) {
10544            synchronized (mPidsSelfLocked) {
10545                boolean printed = false;
10546                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10547                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10548                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10549                        continue;
10550                    }
10551                    if (!printed) {
10552                        if (needSep) pw.println();
10553                        needSep = true;
10554                        pw.println("  PID mappings:");
10555                        printed = true;
10556                        printedAnything = true;
10557                    }
10558                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10559                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10560                }
10561            }
10562        }
10563
10564        if (mForegroundProcesses.size() > 0) {
10565            synchronized (mPidsSelfLocked) {
10566                boolean printed = false;
10567                for (int i=0; i<mForegroundProcesses.size(); i++) {
10568                    ProcessRecord r = mPidsSelfLocked.get(
10569                            mForegroundProcesses.valueAt(i).pid);
10570                    if (dumpPackage != null && (r == null
10571                            || !r.pkgList.containsKey(dumpPackage))) {
10572                        continue;
10573                    }
10574                    if (!printed) {
10575                        if (needSep) pw.println();
10576                        needSep = true;
10577                        pw.println("  Foreground Processes:");
10578                        printed = true;
10579                        printedAnything = true;
10580                    }
10581                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10582                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10583                }
10584            }
10585        }
10586
10587        if (mPersistentStartingProcesses.size() > 0) {
10588            if (needSep) pw.println();
10589            needSep = true;
10590            printedAnything = true;
10591            pw.println("  Persisent processes that are starting:");
10592            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10593                    "Starting Norm", "Restarting PERS", dumpPackage);
10594        }
10595
10596        if (mRemovedProcesses.size() > 0) {
10597            if (needSep) pw.println();
10598            needSep = true;
10599            printedAnything = true;
10600            pw.println("  Processes that are being removed:");
10601            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10602                    "Removed Norm", "Removed PERS", dumpPackage);
10603        }
10604
10605        if (mProcessesOnHold.size() > 0) {
10606            if (needSep) pw.println();
10607            needSep = true;
10608            printedAnything = true;
10609            pw.println("  Processes that are on old until the system is ready:");
10610            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10611                    "OnHold Norm", "OnHold PERS", dumpPackage);
10612        }
10613
10614        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10615
10616        if (mProcessCrashTimes.getMap().size() > 0) {
10617            boolean printed = false;
10618            long now = SystemClock.uptimeMillis();
10619            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10620            final int NP = pmap.size();
10621            for (int ip=0; ip<NP; ip++) {
10622                String pname = pmap.keyAt(ip);
10623                SparseArray<Long> uids = pmap.valueAt(ip);
10624                final int N = uids.size();
10625                for (int i=0; i<N; i++) {
10626                    int puid = uids.keyAt(i);
10627                    ProcessRecord r = mProcessNames.get(pname, puid);
10628                    if (dumpPackage != null && (r == null
10629                            || !r.pkgList.containsKey(dumpPackage))) {
10630                        continue;
10631                    }
10632                    if (!printed) {
10633                        if (needSep) pw.println();
10634                        needSep = true;
10635                        pw.println("  Time since processes crashed:");
10636                        printed = true;
10637                        printedAnything = true;
10638                    }
10639                    pw.print("    Process "); pw.print(pname);
10640                            pw.print(" uid "); pw.print(puid);
10641                            pw.print(": last crashed ");
10642                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10643                            pw.println(" ago");
10644                }
10645            }
10646        }
10647
10648        if (mBadProcesses.getMap().size() > 0) {
10649            boolean printed = false;
10650            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10651            final int NP = pmap.size();
10652            for (int ip=0; ip<NP; ip++) {
10653                String pname = pmap.keyAt(ip);
10654                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10655                final int N = uids.size();
10656                for (int i=0; i<N; i++) {
10657                    int puid = uids.keyAt(i);
10658                    ProcessRecord r = mProcessNames.get(pname, puid);
10659                    if (dumpPackage != null && (r == null
10660                            || !r.pkgList.containsKey(dumpPackage))) {
10661                        continue;
10662                    }
10663                    if (!printed) {
10664                        if (needSep) pw.println();
10665                        needSep = true;
10666                        pw.println("  Bad processes:");
10667                        printedAnything = true;
10668                    }
10669                    BadProcessInfo info = uids.valueAt(i);
10670                    pw.print("    Bad process "); pw.print(pname);
10671                            pw.print(" uid "); pw.print(puid);
10672                            pw.print(": crashed at time "); pw.println(info.time);
10673                    if (info.shortMsg != null) {
10674                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10675                    }
10676                    if (info.longMsg != null) {
10677                        pw.print("      Long msg: "); pw.println(info.longMsg);
10678                    }
10679                    if (info.stack != null) {
10680                        pw.println("      Stack:");
10681                        int lastPos = 0;
10682                        for (int pos=0; pos<info.stack.length(); pos++) {
10683                            if (info.stack.charAt(pos) == '\n') {
10684                                pw.print("        ");
10685                                pw.write(info.stack, lastPos, pos-lastPos);
10686                                pw.println();
10687                                lastPos = pos+1;
10688                            }
10689                        }
10690                        if (lastPos < info.stack.length()) {
10691                            pw.print("        ");
10692                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10693                            pw.println();
10694                        }
10695                    }
10696                }
10697            }
10698        }
10699
10700        if (dumpPackage == null) {
10701            pw.println();
10702            needSep = false;
10703            pw.println("  mStartedUsers:");
10704            for (int i=0; i<mStartedUsers.size(); i++) {
10705                UserStartedState uss = mStartedUsers.valueAt(i);
10706                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10707                        pw.print(": "); uss.dump("", pw);
10708            }
10709            pw.print("  mStartedUserArray: [");
10710            for (int i=0; i<mStartedUserArray.length; i++) {
10711                if (i > 0) pw.print(", ");
10712                pw.print(mStartedUserArray[i]);
10713            }
10714            pw.println("]");
10715            pw.print("  mUserLru: [");
10716            for (int i=0; i<mUserLru.size(); i++) {
10717                if (i > 0) pw.print(", ");
10718                pw.print(mUserLru.get(i));
10719            }
10720            pw.println("]");
10721            if (dumpAll) {
10722                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10723            }
10724        }
10725        if (mHomeProcess != null && (dumpPackage == null
10726                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10727            if (needSep) {
10728                pw.println();
10729                needSep = false;
10730            }
10731            pw.println("  mHomeProcess: " + mHomeProcess);
10732        }
10733        if (mPreviousProcess != null && (dumpPackage == null
10734                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10735            if (needSep) {
10736                pw.println();
10737                needSep = false;
10738            }
10739            pw.println("  mPreviousProcess: " + mPreviousProcess);
10740        }
10741        if (dumpAll) {
10742            StringBuilder sb = new StringBuilder(128);
10743            sb.append("  mPreviousProcessVisibleTime: ");
10744            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10745            pw.println(sb);
10746        }
10747        if (mHeavyWeightProcess != null && (dumpPackage == null
10748                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10749            if (needSep) {
10750                pw.println();
10751                needSep = false;
10752            }
10753            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10754        }
10755        if (dumpPackage == null) {
10756            pw.println("  mConfiguration: " + mConfiguration);
10757        }
10758        if (dumpAll) {
10759            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10760            if (mCompatModePackages.getPackages().size() > 0) {
10761                boolean printed = false;
10762                for (Map.Entry<String, Integer> entry
10763                        : mCompatModePackages.getPackages().entrySet()) {
10764                    String pkg = entry.getKey();
10765                    int mode = entry.getValue();
10766                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10767                        continue;
10768                    }
10769                    if (!printed) {
10770                        pw.println("  mScreenCompatPackages:");
10771                        printed = true;
10772                    }
10773                    pw.print("    "); pw.print(pkg); pw.print(": ");
10774                            pw.print(mode); pw.println();
10775                }
10776            }
10777        }
10778        if (dumpPackage == null) {
10779            if (mSleeping || mWentToSleep || mLockScreenShown) {
10780                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10781                        + " mLockScreenShown " + mLockScreenShown);
10782            }
10783            if (mShuttingDown) {
10784                pw.println("  mShuttingDown=" + mShuttingDown);
10785            }
10786        }
10787        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10788                || mOrigWaitForDebugger) {
10789            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10790                    || dumpPackage.equals(mOrigDebugApp)) {
10791                if (needSep) {
10792                    pw.println();
10793                    needSep = false;
10794                }
10795                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10796                        + " mDebugTransient=" + mDebugTransient
10797                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10798            }
10799        }
10800        if (mOpenGlTraceApp != null) {
10801            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10802                if (needSep) {
10803                    pw.println();
10804                    needSep = false;
10805                }
10806                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10807            }
10808        }
10809        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10810                || mProfileFd != null) {
10811            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10812                if (needSep) {
10813                    pw.println();
10814                    needSep = false;
10815                }
10816                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10817                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10818                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10819                        + mAutoStopProfiler);
10820            }
10821        }
10822        if (dumpPackage == null) {
10823            if (mAlwaysFinishActivities || mController != null) {
10824                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10825                        + " mController=" + mController);
10826            }
10827            if (dumpAll) {
10828                pw.println("  Total persistent processes: " + numPers);
10829                pw.println("  mProcessesReady=" + mProcessesReady
10830                        + " mSystemReady=" + mSystemReady);
10831                pw.println("  mBooting=" + mBooting
10832                        + " mBooted=" + mBooted
10833                        + " mFactoryTest=" + mFactoryTest);
10834                pw.print("  mLastPowerCheckRealtime=");
10835                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10836                        pw.println("");
10837                pw.print("  mLastPowerCheckUptime=");
10838                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10839                        pw.println("");
10840                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10841                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10842                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10843                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10844                        + " (" + mLruProcesses.size() + " total)"
10845                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10846                        + " mNumServiceProcs=" + mNumServiceProcs
10847                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10848                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10849                        + " mLastMemoryLevel" + mLastMemoryLevel
10850                        + " mLastNumProcesses" + mLastNumProcesses);
10851                long now = SystemClock.uptimeMillis();
10852                pw.print("  mLastIdleTime=");
10853                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10854                        pw.print(" mLowRamSinceLastIdle=");
10855                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10856                        pw.println();
10857            }
10858        }
10859
10860        if (!printedAnything) {
10861            pw.println("  (nothing)");
10862        }
10863    }
10864
10865    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10866            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10867        if (mProcessesToGc.size() > 0) {
10868            boolean printed = false;
10869            long now = SystemClock.uptimeMillis();
10870            for (int i=0; i<mProcessesToGc.size(); i++) {
10871                ProcessRecord proc = mProcessesToGc.get(i);
10872                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10873                    continue;
10874                }
10875                if (!printed) {
10876                    if (needSep) pw.println();
10877                    needSep = true;
10878                    pw.println("  Processes that are waiting to GC:");
10879                    printed = true;
10880                }
10881                pw.print("    Process "); pw.println(proc);
10882                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
10883                        pw.print(", last gced=");
10884                        pw.print(now-proc.lastRequestedGc);
10885                        pw.print(" ms ago, last lowMem=");
10886                        pw.print(now-proc.lastLowMemory);
10887                        pw.println(" ms ago");
10888
10889            }
10890        }
10891        return needSep;
10892    }
10893
10894    void printOomLevel(PrintWriter pw, String name, int adj) {
10895        pw.print("    ");
10896        if (adj >= 0) {
10897            pw.print(' ');
10898            if (adj < 10) pw.print(' ');
10899        } else {
10900            if (adj > -10) pw.print(' ');
10901        }
10902        pw.print(adj);
10903        pw.print(": ");
10904        pw.print(name);
10905        pw.print(" (");
10906        pw.print(mProcessList.getMemLevel(adj)/1024);
10907        pw.println(" kB)");
10908    }
10909
10910    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10911            int opti, boolean dumpAll) {
10912        boolean needSep = false;
10913
10914        if (mLruProcesses.size() > 0) {
10915            if (needSep) pw.println();
10916            needSep = true;
10917            pw.println("  OOM levels:");
10918            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
10919            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
10920            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
10921            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
10922            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
10923            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
10924            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
10925            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
10926            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
10927            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
10928            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
10929            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
10930            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
10931
10932            if (needSep) pw.println();
10933            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
10934                    pw.print(" total, non-act at ");
10935                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10936                    pw.print(", non-svc at ");
10937                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10938                    pw.println("):");
10939            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
10940            needSep = true;
10941        }
10942
10943        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
10944
10945        pw.println();
10946        pw.println("  mHomeProcess: " + mHomeProcess);
10947        pw.println("  mPreviousProcess: " + mPreviousProcess);
10948        if (mHeavyWeightProcess != null) {
10949            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10950        }
10951
10952        return true;
10953    }
10954
10955    /**
10956     * There are three ways to call this:
10957     *  - no provider specified: dump all the providers
10958     *  - a flattened component name that matched an existing provider was specified as the
10959     *    first arg: dump that one provider
10960     *  - the first arg isn't the flattened component name of an existing provider:
10961     *    dump all providers whose component contains the first arg as a substring
10962     */
10963    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
10964            int opti, boolean dumpAll) {
10965        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
10966    }
10967
10968    static class ItemMatcher {
10969        ArrayList<ComponentName> components;
10970        ArrayList<String> strings;
10971        ArrayList<Integer> objects;
10972        boolean all;
10973
10974        ItemMatcher() {
10975            all = true;
10976        }
10977
10978        void build(String name) {
10979            ComponentName componentName = ComponentName.unflattenFromString(name);
10980            if (componentName != null) {
10981                if (components == null) {
10982                    components = new ArrayList<ComponentName>();
10983                }
10984                components.add(componentName);
10985                all = false;
10986            } else {
10987                int objectId = 0;
10988                // Not a '/' separated full component name; maybe an object ID?
10989                try {
10990                    objectId = Integer.parseInt(name, 16);
10991                    if (objects == null) {
10992                        objects = new ArrayList<Integer>();
10993                    }
10994                    objects.add(objectId);
10995                    all = false;
10996                } catch (RuntimeException e) {
10997                    // Not an integer; just do string match.
10998                    if (strings == null) {
10999                        strings = new ArrayList<String>();
11000                    }
11001                    strings.add(name);
11002                    all = false;
11003                }
11004            }
11005        }
11006
11007        int build(String[] args, int opti) {
11008            for (; opti<args.length; opti++) {
11009                String name = args[opti];
11010                if ("--".equals(name)) {
11011                    return opti+1;
11012                }
11013                build(name);
11014            }
11015            return opti;
11016        }
11017
11018        boolean match(Object object, ComponentName comp) {
11019            if (all) {
11020                return true;
11021            }
11022            if (components != null) {
11023                for (int i=0; i<components.size(); i++) {
11024                    if (components.get(i).equals(comp)) {
11025                        return true;
11026                    }
11027                }
11028            }
11029            if (objects != null) {
11030                for (int i=0; i<objects.size(); i++) {
11031                    if (System.identityHashCode(object) == objects.get(i)) {
11032                        return true;
11033                    }
11034                }
11035            }
11036            if (strings != null) {
11037                String flat = comp.flattenToString();
11038                for (int i=0; i<strings.size(); i++) {
11039                    if (flat.contains(strings.get(i))) {
11040                        return true;
11041                    }
11042                }
11043            }
11044            return false;
11045        }
11046    }
11047
11048    /**
11049     * There are three things that cmd can be:
11050     *  - a flattened component name that matches an existing activity
11051     *  - the cmd arg isn't the flattened component name of an existing activity:
11052     *    dump all activity whose component contains the cmd as a substring
11053     *  - A hex number of the ActivityRecord object instance.
11054     */
11055    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11056            int opti, boolean dumpAll) {
11057        ArrayList<ActivityRecord> activities;
11058
11059        synchronized (this) {
11060            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11061        }
11062
11063        if (activities.size() <= 0) {
11064            return false;
11065        }
11066
11067        String[] newArgs = new String[args.length - opti];
11068        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11069
11070        TaskRecord lastTask = null;
11071        boolean needSep = false;
11072        for (int i=activities.size()-1; i>=0; i--) {
11073            ActivityRecord r = activities.get(i);
11074            if (needSep) {
11075                pw.println();
11076            }
11077            needSep = true;
11078            synchronized (this) {
11079                if (lastTask != r.task) {
11080                    lastTask = r.task;
11081                    pw.print("TASK "); pw.print(lastTask.affinity);
11082                            pw.print(" id="); pw.println(lastTask.taskId);
11083                    if (dumpAll) {
11084                        lastTask.dump(pw, "  ");
11085                    }
11086                }
11087            }
11088            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11089        }
11090        return true;
11091    }
11092
11093    /**
11094     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11095     * there is a thread associated with the activity.
11096     */
11097    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11098            final ActivityRecord r, String[] args, boolean dumpAll) {
11099        String innerPrefix = prefix + "  ";
11100        synchronized (this) {
11101            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11102                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11103                    pw.print(" pid=");
11104                    if (r.app != null) pw.println(r.app.pid);
11105                    else pw.println("(not running)");
11106            if (dumpAll) {
11107                r.dump(pw, innerPrefix);
11108            }
11109        }
11110        if (r.app != null && r.app.thread != null) {
11111            // flush anything that is already in the PrintWriter since the thread is going
11112            // to write to the file descriptor directly
11113            pw.flush();
11114            try {
11115                TransferPipe tp = new TransferPipe();
11116                try {
11117                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11118                            r.appToken, innerPrefix, args);
11119                    tp.go(fd);
11120                } finally {
11121                    tp.kill();
11122                }
11123            } catch (IOException e) {
11124                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11125            } catch (RemoteException e) {
11126                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11127            }
11128        }
11129    }
11130
11131    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11132            int opti, boolean dumpAll, String dumpPackage) {
11133        boolean needSep = false;
11134        boolean onlyHistory = false;
11135        boolean printedAnything = false;
11136
11137        if ("history".equals(dumpPackage)) {
11138            if (opti < args.length && "-s".equals(args[opti])) {
11139                dumpAll = false;
11140            }
11141            onlyHistory = true;
11142            dumpPackage = null;
11143        }
11144
11145        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11146        if (!onlyHistory && dumpAll) {
11147            if (mRegisteredReceivers.size() > 0) {
11148                boolean printed = false;
11149                Iterator it = mRegisteredReceivers.values().iterator();
11150                while (it.hasNext()) {
11151                    ReceiverList r = (ReceiverList)it.next();
11152                    if (dumpPackage != null && (r.app == null ||
11153                            !dumpPackage.equals(r.app.info.packageName))) {
11154                        continue;
11155                    }
11156                    if (!printed) {
11157                        pw.println("  Registered Receivers:");
11158                        needSep = true;
11159                        printed = true;
11160                        printedAnything = true;
11161                    }
11162                    pw.print("  * "); pw.println(r);
11163                    r.dump(pw, "    ");
11164                }
11165            }
11166
11167            if (mReceiverResolver.dump(pw, needSep ?
11168                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11169                    "    ", dumpPackage, false)) {
11170                needSep = true;
11171                printedAnything = true;
11172            }
11173        }
11174
11175        for (BroadcastQueue q : mBroadcastQueues) {
11176            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11177            printedAnything |= needSep;
11178        }
11179
11180        needSep = true;
11181
11182        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11183            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11184                if (needSep) {
11185                    pw.println();
11186                }
11187                needSep = true;
11188                printedAnything = true;
11189                pw.print("  Sticky broadcasts for user ");
11190                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11191                StringBuilder sb = new StringBuilder(128);
11192                for (Map.Entry<String, ArrayList<Intent>> ent
11193                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11194                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11195                    if (dumpAll) {
11196                        pw.println(":");
11197                        ArrayList<Intent> intents = ent.getValue();
11198                        final int N = intents.size();
11199                        for (int i=0; i<N; i++) {
11200                            sb.setLength(0);
11201                            sb.append("    Intent: ");
11202                            intents.get(i).toShortString(sb, false, true, false, false);
11203                            pw.println(sb.toString());
11204                            Bundle bundle = intents.get(i).getExtras();
11205                            if (bundle != null) {
11206                                pw.print("      ");
11207                                pw.println(bundle.toString());
11208                            }
11209                        }
11210                    } else {
11211                        pw.println("");
11212                    }
11213                }
11214            }
11215        }
11216
11217        if (!onlyHistory && dumpAll) {
11218            pw.println();
11219            for (BroadcastQueue queue : mBroadcastQueues) {
11220                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11221                        + queue.mBroadcastsScheduled);
11222            }
11223            pw.println("  mHandler:");
11224            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11225            needSep = true;
11226            printedAnything = true;
11227        }
11228
11229        if (!printedAnything) {
11230            pw.println("  (nothing)");
11231        }
11232    }
11233
11234    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11235            int opti, boolean dumpAll, String dumpPackage) {
11236        boolean needSep;
11237        boolean printedAnything = false;
11238
11239        ItemMatcher matcher = new ItemMatcher();
11240        matcher.build(args, opti);
11241
11242        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11243
11244        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11245        printedAnything |= needSep;
11246
11247        if (mLaunchingProviders.size() > 0) {
11248            boolean printed = false;
11249            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11250                ContentProviderRecord r = mLaunchingProviders.get(i);
11251                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11252                    continue;
11253                }
11254                if (!printed) {
11255                    if (needSep) pw.println();
11256                    needSep = true;
11257                    pw.println("  Launching content providers:");
11258                    printed = true;
11259                    printedAnything = true;
11260                }
11261                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11262                        pw.println(r);
11263            }
11264        }
11265
11266        if (mGrantedUriPermissions.size() > 0) {
11267            boolean printed = false;
11268            int dumpUid = -2;
11269            if (dumpPackage != null) {
11270                try {
11271                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11272                } catch (NameNotFoundException e) {
11273                    dumpUid = -1;
11274                }
11275            }
11276            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11277                int uid = mGrantedUriPermissions.keyAt(i);
11278                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11279                    continue;
11280                }
11281                ArrayMap<Uri, UriPermission> perms
11282                        = mGrantedUriPermissions.valueAt(i);
11283                if (!printed) {
11284                    if (needSep) pw.println();
11285                    needSep = true;
11286                    pw.println("  Granted Uri Permissions:");
11287                    printed = true;
11288                    printedAnything = true;
11289                }
11290                pw.print("  * UID "); pw.print(uid);
11291                        pw.println(" holds:");
11292                for (UriPermission perm : perms.values()) {
11293                    pw.print("    "); pw.println(perm);
11294                    if (dumpAll) {
11295                        perm.dump(pw, "      ");
11296                    }
11297                }
11298            }
11299        }
11300
11301        if (!printedAnything) {
11302            pw.println("  (nothing)");
11303        }
11304    }
11305
11306    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11307            int opti, boolean dumpAll, String dumpPackage) {
11308        boolean printed = false;
11309
11310        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11311
11312        if (mIntentSenderRecords.size() > 0) {
11313            Iterator<WeakReference<PendingIntentRecord>> it
11314                    = mIntentSenderRecords.values().iterator();
11315            while (it.hasNext()) {
11316                WeakReference<PendingIntentRecord> ref = it.next();
11317                PendingIntentRecord rec = ref != null ? ref.get(): null;
11318                if (dumpPackage != null && (rec == null
11319                        || !dumpPackage.equals(rec.key.packageName))) {
11320                    continue;
11321                }
11322                printed = true;
11323                if (rec != null) {
11324                    pw.print("  * "); pw.println(rec);
11325                    if (dumpAll) {
11326                        rec.dump(pw, "    ");
11327                    }
11328                } else {
11329                    pw.print("  * "); pw.println(ref);
11330                }
11331            }
11332        }
11333
11334        if (!printed) {
11335            pw.println("  (nothing)");
11336        }
11337    }
11338
11339    private static final int dumpProcessList(PrintWriter pw,
11340            ActivityManagerService service, List list,
11341            String prefix, String normalLabel, String persistentLabel,
11342            String dumpPackage) {
11343        int numPers = 0;
11344        final int N = list.size()-1;
11345        for (int i=N; i>=0; i--) {
11346            ProcessRecord r = (ProcessRecord)list.get(i);
11347            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11348                continue;
11349            }
11350            pw.println(String.format("%s%s #%2d: %s",
11351                    prefix, (r.persistent ? persistentLabel : normalLabel),
11352                    i, r.toString()));
11353            if (r.persistent) {
11354                numPers++;
11355            }
11356        }
11357        return numPers;
11358    }
11359
11360    private static final boolean dumpProcessOomList(PrintWriter pw,
11361            ActivityManagerService service, List<ProcessRecord> origList,
11362            String prefix, String normalLabel, String persistentLabel,
11363            boolean inclDetails, String dumpPackage) {
11364
11365        ArrayList<Pair<ProcessRecord, Integer>> list
11366                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11367        for (int i=0; i<origList.size(); i++) {
11368            ProcessRecord r = origList.get(i);
11369            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11370                continue;
11371            }
11372            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11373        }
11374
11375        if (list.size() <= 0) {
11376            return false;
11377        }
11378
11379        Comparator<Pair<ProcessRecord, Integer>> comparator
11380                = new Comparator<Pair<ProcessRecord, Integer>>() {
11381            @Override
11382            public int compare(Pair<ProcessRecord, Integer> object1,
11383                    Pair<ProcessRecord, Integer> object2) {
11384                if (object1.first.setAdj != object2.first.setAdj) {
11385                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11386                }
11387                if (object1.second.intValue() != object2.second.intValue()) {
11388                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11389                }
11390                return 0;
11391            }
11392        };
11393
11394        Collections.sort(list, comparator);
11395
11396        final long curRealtime = SystemClock.elapsedRealtime();
11397        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11398        final long curUptime = SystemClock.uptimeMillis();
11399        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11400
11401        for (int i=list.size()-1; i>=0; i--) {
11402            ProcessRecord r = list.get(i).first;
11403            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11404            char schedGroup;
11405            switch (r.setSchedGroup) {
11406                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11407                    schedGroup = 'B';
11408                    break;
11409                case Process.THREAD_GROUP_DEFAULT:
11410                    schedGroup = 'F';
11411                    break;
11412                default:
11413                    schedGroup = '?';
11414                    break;
11415            }
11416            char foreground;
11417            if (r.foregroundActivities) {
11418                foreground = 'A';
11419            } else if (r.foregroundServices) {
11420                foreground = 'S';
11421            } else {
11422                foreground = ' ';
11423            }
11424            String procState = ProcessList.makeProcStateString(r.curProcState);
11425            pw.print(prefix);
11426            pw.print(r.persistent ? persistentLabel : normalLabel);
11427            pw.print(" #");
11428            int num = (origList.size()-1)-list.get(i).second;
11429            if (num < 10) pw.print(' ');
11430            pw.print(num);
11431            pw.print(": ");
11432            pw.print(oomAdj);
11433            pw.print(' ');
11434            pw.print(schedGroup);
11435            pw.print('/');
11436            pw.print(foreground);
11437            pw.print('/');
11438            pw.print(procState);
11439            pw.print(" trm:");
11440            if (r.trimMemoryLevel < 10) pw.print(' ');
11441            pw.print(r.trimMemoryLevel);
11442            pw.print(' ');
11443            pw.print(r.toShortString());
11444            pw.print(" (");
11445            pw.print(r.adjType);
11446            pw.println(')');
11447            if (r.adjSource != null || r.adjTarget != null) {
11448                pw.print(prefix);
11449                pw.print("    ");
11450                if (r.adjTarget instanceof ComponentName) {
11451                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11452                } else if (r.adjTarget != null) {
11453                    pw.print(r.adjTarget.toString());
11454                } else {
11455                    pw.print("{null}");
11456                }
11457                pw.print("<=");
11458                if (r.adjSource instanceof ProcessRecord) {
11459                    pw.print("Proc{");
11460                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11461                    pw.println("}");
11462                } else if (r.adjSource != null) {
11463                    pw.println(r.adjSource.toString());
11464                } else {
11465                    pw.println("{null}");
11466                }
11467            }
11468            if (inclDetails) {
11469                pw.print(prefix);
11470                pw.print("    ");
11471                pw.print("oom: max="); pw.print(r.maxAdj);
11472                pw.print(" curRaw="); pw.print(r.curRawAdj);
11473                pw.print(" setRaw="); pw.print(r.setRawAdj);
11474                pw.print(" cur="); pw.print(r.curAdj);
11475                pw.print(" set="); pw.println(r.setAdj);
11476                pw.print(prefix);
11477                pw.print("    ");
11478                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11479                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11480                pw.print(" lastPss="); pw.print(r.lastPss);
11481                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11482                pw.print(prefix);
11483                pw.print("    ");
11484                pw.print("keeping="); pw.print(r.keeping);
11485                pw.print(" cached="); pw.print(r.cached);
11486                pw.print(" empty="); pw.print(r.empty);
11487                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11488
11489                if (!r.keeping) {
11490                    if (r.lastWakeTime != 0) {
11491                        long wtime;
11492                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11493                        synchronized (stats) {
11494                            wtime = stats.getProcessWakeTime(r.info.uid,
11495                                    r.pid, curRealtime);
11496                        }
11497                        long timeUsed = wtime - r.lastWakeTime;
11498                        pw.print(prefix);
11499                        pw.print("    ");
11500                        pw.print("keep awake over ");
11501                        TimeUtils.formatDuration(realtimeSince, pw);
11502                        pw.print(" used ");
11503                        TimeUtils.formatDuration(timeUsed, pw);
11504                        pw.print(" (");
11505                        pw.print((timeUsed*100)/realtimeSince);
11506                        pw.println("%)");
11507                    }
11508                    if (r.lastCpuTime != 0) {
11509                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11510                        pw.print(prefix);
11511                        pw.print("    ");
11512                        pw.print("run cpu over ");
11513                        TimeUtils.formatDuration(uptimeSince, pw);
11514                        pw.print(" used ");
11515                        TimeUtils.formatDuration(timeUsed, pw);
11516                        pw.print(" (");
11517                        pw.print((timeUsed*100)/uptimeSince);
11518                        pw.println("%)");
11519                    }
11520                }
11521            }
11522        }
11523        return true;
11524    }
11525
11526    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11527        ArrayList<ProcessRecord> procs;
11528        synchronized (this) {
11529            if (args != null && args.length > start
11530                    && args[start].charAt(0) != '-') {
11531                procs = new ArrayList<ProcessRecord>();
11532                int pid = -1;
11533                try {
11534                    pid = Integer.parseInt(args[start]);
11535                } catch (NumberFormatException e) {
11536                }
11537                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11538                    ProcessRecord proc = mLruProcesses.get(i);
11539                    if (proc.pid == pid) {
11540                        procs.add(proc);
11541                    } else if (proc.processName.equals(args[start])) {
11542                        procs.add(proc);
11543                    }
11544                }
11545                if (procs.size() <= 0) {
11546                    return null;
11547                }
11548            } else {
11549                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11550            }
11551        }
11552        return procs;
11553    }
11554
11555    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11556            PrintWriter pw, String[] args) {
11557        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11558        if (procs == null) {
11559            pw.println("No process found for: " + args[0]);
11560            return;
11561        }
11562
11563        long uptime = SystemClock.uptimeMillis();
11564        long realtime = SystemClock.elapsedRealtime();
11565        pw.println("Applications Graphics Acceleration Info:");
11566        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11567
11568        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11569            ProcessRecord r = procs.get(i);
11570            if (r.thread != null) {
11571                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11572                pw.flush();
11573                try {
11574                    TransferPipe tp = new TransferPipe();
11575                    try {
11576                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11577                        tp.go(fd);
11578                    } finally {
11579                        tp.kill();
11580                    }
11581                } catch (IOException e) {
11582                    pw.println("Failure while dumping the app: " + r);
11583                    pw.flush();
11584                } catch (RemoteException e) {
11585                    pw.println("Got a RemoteException while dumping the app " + r);
11586                    pw.flush();
11587                }
11588            }
11589        }
11590    }
11591
11592    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11593        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11594        if (procs == null) {
11595            pw.println("No process found for: " + args[0]);
11596            return;
11597        }
11598
11599        pw.println("Applications Database Info:");
11600
11601        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11602            ProcessRecord r = procs.get(i);
11603            if (r.thread != null) {
11604                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11605                pw.flush();
11606                try {
11607                    TransferPipe tp = new TransferPipe();
11608                    try {
11609                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11610                        tp.go(fd);
11611                    } finally {
11612                        tp.kill();
11613                    }
11614                } catch (IOException e) {
11615                    pw.println("Failure while dumping the app: " + r);
11616                    pw.flush();
11617                } catch (RemoteException e) {
11618                    pw.println("Got a RemoteException while dumping the app " + r);
11619                    pw.flush();
11620                }
11621            }
11622        }
11623    }
11624
11625    final static class MemItem {
11626        final boolean isProc;
11627        final String label;
11628        final String shortLabel;
11629        final long pss;
11630        final int id;
11631        final boolean hasActivities;
11632        ArrayList<MemItem> subitems;
11633
11634        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11635                boolean _hasActivities) {
11636            isProc = true;
11637            label = _label;
11638            shortLabel = _shortLabel;
11639            pss = _pss;
11640            id = _id;
11641            hasActivities = _hasActivities;
11642        }
11643
11644        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11645            isProc = false;
11646            label = _label;
11647            shortLabel = _shortLabel;
11648            pss = _pss;
11649            id = _id;
11650            hasActivities = false;
11651        }
11652    }
11653
11654    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11655            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11656        if (sort && !isCompact) {
11657            Collections.sort(items, new Comparator<MemItem>() {
11658                @Override
11659                public int compare(MemItem lhs, MemItem rhs) {
11660                    if (lhs.pss < rhs.pss) {
11661                        return 1;
11662                    } else if (lhs.pss > rhs.pss) {
11663                        return -1;
11664                    }
11665                    return 0;
11666                }
11667            });
11668        }
11669
11670        for (int i=0; i<items.size(); i++) {
11671            MemItem mi = items.get(i);
11672            if (!isCompact) {
11673                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11674            } else if (mi.isProc) {
11675                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11676                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11677                pw.println(mi.hasActivities ? ",a" : ",e");
11678            } else {
11679                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11680                pw.println(mi.pss);
11681            }
11682            if (mi.subitems != null) {
11683                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11684                        true, isCompact);
11685            }
11686        }
11687    }
11688
11689    // These are in KB.
11690    static final long[] DUMP_MEM_BUCKETS = new long[] {
11691        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11692        120*1024, 160*1024, 200*1024,
11693        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11694        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11695    };
11696
11697    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11698            boolean stackLike) {
11699        int start = label.lastIndexOf('.');
11700        if (start >= 0) start++;
11701        else start = 0;
11702        int end = label.length();
11703        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11704            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11705                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11706                out.append(bucket);
11707                out.append(stackLike ? "MB." : "MB ");
11708                out.append(label, start, end);
11709                return;
11710            }
11711        }
11712        out.append(memKB/1024);
11713        out.append(stackLike ? "MB." : "MB ");
11714        out.append(label, start, end);
11715    }
11716
11717    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11718            ProcessList.NATIVE_ADJ,
11719            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11720            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11721            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11722            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11723            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11724    };
11725    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11726            "Native",
11727            "System", "Persistent", "Foreground",
11728            "Visible", "Perceptible",
11729            "Heavy Weight", "Backup",
11730            "A Services", "Home",
11731            "Previous", "B Services", "Cached"
11732    };
11733    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11734            "native",
11735            "sys", "pers", "fore",
11736            "vis", "percept",
11737            "heavy", "backup",
11738            "servicea", "home",
11739            "prev", "serviceb", "cached"
11740    };
11741
11742    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11743            long realtime, boolean isCheckinRequest, boolean isCompact) {
11744        if (isCheckinRequest || isCompact) {
11745            // short checkin version
11746            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11747        } else {
11748            pw.println("Applications Memory Usage (kB):");
11749            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11750        }
11751    }
11752
11753    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11754            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11755        boolean dumpDetails = false;
11756        boolean dumpFullDetails = false;
11757        boolean dumpDalvik = false;
11758        boolean oomOnly = false;
11759        boolean isCompact = false;
11760        boolean localOnly = false;
11761
11762        int opti = 0;
11763        while (opti < args.length) {
11764            String opt = args[opti];
11765            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11766                break;
11767            }
11768            opti++;
11769            if ("-a".equals(opt)) {
11770                dumpDetails = true;
11771                dumpFullDetails = true;
11772                dumpDalvik = true;
11773            } else if ("-d".equals(opt)) {
11774                dumpDalvik = true;
11775            } else if ("-c".equals(opt)) {
11776                isCompact = true;
11777            } else if ("--oom".equals(opt)) {
11778                oomOnly = true;
11779            } else if ("--local".equals(opt)) {
11780                localOnly = true;
11781            } else if ("-h".equals(opt)) {
11782                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11783                pw.println("  -a: include all available information for each process.");
11784                pw.println("  -d: include dalvik details when dumping process details.");
11785                pw.println("  -c: dump in a compact machine-parseable representation.");
11786                pw.println("  --oom: only show processes organized by oom adj.");
11787                pw.println("  --local: only collect details locally, don't call process.");
11788                pw.println("If [process] is specified it can be the name or ");
11789                pw.println("pid of a specific process to dump.");
11790                return;
11791            } else {
11792                pw.println("Unknown argument: " + opt + "; use -h for help");
11793            }
11794        }
11795
11796        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11797        long uptime = SystemClock.uptimeMillis();
11798        long realtime = SystemClock.elapsedRealtime();
11799        final long[] tmpLong = new long[1];
11800
11801        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11802        if (procs == null) {
11803            // No Java processes.  Maybe they want to print a native process.
11804            if (args != null && args.length > opti
11805                    && args[opti].charAt(0) != '-') {
11806                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11807                        = new ArrayList<ProcessCpuTracker.Stats>();
11808                updateCpuStatsNow();
11809                int findPid = -1;
11810                try {
11811                    findPid = Integer.parseInt(args[opti]);
11812                } catch (NumberFormatException e) {
11813                }
11814                synchronized (mProcessCpuThread) {
11815                    final int N = mProcessCpuTracker.countStats();
11816                    for (int i=0; i<N; i++) {
11817                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11818                        if (st.pid == findPid || (st.baseName != null
11819                                && st.baseName.equals(args[opti]))) {
11820                            nativeProcs.add(st);
11821                        }
11822                    }
11823                }
11824                if (nativeProcs.size() > 0) {
11825                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11826                            isCompact);
11827                    Debug.MemoryInfo mi = null;
11828                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11829                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11830                        final int pid = r.pid;
11831                        if (!isCheckinRequest && dumpDetails) {
11832                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11833                        }
11834                        if (mi == null) {
11835                            mi = new Debug.MemoryInfo();
11836                        }
11837                        if (dumpDetails || (!brief && !oomOnly)) {
11838                            Debug.getMemoryInfo(pid, mi);
11839                        } else {
11840                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11841                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11842                        }
11843                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11844                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11845                        if (isCheckinRequest) {
11846                            pw.println();
11847                        }
11848                    }
11849                    return;
11850                }
11851            }
11852            pw.println("No process found for: " + args[opti]);
11853            return;
11854        }
11855
11856        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11857            dumpDetails = true;
11858        }
11859
11860        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11861
11862        String[] innerArgs = new String[args.length-opti];
11863        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11864
11865        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11866        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11867        long nativePss=0, dalvikPss=0, otherPss=0;
11868        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11869
11870        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11871        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11872                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11873
11874        long totalPss = 0;
11875        long cachedPss = 0;
11876
11877        Debug.MemoryInfo mi = null;
11878        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11879            final ProcessRecord r = procs.get(i);
11880            final IApplicationThread thread;
11881            final int pid;
11882            final int oomAdj;
11883            final boolean hasActivities;
11884            synchronized (this) {
11885                thread = r.thread;
11886                pid = r.pid;
11887                oomAdj = r.getSetAdjWithServices();
11888                hasActivities = r.activities.size() > 0;
11889            }
11890            if (thread != null) {
11891                if (!isCheckinRequest && dumpDetails) {
11892                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
11893                }
11894                if (mi == null) {
11895                    mi = new Debug.MemoryInfo();
11896                }
11897                if (dumpDetails || (!brief && !oomOnly)) {
11898                    Debug.getMemoryInfo(pid, mi);
11899                } else {
11900                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11901                    mi.dalvikPrivateDirty = (int)tmpLong[0];
11902                }
11903                if (dumpDetails) {
11904                    if (localOnly) {
11905                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11906                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
11907                        if (isCheckinRequest) {
11908                            pw.println();
11909                        }
11910                    } else {
11911                        try {
11912                            pw.flush();
11913                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
11914                                    dumpDalvik, innerArgs);
11915                        } catch (RemoteException e) {
11916                            if (!isCheckinRequest) {
11917                                pw.println("Got RemoteException!");
11918                                pw.flush();
11919                            }
11920                        }
11921                    }
11922                }
11923
11924                final long myTotalPss = mi.getTotalPss();
11925                final long myTotalUss = mi.getTotalUss();
11926
11927                synchronized (this) {
11928                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
11929                        // Record this for posterity if the process has been stable.
11930                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
11931                    }
11932                }
11933
11934                if (!isCheckinRequest && mi != null) {
11935                    totalPss += myTotalPss;
11936                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
11937                            (hasActivities ? " / activities)" : ")"),
11938                            r.processName, myTotalPss, pid, hasActivities);
11939                    procMems.add(pssItem);
11940                    procMemsMap.put(pid, pssItem);
11941
11942                    nativePss += mi.nativePss;
11943                    dalvikPss += mi.dalvikPss;
11944                    otherPss += mi.otherPss;
11945                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
11946                        long mem = mi.getOtherPss(j);
11947                        miscPss[j] += mem;
11948                        otherPss -= mem;
11949                    }
11950
11951                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
11952                        cachedPss += myTotalPss;
11953                    }
11954
11955                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
11956                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
11957                                || oomIndex == (oomPss.length-1)) {
11958                            oomPss[oomIndex] += myTotalPss;
11959                            if (oomProcs[oomIndex] == null) {
11960                                oomProcs[oomIndex] = new ArrayList<MemItem>();
11961                            }
11962                            oomProcs[oomIndex].add(pssItem);
11963                            break;
11964                        }
11965                    }
11966                }
11967            }
11968        }
11969
11970        if (!isCheckinRequest && procs.size() > 1) {
11971            // If we are showing aggregations, also look for native processes to
11972            // include so that our aggregations are more accurate.
11973            updateCpuStatsNow();
11974            synchronized (mProcessCpuThread) {
11975                final int N = mProcessCpuTracker.countStats();
11976                for (int i=0; i<N; i++) {
11977                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11978                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
11979                        if (mi == null) {
11980                            mi = new Debug.MemoryInfo();
11981                        }
11982                        if (!brief && !oomOnly) {
11983                            Debug.getMemoryInfo(st.pid, mi);
11984                        } else {
11985                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
11986                            mi.nativePrivateDirty = (int)tmpLong[0];
11987                        }
11988
11989                        final long myTotalPss = mi.getTotalPss();
11990                        totalPss += myTotalPss;
11991
11992                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
11993                                st.name, myTotalPss, st.pid, false);
11994                        procMems.add(pssItem);
11995
11996                        nativePss += mi.nativePss;
11997                        dalvikPss += mi.dalvikPss;
11998                        otherPss += mi.otherPss;
11999                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12000                            long mem = mi.getOtherPss(j);
12001                            miscPss[j] += mem;
12002                            otherPss -= mem;
12003                        }
12004                        oomPss[0] += myTotalPss;
12005                        if (oomProcs[0] == null) {
12006                            oomProcs[0] = new ArrayList<MemItem>();
12007                        }
12008                        oomProcs[0].add(pssItem);
12009                    }
12010                }
12011            }
12012
12013            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12014
12015            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12016            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12017            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12018            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12019                String label = Debug.MemoryInfo.getOtherLabel(j);
12020                catMems.add(new MemItem(label, label, miscPss[j], j));
12021            }
12022
12023            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12024            for (int j=0; j<oomPss.length; j++) {
12025                if (oomPss[j] != 0) {
12026                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12027                            : DUMP_MEM_OOM_LABEL[j];
12028                    MemItem item = new MemItem(label, label, oomPss[j],
12029                            DUMP_MEM_OOM_ADJ[j]);
12030                    item.subitems = oomProcs[j];
12031                    oomMems.add(item);
12032                }
12033            }
12034
12035            if (!brief && !oomOnly && !isCompact) {
12036                pw.println();
12037                pw.println("Total PSS by process:");
12038                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12039                pw.println();
12040            }
12041            if (!isCompact) {
12042                pw.println("Total PSS by OOM adjustment:");
12043            }
12044            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12045            if (!brief && !oomOnly) {
12046                PrintWriter out = categoryPw != null ? categoryPw : pw;
12047                if (!isCompact) {
12048                    out.println();
12049                    out.println("Total PSS by category:");
12050                }
12051                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12052            }
12053            if (!isCompact) {
12054                pw.println();
12055            }
12056            MemInfoReader memInfo = new MemInfoReader();
12057            memInfo.readMemInfo();
12058            if (!brief) {
12059                if (!isCompact) {
12060                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12061                    pw.println(" kB");
12062                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12063                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12064                            pw.print(cachedPss); pw.print(" cached pss + ");
12065                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12066                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12067                } else {
12068                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12069                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12070                            + memInfo.getFreeSizeKb()); pw.print(",");
12071                    pw.println(totalPss - cachedPss);
12072                }
12073            }
12074            if (!isCompact) {
12075                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12076                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12077                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12078                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12079                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12080                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12081                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12082                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12083                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12084                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12085                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12086            }
12087            if (!brief) {
12088                if (memInfo.getZramTotalSizeKb() != 0) {
12089                    if (!isCompact) {
12090                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12091                                pw.print(" kB physical used for ");
12092                                pw.print(memInfo.getSwapTotalSizeKb()
12093                                        - memInfo.getSwapFreeSizeKb());
12094                                pw.print(" kB in swap (");
12095                                pw.print(memInfo.getSwapTotalSizeKb());
12096                                pw.println(" kB total swap)");
12097                    } else {
12098                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12099                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12100                                pw.println(memInfo.getSwapFreeSizeKb());
12101                    }
12102                }
12103                final int[] SINGLE_LONG_FORMAT = new int[] {
12104                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12105                };
12106                long[] longOut = new long[1];
12107                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12108                        SINGLE_LONG_FORMAT, null, longOut, null);
12109                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12110                longOut[0] = 0;
12111                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12112                        SINGLE_LONG_FORMAT, null, longOut, null);
12113                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12114                longOut[0] = 0;
12115                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12116                        SINGLE_LONG_FORMAT, null, longOut, null);
12117                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12118                longOut[0] = 0;
12119                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12120                        SINGLE_LONG_FORMAT, null, longOut, null);
12121                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12122                if (!isCompact) {
12123                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12124                        pw.print("      KSM: "); pw.print(sharing);
12125                                pw.print(" kB saved from shared ");
12126                                pw.print(shared); pw.println(" kB");
12127                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12128                                pw.print(voltile); pw.println(" kB volatile");
12129                    }
12130                    pw.print("   Tuning: ");
12131                    pw.print(ActivityManager.staticGetMemoryClass());
12132                    pw.print(" (large ");
12133                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12134                    pw.print("), oom ");
12135                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12136                    pw.print(" kB");
12137                    pw.print(", restore limit ");
12138                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12139                    pw.print(" kB");
12140                    if (ActivityManager.isLowRamDeviceStatic()) {
12141                        pw.print(" (low-ram)");
12142                    }
12143                    if (ActivityManager.isHighEndGfx()) {
12144                        pw.print(" (high-end-gfx)");
12145                    }
12146                    pw.println();
12147                } else {
12148                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12149                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12150                    pw.println(voltile);
12151                    pw.print("tuning,");
12152                    pw.print(ActivityManager.staticGetMemoryClass());
12153                    pw.print(',');
12154                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12155                    pw.print(',');
12156                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12157                    if (ActivityManager.isLowRamDeviceStatic()) {
12158                        pw.print(",low-ram");
12159                    }
12160                    if (ActivityManager.isHighEndGfx()) {
12161                        pw.print(",high-end-gfx");
12162                    }
12163                    pw.println();
12164                }
12165            }
12166        }
12167    }
12168
12169    /**
12170     * Searches array of arguments for the specified string
12171     * @param args array of argument strings
12172     * @param value value to search for
12173     * @return true if the value is contained in the array
12174     */
12175    private static boolean scanArgs(String[] args, String value) {
12176        if (args != null) {
12177            for (String arg : args) {
12178                if (value.equals(arg)) {
12179                    return true;
12180                }
12181            }
12182        }
12183        return false;
12184    }
12185
12186    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12187            ContentProviderRecord cpr, boolean always) {
12188        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12189
12190        if (!inLaunching || always) {
12191            synchronized (cpr) {
12192                cpr.launchingApp = null;
12193                cpr.notifyAll();
12194            }
12195            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12196            String names[] = cpr.info.authority.split(";");
12197            for (int j = 0; j < names.length; j++) {
12198                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12199            }
12200        }
12201
12202        for (int i=0; i<cpr.connections.size(); i++) {
12203            ContentProviderConnection conn = cpr.connections.get(i);
12204            if (conn.waiting) {
12205                // If this connection is waiting for the provider, then we don't
12206                // need to mess with its process unless we are always removing
12207                // or for some reason the provider is not currently launching.
12208                if (inLaunching && !always) {
12209                    continue;
12210                }
12211            }
12212            ProcessRecord capp = conn.client;
12213            conn.dead = true;
12214            if (conn.stableCount > 0) {
12215                if (!capp.persistent && capp.thread != null
12216                        && capp.pid != 0
12217                        && capp.pid != MY_PID) {
12218                    killUnneededProcessLocked(capp, "depends on provider "
12219                            + cpr.name.flattenToShortString()
12220                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12221                }
12222            } else if (capp.thread != null && conn.provider.provider != null) {
12223                try {
12224                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12225                } catch (RemoteException e) {
12226                }
12227                // In the protocol here, we don't expect the client to correctly
12228                // clean up this connection, we'll just remove it.
12229                cpr.connections.remove(i);
12230                conn.client.conProviders.remove(conn);
12231            }
12232        }
12233
12234        if (inLaunching && always) {
12235            mLaunchingProviders.remove(cpr);
12236        }
12237        return inLaunching;
12238    }
12239
12240    /**
12241     * Main code for cleaning up a process when it has gone away.  This is
12242     * called both as a result of the process dying, or directly when stopping
12243     * a process when running in single process mode.
12244     */
12245    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12246            boolean restarting, boolean allowRestart, int index) {
12247        if (index >= 0) {
12248            removeLruProcessLocked(app);
12249            ProcessList.remove(app.pid);
12250        }
12251
12252        mProcessesToGc.remove(app);
12253        mPendingPssProcesses.remove(app);
12254
12255        // Dismiss any open dialogs.
12256        if (app.crashDialog != null && !app.forceCrashReport) {
12257            app.crashDialog.dismiss();
12258            app.crashDialog = null;
12259        }
12260        if (app.anrDialog != null) {
12261            app.anrDialog.dismiss();
12262            app.anrDialog = null;
12263        }
12264        if (app.waitDialog != null) {
12265            app.waitDialog.dismiss();
12266            app.waitDialog = null;
12267        }
12268
12269        app.crashing = false;
12270        app.notResponding = false;
12271
12272        app.resetPackageList(mProcessStats);
12273        app.unlinkDeathRecipient();
12274        app.makeInactive(mProcessStats);
12275        app.forcingToForeground = null;
12276        app.foregroundServices = false;
12277        app.foregroundActivities = false;
12278        app.hasShownUi = false;
12279        app.hasAboveClient = false;
12280
12281        mServices.killServicesLocked(app, allowRestart);
12282
12283        boolean restart = false;
12284
12285        // Remove published content providers.
12286        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12287            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12288            final boolean always = app.bad || !allowRestart;
12289            if (removeDyingProviderLocked(app, cpr, always) || always) {
12290                // We left the provider in the launching list, need to
12291                // restart it.
12292                restart = true;
12293            }
12294
12295            cpr.provider = null;
12296            cpr.proc = null;
12297        }
12298        app.pubProviders.clear();
12299
12300        // Take care of any launching providers waiting for this process.
12301        if (checkAppInLaunchingProvidersLocked(app, false)) {
12302            restart = true;
12303        }
12304
12305        // Unregister from connected content providers.
12306        if (!app.conProviders.isEmpty()) {
12307            for (int i=0; i<app.conProviders.size(); i++) {
12308                ContentProviderConnection conn = app.conProviders.get(i);
12309                conn.provider.connections.remove(conn);
12310            }
12311            app.conProviders.clear();
12312        }
12313
12314        // At this point there may be remaining entries in mLaunchingProviders
12315        // where we were the only one waiting, so they are no longer of use.
12316        // Look for these and clean up if found.
12317        // XXX Commented out for now.  Trying to figure out a way to reproduce
12318        // the actual situation to identify what is actually going on.
12319        if (false) {
12320            for (int i=0; i<mLaunchingProviders.size(); i++) {
12321                ContentProviderRecord cpr = (ContentProviderRecord)
12322                        mLaunchingProviders.get(i);
12323                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12324                    synchronized (cpr) {
12325                        cpr.launchingApp = null;
12326                        cpr.notifyAll();
12327                    }
12328                }
12329            }
12330        }
12331
12332        skipCurrentReceiverLocked(app);
12333
12334        // Unregister any receivers.
12335        for (int i=app.receivers.size()-1; i>=0; i--) {
12336            removeReceiverLocked(app.receivers.valueAt(i));
12337        }
12338        app.receivers.clear();
12339
12340        // If the app is undergoing backup, tell the backup manager about it
12341        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12342            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12343                    + mBackupTarget.appInfo + " died during backup");
12344            try {
12345                IBackupManager bm = IBackupManager.Stub.asInterface(
12346                        ServiceManager.getService(Context.BACKUP_SERVICE));
12347                bm.agentDisconnected(app.info.packageName);
12348            } catch (RemoteException e) {
12349                // can't happen; backup manager is local
12350            }
12351        }
12352
12353        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12354            ProcessChangeItem item = mPendingProcessChanges.get(i);
12355            if (item.pid == app.pid) {
12356                mPendingProcessChanges.remove(i);
12357                mAvailProcessChanges.add(item);
12358            }
12359        }
12360        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12361
12362        // If the caller is restarting this app, then leave it in its
12363        // current lists and let the caller take care of it.
12364        if (restarting) {
12365            return;
12366        }
12367
12368        if (!app.persistent || app.isolated) {
12369            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12370                    "Removing non-persistent process during cleanup: " + app);
12371            mProcessNames.remove(app.processName, app.uid);
12372            mIsolatedProcesses.remove(app.uid);
12373            if (mHeavyWeightProcess == app) {
12374                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12375                        mHeavyWeightProcess.userId, 0));
12376                mHeavyWeightProcess = null;
12377            }
12378        } else if (!app.removed) {
12379            // This app is persistent, so we need to keep its record around.
12380            // If it is not already on the pending app list, add it there
12381            // and start a new process for it.
12382            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12383                mPersistentStartingProcesses.add(app);
12384                restart = true;
12385            }
12386        }
12387        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12388                "Clean-up removing on hold: " + app);
12389        mProcessesOnHold.remove(app);
12390
12391        if (app == mHomeProcess) {
12392            mHomeProcess = null;
12393        }
12394        if (app == mPreviousProcess) {
12395            mPreviousProcess = null;
12396        }
12397
12398        if (restart && !app.isolated) {
12399            // We have components that still need to be running in the
12400            // process, so re-launch it.
12401            mProcessNames.put(app.processName, app.uid, app);
12402            startProcessLocked(app, "restart", app.processName);
12403        } else if (app.pid > 0 && app.pid != MY_PID) {
12404            // Goodbye!
12405            synchronized (mPidsSelfLocked) {
12406                mPidsSelfLocked.remove(app.pid);
12407                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12408            }
12409            app.setPid(0);
12410        }
12411    }
12412
12413    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12414        // Look through the content providers we are waiting to have launched,
12415        // and if any run in this process then either schedule a restart of
12416        // the process or kill the client waiting for it if this process has
12417        // gone bad.
12418        int NL = mLaunchingProviders.size();
12419        boolean restart = false;
12420        for (int i=0; i<NL; i++) {
12421            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12422            if (cpr.launchingApp == app) {
12423                if (!alwaysBad && !app.bad) {
12424                    restart = true;
12425                } else {
12426                    removeDyingProviderLocked(app, cpr, true);
12427                    // cpr should have been removed from mLaunchingProviders
12428                    NL = mLaunchingProviders.size();
12429                    i--;
12430                }
12431            }
12432        }
12433        return restart;
12434    }
12435
12436    // =========================================================
12437    // SERVICES
12438    // =========================================================
12439
12440    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12441            int flags) {
12442        enforceNotIsolatedCaller("getServices");
12443        synchronized (this) {
12444            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12445        }
12446    }
12447
12448    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12449        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12450        synchronized (this) {
12451            return mServices.getRunningServiceControlPanelLocked(name);
12452        }
12453    }
12454
12455    public ComponentName startService(IApplicationThread caller, Intent service,
12456            String resolvedType, int userId) {
12457        enforceNotIsolatedCaller("startService");
12458        // Refuse possible leaked file descriptors
12459        if (service != null && service.hasFileDescriptors() == true) {
12460            throw new IllegalArgumentException("File descriptors passed in Intent");
12461        }
12462
12463        if (DEBUG_SERVICE)
12464            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12465        synchronized(this) {
12466            final int callingPid = Binder.getCallingPid();
12467            final int callingUid = Binder.getCallingUid();
12468            final long origId = Binder.clearCallingIdentity();
12469            ComponentName res = mServices.startServiceLocked(caller, service,
12470                    resolvedType, callingPid, callingUid, userId);
12471            Binder.restoreCallingIdentity(origId);
12472            return res;
12473        }
12474    }
12475
12476    ComponentName startServiceInPackage(int uid,
12477            Intent service, String resolvedType, int userId) {
12478        synchronized(this) {
12479            if (DEBUG_SERVICE)
12480                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12481            final long origId = Binder.clearCallingIdentity();
12482            ComponentName res = mServices.startServiceLocked(null, service,
12483                    resolvedType, -1, uid, userId);
12484            Binder.restoreCallingIdentity(origId);
12485            return res;
12486        }
12487    }
12488
12489    public int stopService(IApplicationThread caller, Intent service,
12490            String resolvedType, int userId) {
12491        enforceNotIsolatedCaller("stopService");
12492        // Refuse possible leaked file descriptors
12493        if (service != null && service.hasFileDescriptors() == true) {
12494            throw new IllegalArgumentException("File descriptors passed in Intent");
12495        }
12496
12497        synchronized(this) {
12498            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12499        }
12500    }
12501
12502    public IBinder peekService(Intent service, String resolvedType) {
12503        enforceNotIsolatedCaller("peekService");
12504        // Refuse possible leaked file descriptors
12505        if (service != null && service.hasFileDescriptors() == true) {
12506            throw new IllegalArgumentException("File descriptors passed in Intent");
12507        }
12508        synchronized(this) {
12509            return mServices.peekServiceLocked(service, resolvedType);
12510        }
12511    }
12512
12513    public boolean stopServiceToken(ComponentName className, IBinder token,
12514            int startId) {
12515        synchronized(this) {
12516            return mServices.stopServiceTokenLocked(className, token, startId);
12517        }
12518    }
12519
12520    public void setServiceForeground(ComponentName className, IBinder token,
12521            int id, Notification notification, boolean removeNotification) {
12522        synchronized(this) {
12523            mServices.setServiceForegroundLocked(className, token, id, notification,
12524                    removeNotification);
12525        }
12526    }
12527
12528    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12529            boolean requireFull, String name, String callerPackage) {
12530        final int callingUserId = UserHandle.getUserId(callingUid);
12531        if (callingUserId != userId) {
12532            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12533                if ((requireFull || checkComponentPermission(
12534                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12535                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12536                        && checkComponentPermission(
12537                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12538                                callingPid, callingUid, -1, true)
12539                                != PackageManager.PERMISSION_GRANTED) {
12540                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12541                        // In this case, they would like to just execute as their
12542                        // owner user instead of failing.
12543                        userId = callingUserId;
12544                    } else {
12545                        StringBuilder builder = new StringBuilder(128);
12546                        builder.append("Permission Denial: ");
12547                        builder.append(name);
12548                        if (callerPackage != null) {
12549                            builder.append(" from ");
12550                            builder.append(callerPackage);
12551                        }
12552                        builder.append(" asks to run as user ");
12553                        builder.append(userId);
12554                        builder.append(" but is calling from user ");
12555                        builder.append(UserHandle.getUserId(callingUid));
12556                        builder.append("; this requires ");
12557                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12558                        if (!requireFull) {
12559                            builder.append(" or ");
12560                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12561                        }
12562                        String msg = builder.toString();
12563                        Slog.w(TAG, msg);
12564                        throw new SecurityException(msg);
12565                    }
12566                }
12567            }
12568            if (userId == UserHandle.USER_CURRENT
12569                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12570                // Note that we may be accessing this outside of a lock...
12571                // shouldn't be a big deal, if this is being called outside
12572                // of a locked context there is intrinsically a race with
12573                // the value the caller will receive and someone else changing it.
12574                userId = mCurrentUserId;
12575            }
12576            if (!allowAll && userId < 0) {
12577                throw new IllegalArgumentException(
12578                        "Call does not support special user #" + userId);
12579            }
12580        }
12581        return userId;
12582    }
12583
12584    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12585            String className, int flags) {
12586        boolean result = false;
12587        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12588            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12589                if (ActivityManager.checkUidPermission(
12590                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12591                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12592                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12593                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12594                            + " requests FLAG_SINGLE_USER, but app does not hold "
12595                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12596                    Slog.w(TAG, msg);
12597                    throw new SecurityException(msg);
12598                }
12599                result = true;
12600            }
12601        } else if (componentProcessName == aInfo.packageName) {
12602            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12603        } else if ("system".equals(componentProcessName)) {
12604            result = true;
12605        }
12606        if (DEBUG_MU) {
12607            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12608                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12609        }
12610        return result;
12611    }
12612
12613    public int bindService(IApplicationThread caller, IBinder token,
12614            Intent service, String resolvedType,
12615            IServiceConnection connection, int flags, int userId) {
12616        enforceNotIsolatedCaller("bindService");
12617        // Refuse possible leaked file descriptors
12618        if (service != null && service.hasFileDescriptors() == true) {
12619            throw new IllegalArgumentException("File descriptors passed in Intent");
12620        }
12621
12622        synchronized(this) {
12623            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12624                    connection, flags, userId);
12625        }
12626    }
12627
12628    public boolean unbindService(IServiceConnection connection) {
12629        synchronized (this) {
12630            return mServices.unbindServiceLocked(connection);
12631        }
12632    }
12633
12634    public void publishService(IBinder token, Intent intent, IBinder service) {
12635        // Refuse possible leaked file descriptors
12636        if (intent != null && intent.hasFileDescriptors() == true) {
12637            throw new IllegalArgumentException("File descriptors passed in Intent");
12638        }
12639
12640        synchronized(this) {
12641            if (!(token instanceof ServiceRecord)) {
12642                throw new IllegalArgumentException("Invalid service token");
12643            }
12644            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12645        }
12646    }
12647
12648    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12649        // Refuse possible leaked file descriptors
12650        if (intent != null && intent.hasFileDescriptors() == true) {
12651            throw new IllegalArgumentException("File descriptors passed in Intent");
12652        }
12653
12654        synchronized(this) {
12655            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12656        }
12657    }
12658
12659    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12660        synchronized(this) {
12661            if (!(token instanceof ServiceRecord)) {
12662                throw new IllegalArgumentException("Invalid service token");
12663            }
12664            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12665        }
12666    }
12667
12668    // =========================================================
12669    // BACKUP AND RESTORE
12670    // =========================================================
12671
12672    // Cause the target app to be launched if necessary and its backup agent
12673    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12674    // activity manager to announce its creation.
12675    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12676        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12677        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12678
12679        synchronized(this) {
12680            // !!! TODO: currently no check here that we're already bound
12681            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12682            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12683            synchronized (stats) {
12684                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12685            }
12686
12687            // Backup agent is now in use, its package can't be stopped.
12688            try {
12689                AppGlobals.getPackageManager().setPackageStoppedState(
12690                        app.packageName, false, UserHandle.getUserId(app.uid));
12691            } catch (RemoteException e) {
12692            } catch (IllegalArgumentException e) {
12693                Slog.w(TAG, "Failed trying to unstop package "
12694                        + app.packageName + ": " + e);
12695            }
12696
12697            BackupRecord r = new BackupRecord(ss, app, backupMode);
12698            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12699                    ? new ComponentName(app.packageName, app.backupAgentName)
12700                    : new ComponentName("android", "FullBackupAgent");
12701            // startProcessLocked() returns existing proc's record if it's already running
12702            ProcessRecord proc = startProcessLocked(app.processName, app,
12703                    false, 0, "backup", hostingName, false, false, false);
12704            if (proc == null) {
12705                Slog.e(TAG, "Unable to start backup agent process " + r);
12706                return false;
12707            }
12708
12709            r.app = proc;
12710            mBackupTarget = r;
12711            mBackupAppName = app.packageName;
12712
12713            // Try not to kill the process during backup
12714            updateOomAdjLocked(proc);
12715
12716            // If the process is already attached, schedule the creation of the backup agent now.
12717            // If it is not yet live, this will be done when it attaches to the framework.
12718            if (proc.thread != null) {
12719                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12720                try {
12721                    proc.thread.scheduleCreateBackupAgent(app,
12722                            compatibilityInfoForPackageLocked(app), backupMode);
12723                } catch (RemoteException e) {
12724                    // Will time out on the backup manager side
12725                }
12726            } else {
12727                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12728            }
12729            // Invariants: at this point, the target app process exists and the application
12730            // is either already running or in the process of coming up.  mBackupTarget and
12731            // mBackupAppName describe the app, so that when it binds back to the AM we
12732            // know that it's scheduled for a backup-agent operation.
12733        }
12734
12735        return true;
12736    }
12737
12738    @Override
12739    public void clearPendingBackup() {
12740        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12741        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12742
12743        synchronized (this) {
12744            mBackupTarget = null;
12745            mBackupAppName = null;
12746        }
12747    }
12748
12749    // A backup agent has just come up
12750    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12751        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12752                + " = " + agent);
12753
12754        synchronized(this) {
12755            if (!agentPackageName.equals(mBackupAppName)) {
12756                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12757                return;
12758            }
12759        }
12760
12761        long oldIdent = Binder.clearCallingIdentity();
12762        try {
12763            IBackupManager bm = IBackupManager.Stub.asInterface(
12764                    ServiceManager.getService(Context.BACKUP_SERVICE));
12765            bm.agentConnected(agentPackageName, agent);
12766        } catch (RemoteException e) {
12767            // can't happen; the backup manager service is local
12768        } catch (Exception e) {
12769            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12770            e.printStackTrace();
12771        } finally {
12772            Binder.restoreCallingIdentity(oldIdent);
12773        }
12774    }
12775
12776    // done with this agent
12777    public void unbindBackupAgent(ApplicationInfo appInfo) {
12778        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12779        if (appInfo == null) {
12780            Slog.w(TAG, "unbind backup agent for null app");
12781            return;
12782        }
12783
12784        synchronized(this) {
12785            try {
12786                if (mBackupAppName == null) {
12787                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12788                    return;
12789                }
12790
12791                if (!mBackupAppName.equals(appInfo.packageName)) {
12792                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12793                    return;
12794                }
12795
12796                // Not backing this app up any more; reset its OOM adjustment
12797                final ProcessRecord proc = mBackupTarget.app;
12798                updateOomAdjLocked(proc);
12799
12800                // If the app crashed during backup, 'thread' will be null here
12801                if (proc.thread != null) {
12802                    try {
12803                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12804                                compatibilityInfoForPackageLocked(appInfo));
12805                    } catch (Exception e) {
12806                        Slog.e(TAG, "Exception when unbinding backup agent:");
12807                        e.printStackTrace();
12808                    }
12809                }
12810            } finally {
12811                mBackupTarget = null;
12812                mBackupAppName = null;
12813            }
12814        }
12815    }
12816    // =========================================================
12817    // BROADCASTS
12818    // =========================================================
12819
12820    private final List getStickiesLocked(String action, IntentFilter filter,
12821            List cur, int userId) {
12822        final ContentResolver resolver = mContext.getContentResolver();
12823        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12824        if (stickies == null) {
12825            return cur;
12826        }
12827        final ArrayList<Intent> list = stickies.get(action);
12828        if (list == null) {
12829            return cur;
12830        }
12831        int N = list.size();
12832        for (int i=0; i<N; i++) {
12833            Intent intent = list.get(i);
12834            if (filter.match(resolver, intent, true, TAG) >= 0) {
12835                if (cur == null) {
12836                    cur = new ArrayList<Intent>();
12837                }
12838                cur.add(intent);
12839            }
12840        }
12841        return cur;
12842    }
12843
12844    boolean isPendingBroadcastProcessLocked(int pid) {
12845        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12846                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12847    }
12848
12849    void skipPendingBroadcastLocked(int pid) {
12850            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12851            for (BroadcastQueue queue : mBroadcastQueues) {
12852                queue.skipPendingBroadcastLocked(pid);
12853            }
12854    }
12855
12856    // The app just attached; send any pending broadcasts that it should receive
12857    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12858        boolean didSomething = false;
12859        for (BroadcastQueue queue : mBroadcastQueues) {
12860            didSomething |= queue.sendPendingBroadcastsLocked(app);
12861        }
12862        return didSomething;
12863    }
12864
12865    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12866            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
12867        enforceNotIsolatedCaller("registerReceiver");
12868        int callingUid;
12869        int callingPid;
12870        synchronized(this) {
12871            ProcessRecord callerApp = null;
12872            if (caller != null) {
12873                callerApp = getRecordForAppLocked(caller);
12874                if (callerApp == null) {
12875                    throw new SecurityException(
12876                            "Unable to find app for caller " + caller
12877                            + " (pid=" + Binder.getCallingPid()
12878                            + ") when registering receiver " + receiver);
12879                }
12880                if (callerApp.info.uid != Process.SYSTEM_UID &&
12881                        !callerApp.pkgList.containsKey(callerPackage) &&
12882                        !"android".equals(callerPackage)) {
12883                    throw new SecurityException("Given caller package " + callerPackage
12884                            + " is not running in process " + callerApp);
12885                }
12886                callingUid = callerApp.info.uid;
12887                callingPid = callerApp.pid;
12888            } else {
12889                callerPackage = null;
12890                callingUid = Binder.getCallingUid();
12891                callingPid = Binder.getCallingPid();
12892            }
12893
12894            userId = this.handleIncomingUser(callingPid, callingUid, userId,
12895                    true, true, "registerReceiver", callerPackage);
12896
12897            List allSticky = null;
12898
12899            // Look for any matching sticky broadcasts...
12900            Iterator actions = filter.actionsIterator();
12901            if (actions != null) {
12902                while (actions.hasNext()) {
12903                    String action = (String)actions.next();
12904                    allSticky = getStickiesLocked(action, filter, allSticky,
12905                            UserHandle.USER_ALL);
12906                    allSticky = getStickiesLocked(action, filter, allSticky,
12907                            UserHandle.getUserId(callingUid));
12908                }
12909            } else {
12910                allSticky = getStickiesLocked(null, filter, allSticky,
12911                        UserHandle.USER_ALL);
12912                allSticky = getStickiesLocked(null, filter, allSticky,
12913                        UserHandle.getUserId(callingUid));
12914            }
12915
12916            // The first sticky in the list is returned directly back to
12917            // the client.
12918            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12919
12920            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
12921                    + ": " + sticky);
12922
12923            if (receiver == null) {
12924                return sticky;
12925            }
12926
12927            ReceiverList rl
12928                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12929            if (rl == null) {
12930                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
12931                        userId, receiver);
12932                if (rl.app != null) {
12933                    rl.app.receivers.add(rl);
12934                } else {
12935                    try {
12936                        receiver.asBinder().linkToDeath(rl, 0);
12937                    } catch (RemoteException e) {
12938                        return sticky;
12939                    }
12940                    rl.linkedToDeath = true;
12941                }
12942                mRegisteredReceivers.put(receiver.asBinder(), rl);
12943            } else if (rl.uid != callingUid) {
12944                throw new IllegalArgumentException(
12945                        "Receiver requested to register for uid " + callingUid
12946                        + " was previously registered for uid " + rl.uid);
12947            } else if (rl.pid != callingPid) {
12948                throw new IllegalArgumentException(
12949                        "Receiver requested to register for pid " + callingPid
12950                        + " was previously registered for pid " + rl.pid);
12951            } else if (rl.userId != userId) {
12952                throw new IllegalArgumentException(
12953                        "Receiver requested to register for user " + userId
12954                        + " was previously registered for user " + rl.userId);
12955            }
12956            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
12957                    permission, callingUid, userId);
12958            rl.add(bf);
12959            if (!bf.debugCheck()) {
12960                Slog.w(TAG, "==> For Dynamic broadast");
12961            }
12962            mReceiverResolver.addFilter(bf);
12963
12964            // Enqueue broadcasts for all existing stickies that match
12965            // this filter.
12966            if (allSticky != null) {
12967                ArrayList receivers = new ArrayList();
12968                receivers.add(bf);
12969
12970                int N = allSticky.size();
12971                for (int i=0; i<N; i++) {
12972                    Intent intent = (Intent)allSticky.get(i);
12973                    BroadcastQueue queue = broadcastQueueForIntent(intent);
12974                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
12975                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
12976                            null, null, false, true, true, -1);
12977                    queue.enqueueParallelBroadcastLocked(r);
12978                    queue.scheduleBroadcastsLocked();
12979                }
12980            }
12981
12982            return sticky;
12983        }
12984    }
12985
12986    public void unregisterReceiver(IIntentReceiver receiver) {
12987        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
12988
12989        final long origId = Binder.clearCallingIdentity();
12990        try {
12991            boolean doTrim = false;
12992
12993            synchronized(this) {
12994                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
12995                if (rl != null) {
12996                    if (rl.curBroadcast != null) {
12997                        BroadcastRecord r = rl.curBroadcast;
12998                        final boolean doNext = finishReceiverLocked(
12999                                receiver.asBinder(), r.resultCode, r.resultData,
13000                                r.resultExtras, r.resultAbort);
13001                        if (doNext) {
13002                            doTrim = true;
13003                            r.queue.processNextBroadcast(false);
13004                        }
13005                    }
13006
13007                    if (rl.app != null) {
13008                        rl.app.receivers.remove(rl);
13009                    }
13010                    removeReceiverLocked(rl);
13011                    if (rl.linkedToDeath) {
13012                        rl.linkedToDeath = false;
13013                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13014                    }
13015                }
13016            }
13017
13018            // If we actually concluded any broadcasts, we might now be able
13019            // to trim the recipients' apps from our working set
13020            if (doTrim) {
13021                trimApplications();
13022                return;
13023            }
13024
13025        } finally {
13026            Binder.restoreCallingIdentity(origId);
13027        }
13028    }
13029
13030    void removeReceiverLocked(ReceiverList rl) {
13031        mRegisteredReceivers.remove(rl.receiver.asBinder());
13032        int N = rl.size();
13033        for (int i=0; i<N; i++) {
13034            mReceiverResolver.removeFilter(rl.get(i));
13035        }
13036    }
13037
13038    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13039        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13040            ProcessRecord r = mLruProcesses.get(i);
13041            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13042                try {
13043                    r.thread.dispatchPackageBroadcast(cmd, packages);
13044                } catch (RemoteException ex) {
13045                }
13046            }
13047        }
13048    }
13049
13050    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13051            int[] users) {
13052        List<ResolveInfo> receivers = null;
13053        try {
13054            HashSet<ComponentName> singleUserReceivers = null;
13055            boolean scannedFirstReceivers = false;
13056            for (int user : users) {
13057                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13058                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13059                if (user != 0 && newReceivers != null) {
13060                    // If this is not the primary user, we need to check for
13061                    // any receivers that should be filtered out.
13062                    for (int i=0; i<newReceivers.size(); i++) {
13063                        ResolveInfo ri = newReceivers.get(i);
13064                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13065                            newReceivers.remove(i);
13066                            i--;
13067                        }
13068                    }
13069                }
13070                if (newReceivers != null && newReceivers.size() == 0) {
13071                    newReceivers = null;
13072                }
13073                if (receivers == null) {
13074                    receivers = newReceivers;
13075                } else if (newReceivers != null) {
13076                    // We need to concatenate the additional receivers
13077                    // found with what we have do far.  This would be easy,
13078                    // but we also need to de-dup any receivers that are
13079                    // singleUser.
13080                    if (!scannedFirstReceivers) {
13081                        // Collect any single user receivers we had already retrieved.
13082                        scannedFirstReceivers = true;
13083                        for (int i=0; i<receivers.size(); i++) {
13084                            ResolveInfo ri = receivers.get(i);
13085                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13086                                ComponentName cn = new ComponentName(
13087                                        ri.activityInfo.packageName, ri.activityInfo.name);
13088                                if (singleUserReceivers == null) {
13089                                    singleUserReceivers = new HashSet<ComponentName>();
13090                                }
13091                                singleUserReceivers.add(cn);
13092                            }
13093                        }
13094                    }
13095                    // Add the new results to the existing results, tracking
13096                    // and de-dupping single user receivers.
13097                    for (int i=0; i<newReceivers.size(); i++) {
13098                        ResolveInfo ri = newReceivers.get(i);
13099                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13100                            ComponentName cn = new ComponentName(
13101                                    ri.activityInfo.packageName, ri.activityInfo.name);
13102                            if (singleUserReceivers == null) {
13103                                singleUserReceivers = new HashSet<ComponentName>();
13104                            }
13105                            if (!singleUserReceivers.contains(cn)) {
13106                                singleUserReceivers.add(cn);
13107                                receivers.add(ri);
13108                            }
13109                        } else {
13110                            receivers.add(ri);
13111                        }
13112                    }
13113                }
13114            }
13115        } catch (RemoteException ex) {
13116            // pm is in same process, this will never happen.
13117        }
13118        return receivers;
13119    }
13120
13121    private final int broadcastIntentLocked(ProcessRecord callerApp,
13122            String callerPackage, Intent intent, String resolvedType,
13123            IIntentReceiver resultTo, int resultCode, String resultData,
13124            Bundle map, String requiredPermission, int appOp,
13125            boolean ordered, boolean sticky, int callingPid, int callingUid,
13126            int userId) {
13127        intent = new Intent(intent);
13128
13129        // By default broadcasts do not go to stopped apps.
13130        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13131
13132        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13133            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13134            + " ordered=" + ordered + " userid=" + userId);
13135        if ((resultTo != null) && !ordered) {
13136            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13137        }
13138
13139        userId = handleIncomingUser(callingPid, callingUid, userId,
13140                true, false, "broadcast", callerPackage);
13141
13142        // Make sure that the user who is receiving this broadcast is started.
13143        // If not, we will just skip it.
13144        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13145            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13146                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13147                Slog.w(TAG, "Skipping broadcast of " + intent
13148                        + ": user " + userId + " is stopped");
13149                return ActivityManager.BROADCAST_SUCCESS;
13150            }
13151        }
13152
13153        /*
13154         * Prevent non-system code (defined here to be non-persistent
13155         * processes) from sending protected broadcasts.
13156         */
13157        int callingAppId = UserHandle.getAppId(callingUid);
13158        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13159            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13160            callingUid == 0) {
13161            // Always okay.
13162        } else if (callerApp == null || !callerApp.persistent) {
13163            try {
13164                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13165                        intent.getAction())) {
13166                    String msg = "Permission Denial: not allowed to send broadcast "
13167                            + intent.getAction() + " from pid="
13168                            + callingPid + ", uid=" + callingUid;
13169                    Slog.w(TAG, msg);
13170                    throw new SecurityException(msg);
13171                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13172                    // Special case for compatibility: we don't want apps to send this,
13173                    // but historically it has not been protected and apps may be using it
13174                    // to poke their own app widget.  So, instead of making it protected,
13175                    // just limit it to the caller.
13176                    if (callerApp == null) {
13177                        String msg = "Permission Denial: not allowed to send broadcast "
13178                                + intent.getAction() + " from unknown caller.";
13179                        Slog.w(TAG, msg);
13180                        throw new SecurityException(msg);
13181                    } else if (intent.getComponent() != null) {
13182                        // They are good enough to send to an explicit component...  verify
13183                        // it is being sent to the calling app.
13184                        if (!intent.getComponent().getPackageName().equals(
13185                                callerApp.info.packageName)) {
13186                            String msg = "Permission Denial: not allowed to send broadcast "
13187                                    + intent.getAction() + " to "
13188                                    + intent.getComponent().getPackageName() + " from "
13189                                    + callerApp.info.packageName;
13190                            Slog.w(TAG, msg);
13191                            throw new SecurityException(msg);
13192                        }
13193                    } else {
13194                        // Limit broadcast to their own package.
13195                        intent.setPackage(callerApp.info.packageName);
13196                    }
13197                }
13198            } catch (RemoteException e) {
13199                Slog.w(TAG, "Remote exception", e);
13200                return ActivityManager.BROADCAST_SUCCESS;
13201            }
13202        }
13203
13204        // Handle special intents: if this broadcast is from the package
13205        // manager about a package being removed, we need to remove all of
13206        // its activities from the history stack.
13207        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13208                intent.getAction());
13209        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13210                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13211                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13212                || uidRemoved) {
13213            if (checkComponentPermission(
13214                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13215                    callingPid, callingUid, -1, true)
13216                    == PackageManager.PERMISSION_GRANTED) {
13217                if (uidRemoved) {
13218                    final Bundle intentExtras = intent.getExtras();
13219                    final int uid = intentExtras != null
13220                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13221                    if (uid >= 0) {
13222                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13223                        synchronized (bs) {
13224                            bs.removeUidStatsLocked(uid);
13225                        }
13226                        mAppOpsService.uidRemoved(uid);
13227                    }
13228                } else {
13229                    // If resources are unavailable just force stop all
13230                    // those packages and flush the attribute cache as well.
13231                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13232                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13233                        if (list != null && (list.length > 0)) {
13234                            for (String pkg : list) {
13235                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
13236                                        "storage unmount");
13237                            }
13238                            sendPackageBroadcastLocked(
13239                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13240                        }
13241                    } else {
13242                        Uri data = intent.getData();
13243                        String ssp;
13244                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13245                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13246                                    intent.getAction());
13247                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13248                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13249                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13250                                        false, userId, removed ? "pkg removed" : "pkg changed");
13251                            }
13252                            if (removed) {
13253                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13254                                        new String[] {ssp}, userId);
13255                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13256                                    mAppOpsService.packageRemoved(
13257                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13258
13259                                    // Remove all permissions granted from/to this package
13260                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13261                                }
13262                            }
13263                        }
13264                    }
13265                }
13266            } else {
13267                String msg = "Permission Denial: " + intent.getAction()
13268                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13269                        + ", uid=" + callingUid + ")"
13270                        + " requires "
13271                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13272                Slog.w(TAG, msg);
13273                throw new SecurityException(msg);
13274            }
13275
13276        // Special case for adding a package: by default turn on compatibility
13277        // mode.
13278        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13279            Uri data = intent.getData();
13280            String ssp;
13281            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13282                mCompatModePackages.handlePackageAddedLocked(ssp,
13283                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13284            }
13285        }
13286
13287        /*
13288         * If this is the time zone changed action, queue up a message that will reset the timezone
13289         * of all currently running processes. This message will get queued up before the broadcast
13290         * happens.
13291         */
13292        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13293            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13294        }
13295
13296        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13297            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13298        }
13299
13300        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13301            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13302            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13303        }
13304
13305        // Add to the sticky list if requested.
13306        if (sticky) {
13307            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13308                    callingPid, callingUid)
13309                    != PackageManager.PERMISSION_GRANTED) {
13310                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13311                        + callingPid + ", uid=" + callingUid
13312                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13313                Slog.w(TAG, msg);
13314                throw new SecurityException(msg);
13315            }
13316            if (requiredPermission != null) {
13317                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13318                        + " and enforce permission " + requiredPermission);
13319                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13320            }
13321            if (intent.getComponent() != null) {
13322                throw new SecurityException(
13323                        "Sticky broadcasts can't target a specific component");
13324            }
13325            // We use userId directly here, since the "all" target is maintained
13326            // as a separate set of sticky broadcasts.
13327            if (userId != UserHandle.USER_ALL) {
13328                // But first, if this is not a broadcast to all users, then
13329                // make sure it doesn't conflict with an existing broadcast to
13330                // all users.
13331                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13332                        UserHandle.USER_ALL);
13333                if (stickies != null) {
13334                    ArrayList<Intent> list = stickies.get(intent.getAction());
13335                    if (list != null) {
13336                        int N = list.size();
13337                        int i;
13338                        for (i=0; i<N; i++) {
13339                            if (intent.filterEquals(list.get(i))) {
13340                                throw new IllegalArgumentException(
13341                                        "Sticky broadcast " + intent + " for user "
13342                                        + userId + " conflicts with existing global broadcast");
13343                            }
13344                        }
13345                    }
13346                }
13347            }
13348            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13349            if (stickies == null) {
13350                stickies = new ArrayMap<String, ArrayList<Intent>>();
13351                mStickyBroadcasts.put(userId, stickies);
13352            }
13353            ArrayList<Intent> list = stickies.get(intent.getAction());
13354            if (list == null) {
13355                list = new ArrayList<Intent>();
13356                stickies.put(intent.getAction(), list);
13357            }
13358            int N = list.size();
13359            int i;
13360            for (i=0; i<N; i++) {
13361                if (intent.filterEquals(list.get(i))) {
13362                    // This sticky already exists, replace it.
13363                    list.set(i, new Intent(intent));
13364                    break;
13365                }
13366            }
13367            if (i >= N) {
13368                list.add(new Intent(intent));
13369            }
13370        }
13371
13372        int[] users;
13373        if (userId == UserHandle.USER_ALL) {
13374            // Caller wants broadcast to go to all started users.
13375            users = mStartedUserArray;
13376        } else {
13377            // Caller wants broadcast to go to one specific user.
13378            users = new int[] {userId};
13379        }
13380
13381        // Figure out who all will receive this broadcast.
13382        List receivers = null;
13383        List<BroadcastFilter> registeredReceivers = null;
13384        // Need to resolve the intent to interested receivers...
13385        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13386                 == 0) {
13387            receivers = collectReceiverComponents(intent, resolvedType, users);
13388        }
13389        if (intent.getComponent() == null) {
13390            registeredReceivers = mReceiverResolver.queryIntent(intent,
13391                    resolvedType, false, userId);
13392        }
13393
13394        final boolean replacePending =
13395                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13396
13397        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13398                + " replacePending=" + replacePending);
13399
13400        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13401        if (!ordered && NR > 0) {
13402            // If we are not serializing this broadcast, then send the
13403            // registered receivers separately so they don't wait for the
13404            // components to be launched.
13405            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13406            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13407                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13408                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13409                    ordered, sticky, false, userId);
13410            if (DEBUG_BROADCAST) Slog.v(
13411                    TAG, "Enqueueing parallel broadcast " + r);
13412            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13413            if (!replaced) {
13414                queue.enqueueParallelBroadcastLocked(r);
13415                queue.scheduleBroadcastsLocked();
13416            }
13417            registeredReceivers = null;
13418            NR = 0;
13419        }
13420
13421        // Merge into one list.
13422        int ir = 0;
13423        if (receivers != null) {
13424            // A special case for PACKAGE_ADDED: do not allow the package
13425            // being added to see this broadcast.  This prevents them from
13426            // using this as a back door to get run as soon as they are
13427            // installed.  Maybe in the future we want to have a special install
13428            // broadcast or such for apps, but we'd like to deliberately make
13429            // this decision.
13430            String skipPackages[] = null;
13431            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13432                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13433                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13434                Uri data = intent.getData();
13435                if (data != null) {
13436                    String pkgName = data.getSchemeSpecificPart();
13437                    if (pkgName != null) {
13438                        skipPackages = new String[] { pkgName };
13439                    }
13440                }
13441            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13442                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13443            }
13444            if (skipPackages != null && (skipPackages.length > 0)) {
13445                for (String skipPackage : skipPackages) {
13446                    if (skipPackage != null) {
13447                        int NT = receivers.size();
13448                        for (int it=0; it<NT; it++) {
13449                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13450                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13451                                receivers.remove(it);
13452                                it--;
13453                                NT--;
13454                            }
13455                        }
13456                    }
13457                }
13458            }
13459
13460            int NT = receivers != null ? receivers.size() : 0;
13461            int it = 0;
13462            ResolveInfo curt = null;
13463            BroadcastFilter curr = null;
13464            while (it < NT && ir < NR) {
13465                if (curt == null) {
13466                    curt = (ResolveInfo)receivers.get(it);
13467                }
13468                if (curr == null) {
13469                    curr = registeredReceivers.get(ir);
13470                }
13471                if (curr.getPriority() >= curt.priority) {
13472                    // Insert this broadcast record into the final list.
13473                    receivers.add(it, curr);
13474                    ir++;
13475                    curr = null;
13476                    it++;
13477                    NT++;
13478                } else {
13479                    // Skip to the next ResolveInfo in the final list.
13480                    it++;
13481                    curt = null;
13482                }
13483            }
13484        }
13485        while (ir < NR) {
13486            if (receivers == null) {
13487                receivers = new ArrayList();
13488            }
13489            receivers.add(registeredReceivers.get(ir));
13490            ir++;
13491        }
13492
13493        if ((receivers != null && receivers.size() > 0)
13494                || resultTo != null) {
13495            BroadcastQueue queue = broadcastQueueForIntent(intent);
13496            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13497                    callerPackage, callingPid, callingUid, resolvedType,
13498                    requiredPermission, appOp, receivers, resultTo, resultCode,
13499                    resultData, map, ordered, sticky, false, userId);
13500            if (DEBUG_BROADCAST) Slog.v(
13501                    TAG, "Enqueueing ordered broadcast " + r
13502                    + ": prev had " + queue.mOrderedBroadcasts.size());
13503            if (DEBUG_BROADCAST) {
13504                int seq = r.intent.getIntExtra("seq", -1);
13505                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13506            }
13507            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13508            if (!replaced) {
13509                queue.enqueueOrderedBroadcastLocked(r);
13510                queue.scheduleBroadcastsLocked();
13511            }
13512        }
13513
13514        return ActivityManager.BROADCAST_SUCCESS;
13515    }
13516
13517    final Intent verifyBroadcastLocked(Intent intent) {
13518        // Refuse possible leaked file descriptors
13519        if (intent != null && intent.hasFileDescriptors() == true) {
13520            throw new IllegalArgumentException("File descriptors passed in Intent");
13521        }
13522
13523        int flags = intent.getFlags();
13524
13525        if (!mProcessesReady) {
13526            // if the caller really truly claims to know what they're doing, go
13527            // ahead and allow the broadcast without launching any receivers
13528            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13529                intent = new Intent(intent);
13530                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13531            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13532                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13533                        + " before boot completion");
13534                throw new IllegalStateException("Cannot broadcast before boot completed");
13535            }
13536        }
13537
13538        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13539            throw new IllegalArgumentException(
13540                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13541        }
13542
13543        return intent;
13544    }
13545
13546    public final int broadcastIntent(IApplicationThread caller,
13547            Intent intent, String resolvedType, IIntentReceiver resultTo,
13548            int resultCode, String resultData, Bundle map,
13549            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13550        enforceNotIsolatedCaller("broadcastIntent");
13551        synchronized(this) {
13552            intent = verifyBroadcastLocked(intent);
13553
13554            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13555            final int callingPid = Binder.getCallingPid();
13556            final int callingUid = Binder.getCallingUid();
13557            final long origId = Binder.clearCallingIdentity();
13558            int res = broadcastIntentLocked(callerApp,
13559                    callerApp != null ? callerApp.info.packageName : null,
13560                    intent, resolvedType, resultTo,
13561                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13562                    callingPid, callingUid, userId);
13563            Binder.restoreCallingIdentity(origId);
13564            return res;
13565        }
13566    }
13567
13568    int broadcastIntentInPackage(String packageName, int uid,
13569            Intent intent, String resolvedType, IIntentReceiver resultTo,
13570            int resultCode, String resultData, Bundle map,
13571            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13572        synchronized(this) {
13573            intent = verifyBroadcastLocked(intent);
13574
13575            final long origId = Binder.clearCallingIdentity();
13576            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13577                    resultTo, resultCode, resultData, map, requiredPermission,
13578                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13579            Binder.restoreCallingIdentity(origId);
13580            return res;
13581        }
13582    }
13583
13584    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13585        // Refuse possible leaked file descriptors
13586        if (intent != null && intent.hasFileDescriptors() == true) {
13587            throw new IllegalArgumentException("File descriptors passed in Intent");
13588        }
13589
13590        userId = handleIncomingUser(Binder.getCallingPid(),
13591                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13592
13593        synchronized(this) {
13594            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13595                    != PackageManager.PERMISSION_GRANTED) {
13596                String msg = "Permission Denial: unbroadcastIntent() from pid="
13597                        + Binder.getCallingPid()
13598                        + ", uid=" + Binder.getCallingUid()
13599                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13600                Slog.w(TAG, msg);
13601                throw new SecurityException(msg);
13602            }
13603            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13604            if (stickies != null) {
13605                ArrayList<Intent> list = stickies.get(intent.getAction());
13606                if (list != null) {
13607                    int N = list.size();
13608                    int i;
13609                    for (i=0; i<N; i++) {
13610                        if (intent.filterEquals(list.get(i))) {
13611                            list.remove(i);
13612                            break;
13613                        }
13614                    }
13615                    if (list.size() <= 0) {
13616                        stickies.remove(intent.getAction());
13617                    }
13618                }
13619                if (stickies.size() <= 0) {
13620                    mStickyBroadcasts.remove(userId);
13621                }
13622            }
13623        }
13624    }
13625
13626    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13627            String resultData, Bundle resultExtras, boolean resultAbort) {
13628        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13629        if (r == null) {
13630            Slog.w(TAG, "finishReceiver called but not found on queue");
13631            return false;
13632        }
13633
13634        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13635    }
13636
13637    void backgroundServicesFinishedLocked(int userId) {
13638        for (BroadcastQueue queue : mBroadcastQueues) {
13639            queue.backgroundServicesFinishedLocked(userId);
13640        }
13641    }
13642
13643    public void finishReceiver(IBinder who, int resultCode, String resultData,
13644            Bundle resultExtras, boolean resultAbort) {
13645        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13646
13647        // Refuse possible leaked file descriptors
13648        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13649            throw new IllegalArgumentException("File descriptors passed in Bundle");
13650        }
13651
13652        final long origId = Binder.clearCallingIdentity();
13653        try {
13654            boolean doNext = false;
13655            BroadcastRecord r;
13656
13657            synchronized(this) {
13658                r = broadcastRecordForReceiverLocked(who);
13659                if (r != null) {
13660                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13661                        resultData, resultExtras, resultAbort, true);
13662                }
13663            }
13664
13665            if (doNext) {
13666                r.queue.processNextBroadcast(false);
13667            }
13668            trimApplications();
13669        } finally {
13670            Binder.restoreCallingIdentity(origId);
13671        }
13672    }
13673
13674    // =========================================================
13675    // INSTRUMENTATION
13676    // =========================================================
13677
13678    public boolean startInstrumentation(ComponentName className,
13679            String profileFile, int flags, Bundle arguments,
13680            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13681            int userId) {
13682        enforceNotIsolatedCaller("startInstrumentation");
13683        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13684                userId, false, true, "startInstrumentation", null);
13685        // Refuse possible leaked file descriptors
13686        if (arguments != null && arguments.hasFileDescriptors()) {
13687            throw new IllegalArgumentException("File descriptors passed in Bundle");
13688        }
13689
13690        synchronized(this) {
13691            InstrumentationInfo ii = null;
13692            ApplicationInfo ai = null;
13693            try {
13694                ii = mContext.getPackageManager().getInstrumentationInfo(
13695                    className, STOCK_PM_FLAGS);
13696                ai = AppGlobals.getPackageManager().getApplicationInfo(
13697                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13698            } catch (PackageManager.NameNotFoundException e) {
13699            } catch (RemoteException e) {
13700            }
13701            if (ii == null) {
13702                reportStartInstrumentationFailure(watcher, className,
13703                        "Unable to find instrumentation info for: " + className);
13704                return false;
13705            }
13706            if (ai == null) {
13707                reportStartInstrumentationFailure(watcher, className,
13708                        "Unable to find instrumentation target package: " + ii.targetPackage);
13709                return false;
13710            }
13711
13712            int match = mContext.getPackageManager().checkSignatures(
13713                    ii.targetPackage, ii.packageName);
13714            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13715                String msg = "Permission Denial: starting instrumentation "
13716                        + className + " from pid="
13717                        + Binder.getCallingPid()
13718                        + ", uid=" + Binder.getCallingPid()
13719                        + " not allowed because package " + ii.packageName
13720                        + " does not have a signature matching the target "
13721                        + ii.targetPackage;
13722                reportStartInstrumentationFailure(watcher, className, msg);
13723                throw new SecurityException(msg);
13724            }
13725
13726            final long origId = Binder.clearCallingIdentity();
13727            // Instrumentation can kill and relaunch even persistent processes
13728            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId,
13729                    "start instr");
13730            ProcessRecord app = addAppLocked(ai, false);
13731            app.instrumentationClass = className;
13732            app.instrumentationInfo = ai;
13733            app.instrumentationProfileFile = profileFile;
13734            app.instrumentationArguments = arguments;
13735            app.instrumentationWatcher = watcher;
13736            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13737            app.instrumentationResultClass = className;
13738            Binder.restoreCallingIdentity(origId);
13739        }
13740
13741        return true;
13742    }
13743
13744    /**
13745     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13746     * error to the logs, but if somebody is watching, send the report there too.  This enables
13747     * the "am" command to report errors with more information.
13748     *
13749     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13750     * @param cn The component name of the instrumentation.
13751     * @param report The error report.
13752     */
13753    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13754            ComponentName cn, String report) {
13755        Slog.w(TAG, report);
13756        try {
13757            if (watcher != null) {
13758                Bundle results = new Bundle();
13759                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13760                results.putString("Error", report);
13761                watcher.instrumentationStatus(cn, -1, results);
13762            }
13763        } catch (RemoteException e) {
13764            Slog.w(TAG, e);
13765        }
13766    }
13767
13768    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13769        if (app.instrumentationWatcher != null) {
13770            try {
13771                // NOTE:  IInstrumentationWatcher *must* be oneway here
13772                app.instrumentationWatcher.instrumentationFinished(
13773                    app.instrumentationClass,
13774                    resultCode,
13775                    results);
13776            } catch (RemoteException e) {
13777            }
13778        }
13779        if (app.instrumentationUiAutomationConnection != null) {
13780            try {
13781                app.instrumentationUiAutomationConnection.shutdown();
13782            } catch (RemoteException re) {
13783                /* ignore */
13784            }
13785            // Only a UiAutomation can set this flag and now that
13786            // it is finished we make sure it is reset to its default.
13787            mUserIsMonkey = false;
13788        }
13789        app.instrumentationWatcher = null;
13790        app.instrumentationUiAutomationConnection = null;
13791        app.instrumentationClass = null;
13792        app.instrumentationInfo = null;
13793        app.instrumentationProfileFile = null;
13794        app.instrumentationArguments = null;
13795
13796        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId,
13797                "finished inst");
13798    }
13799
13800    public void finishInstrumentation(IApplicationThread target,
13801            int resultCode, Bundle results) {
13802        int userId = UserHandle.getCallingUserId();
13803        // Refuse possible leaked file descriptors
13804        if (results != null && results.hasFileDescriptors()) {
13805            throw new IllegalArgumentException("File descriptors passed in Intent");
13806        }
13807
13808        synchronized(this) {
13809            ProcessRecord app = getRecordForAppLocked(target);
13810            if (app == null) {
13811                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13812                return;
13813            }
13814            final long origId = Binder.clearCallingIdentity();
13815            finishInstrumentationLocked(app, resultCode, results);
13816            Binder.restoreCallingIdentity(origId);
13817        }
13818    }
13819
13820    // =========================================================
13821    // CONFIGURATION
13822    // =========================================================
13823
13824    public ConfigurationInfo getDeviceConfigurationInfo() {
13825        ConfigurationInfo config = new ConfigurationInfo();
13826        synchronized (this) {
13827            config.reqTouchScreen = mConfiguration.touchscreen;
13828            config.reqKeyboardType = mConfiguration.keyboard;
13829            config.reqNavigation = mConfiguration.navigation;
13830            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13831                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13832                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13833            }
13834            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13835                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13836                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13837            }
13838            config.reqGlEsVersion = GL_ES_VERSION;
13839        }
13840        return config;
13841    }
13842
13843    ActivityStack getFocusedStack() {
13844        return mStackSupervisor.getFocusedStack();
13845    }
13846
13847    public Configuration getConfiguration() {
13848        Configuration ci;
13849        synchronized(this) {
13850            ci = new Configuration(mConfiguration);
13851        }
13852        return ci;
13853    }
13854
13855    public void updatePersistentConfiguration(Configuration values) {
13856        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13857                "updateConfiguration()");
13858        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13859                "updateConfiguration()");
13860        if (values == null) {
13861            throw new NullPointerException("Configuration must not be null");
13862        }
13863
13864        synchronized(this) {
13865            final long origId = Binder.clearCallingIdentity();
13866            updateConfigurationLocked(values, null, true, false);
13867            Binder.restoreCallingIdentity(origId);
13868        }
13869    }
13870
13871    public void updateConfiguration(Configuration values) {
13872        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13873                "updateConfiguration()");
13874
13875        synchronized(this) {
13876            if (values == null && mWindowManager != null) {
13877                // sentinel: fetch the current configuration from the window manager
13878                values = mWindowManager.computeNewConfiguration();
13879            }
13880
13881            if (mWindowManager != null) {
13882                mProcessList.applyDisplaySize(mWindowManager);
13883            }
13884
13885            final long origId = Binder.clearCallingIdentity();
13886            if (values != null) {
13887                Settings.System.clearConfiguration(values);
13888            }
13889            updateConfigurationLocked(values, null, false, false);
13890            Binder.restoreCallingIdentity(origId);
13891        }
13892    }
13893
13894    /**
13895     * Do either or both things: (1) change the current configuration, and (2)
13896     * make sure the given activity is running with the (now) current
13897     * configuration.  Returns true if the activity has been left running, or
13898     * false if <var>starting</var> is being destroyed to match the new
13899     * configuration.
13900     * @param persistent TODO
13901     */
13902    boolean updateConfigurationLocked(Configuration values,
13903            ActivityRecord starting, boolean persistent, boolean initLocale) {
13904        int changes = 0;
13905
13906        if (values != null) {
13907            Configuration newConfig = new Configuration(mConfiguration);
13908            changes = newConfig.updateFrom(values);
13909            if (changes != 0) {
13910                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13911                    Slog.i(TAG, "Updating configuration to: " + values);
13912                }
13913
13914                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13915
13916                if (values.locale != null && !initLocale) {
13917                    saveLocaleLocked(values.locale,
13918                                     !values.locale.equals(mConfiguration.locale),
13919                                     values.userSetLocale);
13920                }
13921
13922                mConfigurationSeq++;
13923                if (mConfigurationSeq <= 0) {
13924                    mConfigurationSeq = 1;
13925                }
13926                newConfig.seq = mConfigurationSeq;
13927                mConfiguration = newConfig;
13928                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
13929
13930                final Configuration configCopy = new Configuration(mConfiguration);
13931
13932                // TODO: If our config changes, should we auto dismiss any currently
13933                // showing dialogs?
13934                mShowDialogs = shouldShowDialogs(newConfig);
13935
13936                AttributeCache ac = AttributeCache.instance();
13937                if (ac != null) {
13938                    ac.updateConfiguration(configCopy);
13939                }
13940
13941                // Make sure all resources in our process are updated
13942                // right now, so that anyone who is going to retrieve
13943                // resource values after we return will be sure to get
13944                // the new ones.  This is especially important during
13945                // boot, where the first config change needs to guarantee
13946                // all resources have that config before following boot
13947                // code is executed.
13948                mSystemThread.applyConfigurationToResources(configCopy);
13949
13950                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
13951                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
13952                    msg.obj = new Configuration(configCopy);
13953                    mHandler.sendMessage(msg);
13954                }
13955
13956                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13957                    ProcessRecord app = mLruProcesses.get(i);
13958                    try {
13959                        if (app.thread != null) {
13960                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
13961                                    + app.processName + " new config " + mConfiguration);
13962                            app.thread.scheduleConfigurationChanged(configCopy);
13963                        }
13964                    } catch (Exception e) {
13965                    }
13966                }
13967                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
13968                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13969                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
13970                        | Intent.FLAG_RECEIVER_FOREGROUND);
13971                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
13972                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
13973                        Process.SYSTEM_UID, UserHandle.USER_ALL);
13974                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13975                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
13976                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13977                    broadcastIntentLocked(null, null, intent,
13978                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13979                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13980                }
13981            }
13982        }
13983
13984        boolean kept = true;
13985        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
13986        // mainStack is null during startup.
13987        if (mainStack != null) {
13988            if (changes != 0 && starting == null) {
13989                // If the configuration changed, and the caller is not already
13990                // in the process of starting an activity, then find the top
13991                // activity to check if its configuration needs to change.
13992                starting = mainStack.topRunningActivityLocked(null);
13993            }
13994
13995            if (starting != null) {
13996                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
13997                // And we need to make sure at this point that all other activities
13998                // are made visible with the correct configuration.
13999                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14000            }
14001        }
14002
14003        if (values != null && mWindowManager != null) {
14004            mWindowManager.setNewConfiguration(mConfiguration);
14005        }
14006
14007        return kept;
14008    }
14009
14010    /**
14011     * Decide based on the configuration whether we should shouw the ANR,
14012     * crash, etc dialogs.  The idea is that if there is no affordnace to
14013     * press the on-screen buttons, we shouldn't show the dialog.
14014     *
14015     * A thought: SystemUI might also want to get told about this, the Power
14016     * dialog / global actions also might want different behaviors.
14017     */
14018    private static final boolean shouldShowDialogs(Configuration config) {
14019        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14020                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14021    }
14022
14023    /**
14024     * Save the locale.  You must be inside a synchronized (this) block.
14025     */
14026    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14027        if(isDiff) {
14028            SystemProperties.set("user.language", l.getLanguage());
14029            SystemProperties.set("user.region", l.getCountry());
14030        }
14031
14032        if(isPersist) {
14033            SystemProperties.set("persist.sys.language", l.getLanguage());
14034            SystemProperties.set("persist.sys.country", l.getCountry());
14035            SystemProperties.set("persist.sys.localevar", l.getVariant());
14036        }
14037    }
14038
14039    @Override
14040    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14041        ActivityRecord srec = ActivityRecord.forToken(token);
14042        return srec != null && srec.task.affinity != null &&
14043                srec.task.affinity.equals(destAffinity);
14044    }
14045
14046    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14047            Intent resultData) {
14048
14049        synchronized (this) {
14050            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14051            if (stack != null) {
14052                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14053            }
14054            return false;
14055        }
14056    }
14057
14058    public int getLaunchedFromUid(IBinder activityToken) {
14059        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14060        if (srec == null) {
14061            return -1;
14062        }
14063        return srec.launchedFromUid;
14064    }
14065
14066    public String getLaunchedFromPackage(IBinder activityToken) {
14067        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14068        if (srec == null) {
14069            return null;
14070        }
14071        return srec.launchedFromPackage;
14072    }
14073
14074    // =========================================================
14075    // LIFETIME MANAGEMENT
14076    // =========================================================
14077
14078    // Returns which broadcast queue the app is the current [or imminent] receiver
14079    // on, or 'null' if the app is not an active broadcast recipient.
14080    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14081        BroadcastRecord r = app.curReceiver;
14082        if (r != null) {
14083            return r.queue;
14084        }
14085
14086        // It's not the current receiver, but it might be starting up to become one
14087        synchronized (this) {
14088            for (BroadcastQueue queue : mBroadcastQueues) {
14089                r = queue.mPendingBroadcast;
14090                if (r != null && r.curApp == app) {
14091                    // found it; report which queue it's in
14092                    return queue;
14093                }
14094            }
14095        }
14096
14097        return null;
14098    }
14099
14100    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14101            boolean doingAll, long now) {
14102        if (mAdjSeq == app.adjSeq) {
14103            // This adjustment has already been computed.
14104            return app.curRawAdj;
14105        }
14106
14107        if (app.thread == null) {
14108            app.adjSeq = mAdjSeq;
14109            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14110            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14111            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14112        }
14113
14114        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14115        app.adjSource = null;
14116        app.adjTarget = null;
14117        app.empty = false;
14118        app.cached = false;
14119
14120        final int activitiesSize = app.activities.size();
14121
14122        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14123            // The max adjustment doesn't allow this app to be anything
14124            // below foreground, so it is not worth doing work for it.
14125            app.adjType = "fixed";
14126            app.adjSeq = mAdjSeq;
14127            app.curRawAdj = app.maxAdj;
14128            app.foregroundActivities = false;
14129            app.keeping = true;
14130            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14131            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14132            // System process can do UI, and when they do we want to have
14133            // them trim their memory after the user leaves the UI.  To
14134            // facilitate this, here we need to determine whether or not it
14135            // is currently showing UI.
14136            app.systemNoUi = true;
14137            if (app == TOP_APP) {
14138                app.systemNoUi = false;
14139            } else if (activitiesSize > 0) {
14140                for (int j = 0; j < activitiesSize; j++) {
14141                    final ActivityRecord r = app.activities.get(j);
14142                    if (r.visible) {
14143                        app.systemNoUi = false;
14144                    }
14145                }
14146            }
14147            if (!app.systemNoUi) {
14148                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14149            }
14150            return (app.curAdj=app.maxAdj);
14151        }
14152
14153        app.keeping = false;
14154        app.systemNoUi = false;
14155
14156        // Determine the importance of the process, starting with most
14157        // important to least, and assign an appropriate OOM adjustment.
14158        int adj;
14159        int schedGroup;
14160        int procState;
14161        boolean foregroundActivities = false;
14162        boolean interesting = false;
14163        BroadcastQueue queue;
14164        if (app == TOP_APP) {
14165            // The last app on the list is the foreground app.
14166            adj = ProcessList.FOREGROUND_APP_ADJ;
14167            schedGroup = Process.THREAD_GROUP_DEFAULT;
14168            app.adjType = "top-activity";
14169            foregroundActivities = true;
14170            interesting = true;
14171            procState = ActivityManager.PROCESS_STATE_TOP;
14172        } else if (app.instrumentationClass != null) {
14173            // Don't want to kill running instrumentation.
14174            adj = ProcessList.FOREGROUND_APP_ADJ;
14175            schedGroup = Process.THREAD_GROUP_DEFAULT;
14176            app.adjType = "instrumentation";
14177            interesting = true;
14178            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14179        } else if ((queue = isReceivingBroadcast(app)) != null) {
14180            // An app that is currently receiving a broadcast also
14181            // counts as being in the foreground for OOM killer purposes.
14182            // It's placed in a sched group based on the nature of the
14183            // broadcast as reflected by which queue it's active in.
14184            adj = ProcessList.FOREGROUND_APP_ADJ;
14185            schedGroup = (queue == mFgBroadcastQueue)
14186                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14187            app.adjType = "broadcast";
14188            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14189        } else if (app.executingServices.size() > 0) {
14190            // An app that is currently executing a service callback also
14191            // counts as being in the foreground.
14192            adj = ProcessList.FOREGROUND_APP_ADJ;
14193            schedGroup = app.execServicesFg ?
14194                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14195            app.adjType = "exec-service";
14196            procState = ActivityManager.PROCESS_STATE_SERVICE;
14197            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14198        } else {
14199            // As far as we know the process is empty.  We may change our mind later.
14200            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14201            // At this point we don't actually know the adjustment.  Use the cached adj
14202            // value that the caller wants us to.
14203            adj = cachedAdj;
14204            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14205            app.cached = true;
14206            app.empty = true;
14207            app.adjType = "cch-empty";
14208        }
14209
14210        // Examine all activities if not already foreground.
14211        if (!foregroundActivities && activitiesSize > 0) {
14212            for (int j = 0; j < activitiesSize; j++) {
14213                final ActivityRecord r = app.activities.get(j);
14214                if (r.app != app) {
14215                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14216                            + app + "?!?");
14217                    continue;
14218                }
14219                if (r.visible) {
14220                    // App has a visible activity; only upgrade adjustment.
14221                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14222                        adj = ProcessList.VISIBLE_APP_ADJ;
14223                        app.adjType = "visible";
14224                    }
14225                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14226                        procState = ActivityManager.PROCESS_STATE_TOP;
14227                    }
14228                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14229                    app.cached = false;
14230                    app.empty = false;
14231                    foregroundActivities = true;
14232                    break;
14233                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14234                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14235                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14236                        app.adjType = "pausing";
14237                    }
14238                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14239                        procState = ActivityManager.PROCESS_STATE_TOP;
14240                    }
14241                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14242                    app.cached = false;
14243                    app.empty = false;
14244                    foregroundActivities = true;
14245                } else if (r.state == ActivityState.STOPPING) {
14246                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14247                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14248                        app.adjType = "stopping";
14249                    }
14250                    // For the process state, we will at this point consider the
14251                    // process to be cached.  It will be cached either as an activity
14252                    // or empty depending on whether the activity is finishing.  We do
14253                    // this so that we can treat the process as cached for purposes of
14254                    // memory trimming (determing current memory level, trim command to
14255                    // send to process) since there can be an arbitrary number of stopping
14256                    // processes and they should soon all go into the cached state.
14257                    if (!r.finishing) {
14258                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14259                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14260                        }
14261                    }
14262                    app.cached = false;
14263                    app.empty = false;
14264                    foregroundActivities = true;
14265                } else {
14266                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14267                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14268                        app.adjType = "cch-act";
14269                    }
14270                }
14271            }
14272        }
14273
14274        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14275            if (app.foregroundServices) {
14276                // The user is aware of this app, so make it visible.
14277                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14278                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14279                app.cached = false;
14280                app.adjType = "fg-service";
14281                schedGroup = Process.THREAD_GROUP_DEFAULT;
14282            } else if (app.forcingToForeground != null) {
14283                // The user is aware of this app, so make it visible.
14284                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14285                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14286                app.cached = false;
14287                app.adjType = "force-fg";
14288                app.adjSource = app.forcingToForeground;
14289                schedGroup = Process.THREAD_GROUP_DEFAULT;
14290            }
14291        }
14292
14293        if (app.foregroundServices) {
14294            interesting = true;
14295        }
14296
14297        if (app == mHeavyWeightProcess) {
14298            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14299                // We don't want to kill the current heavy-weight process.
14300                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14301                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14302                app.cached = false;
14303                app.adjType = "heavy";
14304            }
14305            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14306                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14307            }
14308        }
14309
14310        if (app == mHomeProcess) {
14311            if (adj > ProcessList.HOME_APP_ADJ) {
14312                // This process is hosting what we currently consider to be the
14313                // home app, so we don't want to let it go into the background.
14314                adj = ProcessList.HOME_APP_ADJ;
14315                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14316                app.cached = false;
14317                app.adjType = "home";
14318            }
14319            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14320                procState = ActivityManager.PROCESS_STATE_HOME;
14321            }
14322        }
14323
14324        if (app == mPreviousProcess && app.activities.size() > 0) {
14325            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14326                // This was the previous process that showed UI to the user.
14327                // We want to try to keep it around more aggressively, to give
14328                // a good experience around switching between two apps.
14329                adj = ProcessList.PREVIOUS_APP_ADJ;
14330                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14331                app.cached = false;
14332                app.adjType = "previous";
14333            }
14334            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14335                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14336            }
14337        }
14338
14339        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14340                + " reason=" + app.adjType);
14341
14342        // By default, we use the computed adjustment.  It may be changed if
14343        // there are applications dependent on our services or providers, but
14344        // this gives us a baseline and makes sure we don't get into an
14345        // infinite recursion.
14346        app.adjSeq = mAdjSeq;
14347        app.curRawAdj = adj;
14348        app.hasStartedServices = false;
14349
14350        if (mBackupTarget != null && app == mBackupTarget.app) {
14351            // If possible we want to avoid killing apps while they're being backed up
14352            if (adj > ProcessList.BACKUP_APP_ADJ) {
14353                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14354                adj = ProcessList.BACKUP_APP_ADJ;
14355                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14356                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14357                }
14358                app.adjType = "backup";
14359                app.cached = false;
14360            }
14361            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14362                procState = ActivityManager.PROCESS_STATE_BACKUP;
14363            }
14364        }
14365
14366        boolean mayBeTop = false;
14367
14368        for (int is = app.services.size()-1;
14369                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14370                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14371                        || procState > ActivityManager.PROCESS_STATE_TOP);
14372                is--) {
14373            ServiceRecord s = app.services.valueAt(is);
14374            if (s.startRequested) {
14375                app.hasStartedServices = true;
14376                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14377                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14378                }
14379                if (app.hasShownUi && app != mHomeProcess) {
14380                    // If this process has shown some UI, let it immediately
14381                    // go to the LRU list because it may be pretty heavy with
14382                    // UI stuff.  We'll tag it with a label just to help
14383                    // debug and understand what is going on.
14384                    if (adj > ProcessList.SERVICE_ADJ) {
14385                        app.adjType = "cch-started-ui-services";
14386                    }
14387                } else {
14388                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14389                        // This service has seen some activity within
14390                        // recent memory, so we will keep its process ahead
14391                        // of the background processes.
14392                        if (adj > ProcessList.SERVICE_ADJ) {
14393                            adj = ProcessList.SERVICE_ADJ;
14394                            app.adjType = "started-services";
14395                            app.cached = false;
14396                        }
14397                    }
14398                    // If we have let the service slide into the background
14399                    // state, still have some text describing what it is doing
14400                    // even though the service no longer has an impact.
14401                    if (adj > ProcessList.SERVICE_ADJ) {
14402                        app.adjType = "cch-started-services";
14403                    }
14404                }
14405                // Don't kill this process because it is doing work; it
14406                // has said it is doing work.
14407                app.keeping = true;
14408            }
14409            for (int conni = s.connections.size()-1;
14410                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14411                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14412                            || procState > ActivityManager.PROCESS_STATE_TOP);
14413                    conni--) {
14414                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14415                for (int i = 0;
14416                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14417                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14418                                || procState > ActivityManager.PROCESS_STATE_TOP);
14419                        i++) {
14420                    // XXX should compute this based on the max of
14421                    // all connected clients.
14422                    ConnectionRecord cr = clist.get(i);
14423                    if (cr.binding.client == app) {
14424                        // Binding to ourself is not interesting.
14425                        continue;
14426                    }
14427                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14428                        ProcessRecord client = cr.binding.client;
14429                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14430                                TOP_APP, doingAll, now);
14431                        int clientProcState = client.curProcState;
14432                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14433                            // If the other app is cached for any reason, for purposes here
14434                            // we are going to consider it empty.  The specific cached state
14435                            // doesn't propagate except under certain conditions.
14436                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14437                        }
14438                        String adjType = null;
14439                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14440                            // Not doing bind OOM management, so treat
14441                            // this guy more like a started service.
14442                            if (app.hasShownUi && app != mHomeProcess) {
14443                                // If this process has shown some UI, let it immediately
14444                                // go to the LRU list because it may be pretty heavy with
14445                                // UI stuff.  We'll tag it with a label just to help
14446                                // debug and understand what is going on.
14447                                if (adj > clientAdj) {
14448                                    adjType = "cch-bound-ui-services";
14449                                }
14450                                app.cached = false;
14451                                clientAdj = adj;
14452                                clientProcState = procState;
14453                            } else {
14454                                if (now >= (s.lastActivity
14455                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14456                                    // This service has not seen activity within
14457                                    // recent memory, so allow it to drop to the
14458                                    // LRU list if there is no other reason to keep
14459                                    // it around.  We'll also tag it with a label just
14460                                    // to help debug and undertand what is going on.
14461                                    if (adj > clientAdj) {
14462                                        adjType = "cch-bound-services";
14463                                    }
14464                                    clientAdj = adj;
14465                                }
14466                            }
14467                        }
14468                        if (adj > clientAdj) {
14469                            // If this process has recently shown UI, and
14470                            // the process that is binding to it is less
14471                            // important than being visible, then we don't
14472                            // care about the binding as much as we care
14473                            // about letting this process get into the LRU
14474                            // list to be killed and restarted if needed for
14475                            // memory.
14476                            if (app.hasShownUi && app != mHomeProcess
14477                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14478                                adjType = "cch-bound-ui-services";
14479                            } else {
14480                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14481                                        |Context.BIND_IMPORTANT)) != 0) {
14482                                    adj = clientAdj;
14483                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14484                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14485                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14486                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14487                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14488                                    adj = clientAdj;
14489                                } else {
14490                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14491                                        adj = ProcessList.VISIBLE_APP_ADJ;
14492                                    }
14493                                }
14494                                if (!client.cached) {
14495                                    app.cached = false;
14496                                }
14497                                if (client.keeping) {
14498                                    app.keeping = true;
14499                                }
14500                                adjType = "service";
14501                            }
14502                        }
14503                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14504                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14505                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14506                            }
14507                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14508                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14509                                    // Special handling of clients who are in the top state.
14510                                    // We *may* want to consider this process to be in the
14511                                    // top state as well, but only if there is not another
14512                                    // reason for it to be running.  Being on the top is a
14513                                    // special state, meaning you are specifically running
14514                                    // for the current top app.  If the process is already
14515                                    // running in the background for some other reason, it
14516                                    // is more important to continue considering it to be
14517                                    // in the background state.
14518                                    mayBeTop = true;
14519                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14520                                } else {
14521                                    // Special handling for above-top states (persistent
14522                                    // processes).  These should not bring the current process
14523                                    // into the top state, since they are not on top.  Instead
14524                                    // give them the best state after that.
14525                                    clientProcState =
14526                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14527                                }
14528                            }
14529                        } else {
14530                            if (clientProcState <
14531                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14532                                clientProcState =
14533                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14534                            }
14535                        }
14536                        if (procState > clientProcState) {
14537                            procState = clientProcState;
14538                        }
14539                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14540                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14541                            app.pendingUiClean = true;
14542                        }
14543                        if (adjType != null) {
14544                            app.adjType = adjType;
14545                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14546                                    .REASON_SERVICE_IN_USE;
14547                            app.adjSource = cr.binding.client;
14548                            app.adjSourceOom = clientAdj;
14549                            app.adjTarget = s.name;
14550                        }
14551                    }
14552                    final ActivityRecord a = cr.activity;
14553                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14554                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14555                                (a.visible || a.state == ActivityState.RESUMED
14556                                 || a.state == ActivityState.PAUSING)) {
14557                            adj = ProcessList.FOREGROUND_APP_ADJ;
14558                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14559                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14560                            }
14561                            app.cached = false;
14562                            app.adjType = "service";
14563                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14564                                    .REASON_SERVICE_IN_USE;
14565                            app.adjSource = a;
14566                            app.adjSourceOom = adj;
14567                            app.adjTarget = s.name;
14568                        }
14569                    }
14570                }
14571            }
14572        }
14573
14574        for (int provi = app.pubProviders.size()-1;
14575                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14576                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14577                        || procState > ActivityManager.PROCESS_STATE_TOP);
14578                provi--) {
14579            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14580            for (int i = cpr.connections.size()-1;
14581                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14582                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14583                            || procState > ActivityManager.PROCESS_STATE_TOP);
14584                    i--) {
14585                ContentProviderConnection conn = cpr.connections.get(i);
14586                ProcessRecord client = conn.client;
14587                if (client == app) {
14588                    // Being our own client is not interesting.
14589                    continue;
14590                }
14591                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14592                int clientProcState = client.curProcState;
14593                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14594                    // If the other app is cached for any reason, for purposes here
14595                    // we are going to consider it empty.
14596                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14597                }
14598                if (adj > clientAdj) {
14599                    if (app.hasShownUi && app != mHomeProcess
14600                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14601                        app.adjType = "cch-ui-provider";
14602                    } else {
14603                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14604                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14605                        app.adjType = "provider";
14606                    }
14607                    app.cached &= client.cached;
14608                    app.keeping |= client.keeping;
14609                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14610                            .REASON_PROVIDER_IN_USE;
14611                    app.adjSource = client;
14612                    app.adjSourceOom = clientAdj;
14613                    app.adjTarget = cpr.name;
14614                }
14615                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14616                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14617                        // Special handling of clients who are in the top state.
14618                        // We *may* want to consider this process to be in the
14619                        // top state as well, but only if there is not another
14620                        // reason for it to be running.  Being on the top is a
14621                        // special state, meaning you are specifically running
14622                        // for the current top app.  If the process is already
14623                        // running in the background for some other reason, it
14624                        // is more important to continue considering it to be
14625                        // in the background state.
14626                        mayBeTop = true;
14627                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14628                    } else {
14629                        // Special handling for above-top states (persistent
14630                        // processes).  These should not bring the current process
14631                        // into the top state, since they are not on top.  Instead
14632                        // give them the best state after that.
14633                        clientProcState =
14634                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14635                    }
14636                }
14637                if (procState > clientProcState) {
14638                    procState = clientProcState;
14639                }
14640                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14641                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14642                }
14643            }
14644            // If the provider has external (non-framework) process
14645            // dependencies, ensure that its adjustment is at least
14646            // FOREGROUND_APP_ADJ.
14647            if (cpr.hasExternalProcessHandles()) {
14648                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14649                    adj = ProcessList.FOREGROUND_APP_ADJ;
14650                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14651                    app.cached = false;
14652                    app.keeping = true;
14653                    app.adjType = "provider";
14654                    app.adjTarget = cpr.name;
14655                }
14656                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14657                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14658                }
14659            }
14660        }
14661
14662        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14663            // A client of one of our services or providers is in the top state.  We
14664            // *may* want to be in the top state, but not if we are already running in
14665            // the background for some other reason.  For the decision here, we are going
14666            // to pick out a few specific states that we want to remain in when a client
14667            // is top (states that tend to be longer-term) and otherwise allow it to go
14668            // to the top state.
14669            switch (procState) {
14670                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14671                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14672                case ActivityManager.PROCESS_STATE_SERVICE:
14673                    // These all are longer-term states, so pull them up to the top
14674                    // of the background states, but not all the way to the top state.
14675                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14676                    break;
14677                default:
14678                    // Otherwise, top is a better choice, so take it.
14679                    procState = ActivityManager.PROCESS_STATE_TOP;
14680                    break;
14681            }
14682        }
14683
14684        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14685            // This is a cached process, but with client activities.  Mark it so.
14686            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14687            app.adjType = "cch-client-act";
14688        }
14689
14690        if (adj == ProcessList.SERVICE_ADJ) {
14691            if (doingAll) {
14692                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14693                mNewNumServiceProcs++;
14694                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14695                if (!app.serviceb) {
14696                    // This service isn't far enough down on the LRU list to
14697                    // normally be a B service, but if we are low on RAM and it
14698                    // is large we want to force it down since we would prefer to
14699                    // keep launcher over it.
14700                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14701                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14702                        app.serviceHighRam = true;
14703                        app.serviceb = true;
14704                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14705                    } else {
14706                        mNewNumAServiceProcs++;
14707                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14708                    }
14709                } else {
14710                    app.serviceHighRam = false;
14711                }
14712            }
14713            if (app.serviceb) {
14714                adj = ProcessList.SERVICE_B_ADJ;
14715            }
14716        }
14717
14718        app.curRawAdj = adj;
14719
14720        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14721        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14722        if (adj > app.maxAdj) {
14723            adj = app.maxAdj;
14724            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14725                schedGroup = Process.THREAD_GROUP_DEFAULT;
14726            }
14727        }
14728        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14729            app.keeping = true;
14730        }
14731
14732        // Do final modification to adj.  Everything we do between here and applying
14733        // the final setAdj must be done in this function, because we will also use
14734        // it when computing the final cached adj later.  Note that we don't need to
14735        // worry about this for max adj above, since max adj will always be used to
14736        // keep it out of the cached vaues.
14737        adj = app.modifyRawOomAdj(adj);
14738
14739        app.curProcState = procState;
14740
14741        int importance = app.memImportance;
14742        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14743            app.curAdj = adj;
14744            app.curSchedGroup = schedGroup;
14745            if (!interesting) {
14746                // For this reporting, if there is not something explicitly
14747                // interesting in this process then we will push it to the
14748                // background importance.
14749                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14750            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14751                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14752            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14753                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14754            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14755                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14756            } else if (adj >= ProcessList.SERVICE_ADJ) {
14757                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14758            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14759                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14760            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14761                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14762            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14763                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14764            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14765                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14766            } else {
14767                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14768            }
14769        }
14770
14771        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14772        if (foregroundActivities != app.foregroundActivities) {
14773            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14774        }
14775        if (changes != 0) {
14776            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14777            app.memImportance = importance;
14778            app.foregroundActivities = foregroundActivities;
14779            int i = mPendingProcessChanges.size()-1;
14780            ProcessChangeItem item = null;
14781            while (i >= 0) {
14782                item = mPendingProcessChanges.get(i);
14783                if (item.pid == app.pid) {
14784                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14785                    break;
14786                }
14787                i--;
14788            }
14789            if (i < 0) {
14790                // No existing item in pending changes; need a new one.
14791                final int NA = mAvailProcessChanges.size();
14792                if (NA > 0) {
14793                    item = mAvailProcessChanges.remove(NA-1);
14794                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14795                } else {
14796                    item = new ProcessChangeItem();
14797                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14798                }
14799                item.changes = 0;
14800                item.pid = app.pid;
14801                item.uid = app.info.uid;
14802                if (mPendingProcessChanges.size() == 0) {
14803                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14804                            "*** Enqueueing dispatch processes changed!");
14805                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14806                }
14807                mPendingProcessChanges.add(item);
14808            }
14809            item.changes |= changes;
14810            item.importance = importance;
14811            item.foregroundActivities = foregroundActivities;
14812            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14813                    + Integer.toHexString(System.identityHashCode(item))
14814                    + " " + app.toShortString() + ": changes=" + item.changes
14815                    + " importance=" + item.importance
14816                    + " foreground=" + item.foregroundActivities
14817                    + " type=" + app.adjType + " source=" + app.adjSource
14818                    + " target=" + app.adjTarget);
14819        }
14820
14821        return app.curRawAdj;
14822    }
14823
14824    /**
14825     * Schedule PSS collection of a process.
14826     */
14827    void requestPssLocked(ProcessRecord proc, int procState) {
14828        if (mPendingPssProcesses.contains(proc)) {
14829            return;
14830        }
14831        if (mPendingPssProcesses.size() == 0) {
14832            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14833        }
14834        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
14835        proc.pssProcState = procState;
14836        mPendingPssProcesses.add(proc);
14837    }
14838
14839    /**
14840     * Schedule PSS collection of all processes.
14841     */
14842    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
14843        if (!always) {
14844            if (now < (mLastFullPssTime +
14845                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
14846                return;
14847            }
14848        }
14849        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
14850        mLastFullPssTime = now;
14851        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
14852        mPendingPssProcesses.clear();
14853        for (int i=mLruProcesses.size()-1; i>=0; i--) {
14854            ProcessRecord app = mLruProcesses.get(i);
14855            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
14856                app.pssProcState = app.setProcState;
14857                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
14858                        mSleeping, now);
14859                mPendingPssProcesses.add(app);
14860            }
14861        }
14862        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14863    }
14864
14865    /**
14866     * Ask a given process to GC right now.
14867     */
14868    final void performAppGcLocked(ProcessRecord app) {
14869        try {
14870            app.lastRequestedGc = SystemClock.uptimeMillis();
14871            if (app.thread != null) {
14872                if (app.reportLowMemory) {
14873                    app.reportLowMemory = false;
14874                    app.thread.scheduleLowMemory();
14875                } else {
14876                    app.thread.processInBackground();
14877                }
14878            }
14879        } catch (Exception e) {
14880            // whatever.
14881        }
14882    }
14883
14884    /**
14885     * Returns true if things are idle enough to perform GCs.
14886     */
14887    private final boolean canGcNowLocked() {
14888        boolean processingBroadcasts = false;
14889        for (BroadcastQueue q : mBroadcastQueues) {
14890            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14891                processingBroadcasts = true;
14892            }
14893        }
14894        return !processingBroadcasts
14895                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
14896    }
14897
14898    /**
14899     * Perform GCs on all processes that are waiting for it, but only
14900     * if things are idle.
14901     */
14902    final void performAppGcsLocked() {
14903        final int N = mProcessesToGc.size();
14904        if (N <= 0) {
14905            return;
14906        }
14907        if (canGcNowLocked()) {
14908            while (mProcessesToGc.size() > 0) {
14909                ProcessRecord proc = mProcessesToGc.remove(0);
14910                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
14911                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14912                            <= SystemClock.uptimeMillis()) {
14913                        // To avoid spamming the system, we will GC processes one
14914                        // at a time, waiting a few seconds between each.
14915                        performAppGcLocked(proc);
14916                        scheduleAppGcsLocked();
14917                        return;
14918                    } else {
14919                        // It hasn't been long enough since we last GCed this
14920                        // process...  put it in the list to wait for its time.
14921                        addProcessToGcListLocked(proc);
14922                        break;
14923                    }
14924                }
14925            }
14926
14927            scheduleAppGcsLocked();
14928        }
14929    }
14930
14931    /**
14932     * If all looks good, perform GCs on all processes waiting for them.
14933     */
14934    final void performAppGcsIfAppropriateLocked() {
14935        if (canGcNowLocked()) {
14936            performAppGcsLocked();
14937            return;
14938        }
14939        // Still not idle, wait some more.
14940        scheduleAppGcsLocked();
14941    }
14942
14943    /**
14944     * Schedule the execution of all pending app GCs.
14945     */
14946    final void scheduleAppGcsLocked() {
14947        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
14948
14949        if (mProcessesToGc.size() > 0) {
14950            // Schedule a GC for the time to the next process.
14951            ProcessRecord proc = mProcessesToGc.get(0);
14952            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14953
14954            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
14955            long now = SystemClock.uptimeMillis();
14956            if (when < (now+GC_TIMEOUT)) {
14957                when = now + GC_TIMEOUT;
14958            }
14959            mHandler.sendMessageAtTime(msg, when);
14960        }
14961    }
14962
14963    /**
14964     * Add a process to the array of processes waiting to be GCed.  Keeps the
14965     * list in sorted order by the last GC time.  The process can't already be
14966     * on the list.
14967     */
14968    final void addProcessToGcListLocked(ProcessRecord proc) {
14969        boolean added = false;
14970        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14971            if (mProcessesToGc.get(i).lastRequestedGc <
14972                    proc.lastRequestedGc) {
14973                added = true;
14974                mProcessesToGc.add(i+1, proc);
14975                break;
14976            }
14977        }
14978        if (!added) {
14979            mProcessesToGc.add(0, proc);
14980        }
14981    }
14982
14983    /**
14984     * Set up to ask a process to GC itself.  This will either do it
14985     * immediately, or put it on the list of processes to gc the next
14986     * time things are idle.
14987     */
14988    final void scheduleAppGcLocked(ProcessRecord app) {
14989        long now = SystemClock.uptimeMillis();
14990        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
14991            return;
14992        }
14993        if (!mProcessesToGc.contains(app)) {
14994            addProcessToGcListLocked(app);
14995            scheduleAppGcsLocked();
14996        }
14997    }
14998
14999    final void checkExcessivePowerUsageLocked(boolean doKills) {
15000        updateCpuStatsNow();
15001
15002        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15003        boolean doWakeKills = doKills;
15004        boolean doCpuKills = doKills;
15005        if (mLastPowerCheckRealtime == 0) {
15006            doWakeKills = false;
15007        }
15008        if (mLastPowerCheckUptime == 0) {
15009            doCpuKills = false;
15010        }
15011        if (stats.isScreenOn()) {
15012            doWakeKills = false;
15013        }
15014        final long curRealtime = SystemClock.elapsedRealtime();
15015        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15016        final long curUptime = SystemClock.uptimeMillis();
15017        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15018        mLastPowerCheckRealtime = curRealtime;
15019        mLastPowerCheckUptime = curUptime;
15020        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15021            doWakeKills = false;
15022        }
15023        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15024            doCpuKills = false;
15025        }
15026        int i = mLruProcesses.size();
15027        while (i > 0) {
15028            i--;
15029            ProcessRecord app = mLruProcesses.get(i);
15030            if (!app.keeping) {
15031                long wtime;
15032                synchronized (stats) {
15033                    wtime = stats.getProcessWakeTime(app.info.uid,
15034                            app.pid, curRealtime);
15035                }
15036                long wtimeUsed = wtime - app.lastWakeTime;
15037                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15038                if (DEBUG_POWER) {
15039                    StringBuilder sb = new StringBuilder(128);
15040                    sb.append("Wake for ");
15041                    app.toShortString(sb);
15042                    sb.append(": over ");
15043                    TimeUtils.formatDuration(realtimeSince, sb);
15044                    sb.append(" used ");
15045                    TimeUtils.formatDuration(wtimeUsed, sb);
15046                    sb.append(" (");
15047                    sb.append((wtimeUsed*100)/realtimeSince);
15048                    sb.append("%)");
15049                    Slog.i(TAG, sb.toString());
15050                    sb.setLength(0);
15051                    sb.append("CPU for ");
15052                    app.toShortString(sb);
15053                    sb.append(": over ");
15054                    TimeUtils.formatDuration(uptimeSince, sb);
15055                    sb.append(" used ");
15056                    TimeUtils.formatDuration(cputimeUsed, sb);
15057                    sb.append(" (");
15058                    sb.append((cputimeUsed*100)/uptimeSince);
15059                    sb.append("%)");
15060                    Slog.i(TAG, sb.toString());
15061                }
15062                // If a process has held a wake lock for more
15063                // than 50% of the time during this period,
15064                // that sounds bad.  Kill!
15065                if (doWakeKills && realtimeSince > 0
15066                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15067                    synchronized (stats) {
15068                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15069                                realtimeSince, wtimeUsed);
15070                    }
15071                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15072                            + " during " + realtimeSince);
15073                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15074                } else if (doCpuKills && uptimeSince > 0
15075                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15076                    synchronized (stats) {
15077                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15078                                uptimeSince, cputimeUsed);
15079                    }
15080                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15081                            + " during " + uptimeSince);
15082                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15083                } else {
15084                    app.lastWakeTime = wtime;
15085                    app.lastCpuTime = app.curCpuTime;
15086                }
15087            }
15088        }
15089    }
15090
15091    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15092            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15093        boolean success = true;
15094
15095        if (app.curRawAdj != app.setRawAdj) {
15096            if (wasKeeping && !app.keeping) {
15097                // This app is no longer something we want to keep.  Note
15098                // its current wake lock time to later know to kill it if
15099                // it is not behaving well.
15100                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15101                synchronized (stats) {
15102                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15103                            app.pid, SystemClock.elapsedRealtime());
15104                }
15105                app.lastCpuTime = app.curCpuTime;
15106            }
15107
15108            app.setRawAdj = app.curRawAdj;
15109        }
15110
15111        if (app.curAdj != app.setAdj) {
15112            ProcessList.setOomAdj(app.pid, app.curAdj);
15113            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15114                TAG, "Set " + app.pid + " " + app.processName +
15115                " adj " + app.curAdj + ": " + app.adjType);
15116            app.setAdj = app.curAdj;
15117        }
15118
15119        if (app.setSchedGroup != app.curSchedGroup) {
15120            app.setSchedGroup = app.curSchedGroup;
15121            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15122                    "Setting process group of " + app.processName
15123                    + " to " + app.curSchedGroup);
15124            if (app.waitingToKill != null &&
15125                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15126                killUnneededProcessLocked(app, app.waitingToKill);
15127                success = false;
15128            } else {
15129                if (true) {
15130                    long oldId = Binder.clearCallingIdentity();
15131                    try {
15132                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15133                    } catch (Exception e) {
15134                        Slog.w(TAG, "Failed setting process group of " + app.pid
15135                                + " to " + app.curSchedGroup);
15136                        e.printStackTrace();
15137                    } finally {
15138                        Binder.restoreCallingIdentity(oldId);
15139                    }
15140                } else {
15141                    if (app.thread != null) {
15142                        try {
15143                            app.thread.setSchedulingGroup(app.curSchedGroup);
15144                        } catch (RemoteException e) {
15145                        }
15146                    }
15147                }
15148                Process.setSwappiness(app.pid,
15149                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15150            }
15151        }
15152        if (app.repProcState != app.curProcState) {
15153            app.repProcState = app.curProcState;
15154            if (!reportingProcessState && app.thread != null) {
15155                try {
15156                    if (false) {
15157                        //RuntimeException h = new RuntimeException("here");
15158                        Slog.i(TAG, "Sending new process state " + app.repProcState
15159                                + " to " + app /*, h*/);
15160                    }
15161                    app.thread.setProcessState(app.repProcState);
15162                } catch (RemoteException e) {
15163                }
15164            }
15165        }
15166        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15167                app.setProcState)) {
15168            app.lastStateTime = now;
15169            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15170                    mSleeping, now);
15171            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15172                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15173                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15174                    + (app.nextPssTime-now) + ": " + app);
15175        } else {
15176            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15177                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15178                requestPssLocked(app, app.setProcState);
15179                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15180                        mSleeping, now);
15181            } else if (false && DEBUG_PSS) {
15182                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15183            }
15184        }
15185        if (app.setProcState != app.curProcState) {
15186            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15187                    "Proc state change of " + app.processName
15188                    + " to " + app.curProcState);
15189            app.setProcState = app.curProcState;
15190            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15191                app.notCachedSinceIdle = false;
15192            }
15193            if (!doingAll) {
15194                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15195            } else {
15196                app.procStateChanged = true;
15197            }
15198        }
15199        return success;
15200    }
15201
15202    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15203        if (proc.thread != null && proc.baseProcessTracker != null) {
15204            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15205        }
15206    }
15207
15208    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15209            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15210        if (app.thread == null) {
15211            return false;
15212        }
15213
15214        final boolean wasKeeping = app.keeping;
15215
15216        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15217
15218        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15219                reportingProcessState, now);
15220    }
15221
15222    private final ActivityRecord resumedAppLocked() {
15223        return mStackSupervisor.resumedAppLocked();
15224    }
15225
15226    final boolean updateOomAdjLocked(ProcessRecord app) {
15227        return updateOomAdjLocked(app, false);
15228    }
15229
15230    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15231        final ActivityRecord TOP_ACT = resumedAppLocked();
15232        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15233        final boolean wasCached = app.cached;
15234
15235        mAdjSeq++;
15236
15237        // This is the desired cached adjusment we want to tell it to use.
15238        // If our app is currently cached, we know it, and that is it.  Otherwise,
15239        // we don't know it yet, and it needs to now be cached we will then
15240        // need to do a complete oom adj.
15241        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15242                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15243        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15244                SystemClock.uptimeMillis());
15245        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15246            // Changed to/from cached state, so apps after it in the LRU
15247            // list may also be changed.
15248            updateOomAdjLocked();
15249        }
15250        return success;
15251    }
15252
15253    final void updateOomAdjLocked() {
15254        final ActivityRecord TOP_ACT = resumedAppLocked();
15255        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15256        final long now = SystemClock.uptimeMillis();
15257        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15258        final int N = mLruProcesses.size();
15259
15260        if (false) {
15261            RuntimeException e = new RuntimeException();
15262            e.fillInStackTrace();
15263            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15264        }
15265
15266        mAdjSeq++;
15267        mNewNumServiceProcs = 0;
15268        mNewNumAServiceProcs = 0;
15269
15270        final int emptyProcessLimit;
15271        final int cachedProcessLimit;
15272        if (mProcessLimit <= 0) {
15273            emptyProcessLimit = cachedProcessLimit = 0;
15274        } else if (mProcessLimit == 1) {
15275            emptyProcessLimit = 1;
15276            cachedProcessLimit = 0;
15277        } else {
15278            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15279            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15280        }
15281
15282        // Let's determine how many processes we have running vs.
15283        // how many slots we have for background processes; we may want
15284        // to put multiple processes in a slot of there are enough of
15285        // them.
15286        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15287                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15288        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15289        if (numEmptyProcs > cachedProcessLimit) {
15290            // If there are more empty processes than our limit on cached
15291            // processes, then use the cached process limit for the factor.
15292            // This ensures that the really old empty processes get pushed
15293            // down to the bottom, so if we are running low on memory we will
15294            // have a better chance at keeping around more cached processes
15295            // instead of a gazillion empty processes.
15296            numEmptyProcs = cachedProcessLimit;
15297        }
15298        int emptyFactor = numEmptyProcs/numSlots;
15299        if (emptyFactor < 1) emptyFactor = 1;
15300        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15301        if (cachedFactor < 1) cachedFactor = 1;
15302        int stepCached = 0;
15303        int stepEmpty = 0;
15304        int numCached = 0;
15305        int numEmpty = 0;
15306        int numTrimming = 0;
15307
15308        mNumNonCachedProcs = 0;
15309        mNumCachedHiddenProcs = 0;
15310
15311        // First update the OOM adjustment for each of the
15312        // application processes based on their current state.
15313        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15314        int nextCachedAdj = curCachedAdj+1;
15315        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15316        int nextEmptyAdj = curEmptyAdj+2;
15317        for (int i=N-1; i>=0; i--) {
15318            ProcessRecord app = mLruProcesses.get(i);
15319            if (!app.killedByAm && app.thread != null) {
15320                app.procStateChanged = false;
15321                final boolean wasKeeping = app.keeping;
15322                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15323
15324                // If we haven't yet assigned the final cached adj
15325                // to the process, do that now.
15326                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15327                    switch (app.curProcState) {
15328                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15329                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15330                            // This process is a cached process holding activities...
15331                            // assign it the next cached value for that type, and then
15332                            // step that cached level.
15333                            app.curRawAdj = curCachedAdj;
15334                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15335                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15336                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15337                                    + ")");
15338                            if (curCachedAdj != nextCachedAdj) {
15339                                stepCached++;
15340                                if (stepCached >= cachedFactor) {
15341                                    stepCached = 0;
15342                                    curCachedAdj = nextCachedAdj;
15343                                    nextCachedAdj += 2;
15344                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15345                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15346                                    }
15347                                }
15348                            }
15349                            break;
15350                        default:
15351                            // For everything else, assign next empty cached process
15352                            // level and bump that up.  Note that this means that
15353                            // long-running services that have dropped down to the
15354                            // cached level will be treated as empty (since their process
15355                            // state is still as a service), which is what we want.
15356                            app.curRawAdj = curEmptyAdj;
15357                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15358                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15359                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15360                                    + ")");
15361                            if (curEmptyAdj != nextEmptyAdj) {
15362                                stepEmpty++;
15363                                if (stepEmpty >= emptyFactor) {
15364                                    stepEmpty = 0;
15365                                    curEmptyAdj = nextEmptyAdj;
15366                                    nextEmptyAdj += 2;
15367                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15368                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15369                                    }
15370                                }
15371                            }
15372                            break;
15373                    }
15374                }
15375
15376                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15377
15378                // Count the number of process types.
15379                switch (app.curProcState) {
15380                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15381                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15382                        mNumCachedHiddenProcs++;
15383                        numCached++;
15384                        if (numCached > cachedProcessLimit) {
15385                            killUnneededProcessLocked(app, "cached #" + numCached);
15386                        }
15387                        break;
15388                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15389                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15390                                && app.lastActivityTime < oldTime) {
15391                            killUnneededProcessLocked(app, "empty for "
15392                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15393                                    / 1000) + "s");
15394                        } else {
15395                            numEmpty++;
15396                            if (numEmpty > emptyProcessLimit) {
15397                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15398                            }
15399                        }
15400                        break;
15401                    default:
15402                        mNumNonCachedProcs++;
15403                        break;
15404                }
15405
15406                if (app.isolated && app.services.size() <= 0) {
15407                    // If this is an isolated process, and there are no
15408                    // services running in it, then the process is no longer
15409                    // needed.  We agressively kill these because we can by
15410                    // definition not re-use the same process again, and it is
15411                    // good to avoid having whatever code was running in them
15412                    // left sitting around after no longer needed.
15413                    killUnneededProcessLocked(app, "isolated not needed");
15414                }
15415
15416                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15417                        && !app.killedByAm) {
15418                    numTrimming++;
15419                }
15420            }
15421        }
15422
15423        mNumServiceProcs = mNewNumServiceProcs;
15424
15425        // Now determine the memory trimming level of background processes.
15426        // Unfortunately we need to start at the back of the list to do this
15427        // properly.  We only do this if the number of background apps we
15428        // are managing to keep around is less than half the maximum we desire;
15429        // if we are keeping a good number around, we'll let them use whatever
15430        // memory they want.
15431        final int numCachedAndEmpty = numCached + numEmpty;
15432        int memFactor;
15433        if (numCached <= ProcessList.TRIM_CACHED_APPS
15434                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15435            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15436                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15437            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15438                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15439            } else {
15440                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15441            }
15442        } else {
15443            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15444        }
15445        // We always allow the memory level to go up (better).  We only allow it to go
15446        // down if we are in a state where that is allowed, *and* the total number of processes
15447        // has gone down since last time.
15448        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15449                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15450                + " last=" + mLastNumProcesses);
15451        if (memFactor > mLastMemoryLevel) {
15452            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15453                memFactor = mLastMemoryLevel;
15454                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15455            }
15456        }
15457        mLastMemoryLevel = memFactor;
15458        mLastNumProcesses = mLruProcesses.size();
15459        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15460        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15461        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15462            if (mLowRamStartTime == 0) {
15463                mLowRamStartTime = now;
15464            }
15465            int step = 0;
15466            int fgTrimLevel;
15467            switch (memFactor) {
15468                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15469                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15470                    break;
15471                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15472                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15473                    break;
15474                default:
15475                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15476                    break;
15477            }
15478            int factor = numTrimming/3;
15479            int minFactor = 2;
15480            if (mHomeProcess != null) minFactor++;
15481            if (mPreviousProcess != null) minFactor++;
15482            if (factor < minFactor) factor = minFactor;
15483            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15484            for (int i=N-1; i>=0; i--) {
15485                ProcessRecord app = mLruProcesses.get(i);
15486                if (allChanged || app.procStateChanged) {
15487                    setProcessTrackerState(app, trackerMemFactor, now);
15488                    app.procStateChanged = false;
15489                }
15490                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15491                        && !app.killedByAm) {
15492                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15493                        try {
15494                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15495                                    "Trimming memory of " + app.processName
15496                                    + " to " + curLevel);
15497                            app.thread.scheduleTrimMemory(curLevel);
15498                        } catch (RemoteException e) {
15499                        }
15500                        if (false) {
15501                            // For now we won't do this; our memory trimming seems
15502                            // to be good enough at this point that destroying
15503                            // activities causes more harm than good.
15504                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15505                                    && app != mHomeProcess && app != mPreviousProcess) {
15506                                // Need to do this on its own message because the stack may not
15507                                // be in a consistent state at this point.
15508                                // For these apps we will also finish their activities
15509                                // to help them free memory.
15510                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15511                            }
15512                        }
15513                    }
15514                    app.trimMemoryLevel = curLevel;
15515                    step++;
15516                    if (step >= factor) {
15517                        step = 0;
15518                        switch (curLevel) {
15519                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15520                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15521                                break;
15522                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15523                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15524                                break;
15525                        }
15526                    }
15527                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15528                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15529                            && app.thread != null) {
15530                        try {
15531                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15532                                    "Trimming memory of heavy-weight " + app.processName
15533                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15534                            app.thread.scheduleTrimMemory(
15535                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15536                        } catch (RemoteException e) {
15537                        }
15538                    }
15539                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15540                } else {
15541                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15542                            || app.systemNoUi) && app.pendingUiClean) {
15543                        // If this application is now in the background and it
15544                        // had done UI, then give it the special trim level to
15545                        // have it free UI resources.
15546                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15547                        if (app.trimMemoryLevel < level && app.thread != null) {
15548                            try {
15549                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15550                                        "Trimming memory of bg-ui " + app.processName
15551                                        + " to " + level);
15552                                app.thread.scheduleTrimMemory(level);
15553                            } catch (RemoteException e) {
15554                            }
15555                        }
15556                        app.pendingUiClean = false;
15557                    }
15558                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15559                        try {
15560                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15561                                    "Trimming memory of fg " + app.processName
15562                                    + " to " + fgTrimLevel);
15563                            app.thread.scheduleTrimMemory(fgTrimLevel);
15564                        } catch (RemoteException e) {
15565                        }
15566                    }
15567                    app.trimMemoryLevel = fgTrimLevel;
15568                }
15569            }
15570        } else {
15571            if (mLowRamStartTime != 0) {
15572                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15573                mLowRamStartTime = 0;
15574            }
15575            for (int i=N-1; i>=0; i--) {
15576                ProcessRecord app = mLruProcesses.get(i);
15577                if (allChanged || app.procStateChanged) {
15578                    setProcessTrackerState(app, trackerMemFactor, now);
15579                    app.procStateChanged = false;
15580                }
15581                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15582                        || app.systemNoUi) && app.pendingUiClean) {
15583                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15584                            && app.thread != null) {
15585                        try {
15586                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15587                                    "Trimming memory of ui hidden " + app.processName
15588                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15589                            app.thread.scheduleTrimMemory(
15590                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15591                        } catch (RemoteException e) {
15592                        }
15593                    }
15594                    app.pendingUiClean = false;
15595                }
15596                app.trimMemoryLevel = 0;
15597            }
15598        }
15599
15600        if (mAlwaysFinishActivities) {
15601            // Need to do this on its own message because the stack may not
15602            // be in a consistent state at this point.
15603            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15604        }
15605
15606        if (allChanged) {
15607            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15608        }
15609
15610        if (mProcessStats.shouldWriteNowLocked(now)) {
15611            mHandler.post(new Runnable() {
15612                @Override public void run() {
15613                    synchronized (ActivityManagerService.this) {
15614                        mProcessStats.writeStateAsyncLocked();
15615                    }
15616                }
15617            });
15618        }
15619
15620        if (DEBUG_OOM_ADJ) {
15621            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15622        }
15623    }
15624
15625    final void trimApplications() {
15626        synchronized (this) {
15627            int i;
15628
15629            // First remove any unused application processes whose package
15630            // has been removed.
15631            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15632                final ProcessRecord app = mRemovedProcesses.get(i);
15633                if (app.activities.size() == 0
15634                        && app.curReceiver == null && app.services.size() == 0) {
15635                    Slog.i(
15636                        TAG, "Exiting empty application process "
15637                        + app.processName + " ("
15638                        + (app.thread != null ? app.thread.asBinder() : null)
15639                        + ")\n");
15640                    if (app.pid > 0 && app.pid != MY_PID) {
15641                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15642                                app.processName, app.setAdj, "empty");
15643                        app.killedByAm = true;
15644                        Process.killProcessQuiet(app.pid);
15645                    } else {
15646                        try {
15647                            app.thread.scheduleExit();
15648                        } catch (Exception e) {
15649                            // Ignore exceptions.
15650                        }
15651                    }
15652                    cleanUpApplicationRecordLocked(app, false, true, -1);
15653                    mRemovedProcesses.remove(i);
15654
15655                    if (app.persistent) {
15656                        if (app.persistent) {
15657                            addAppLocked(app.info, false);
15658                        }
15659                    }
15660                }
15661            }
15662
15663            // Now update the oom adj for all processes.
15664            updateOomAdjLocked();
15665        }
15666    }
15667
15668    /** This method sends the specified signal to each of the persistent apps */
15669    public void signalPersistentProcesses(int sig) throws RemoteException {
15670        if (sig != Process.SIGNAL_USR1) {
15671            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15672        }
15673
15674        synchronized (this) {
15675            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15676                    != PackageManager.PERMISSION_GRANTED) {
15677                throw new SecurityException("Requires permission "
15678                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15679            }
15680
15681            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15682                ProcessRecord r = mLruProcesses.get(i);
15683                if (r.thread != null && r.persistent) {
15684                    Process.sendSignal(r.pid, sig);
15685                }
15686            }
15687        }
15688    }
15689
15690    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15691        if (proc == null || proc == mProfileProc) {
15692            proc = mProfileProc;
15693            path = mProfileFile;
15694            profileType = mProfileType;
15695            clearProfilerLocked();
15696        }
15697        if (proc == null) {
15698            return;
15699        }
15700        try {
15701            proc.thread.profilerControl(false, path, null, profileType);
15702        } catch (RemoteException e) {
15703            throw new IllegalStateException("Process disappeared");
15704        }
15705    }
15706
15707    private void clearProfilerLocked() {
15708        if (mProfileFd != null) {
15709            try {
15710                mProfileFd.close();
15711            } catch (IOException e) {
15712            }
15713        }
15714        mProfileApp = null;
15715        mProfileProc = null;
15716        mProfileFile = null;
15717        mProfileType = 0;
15718        mAutoStopProfiler = false;
15719    }
15720
15721    public boolean profileControl(String process, int userId, boolean start,
15722            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15723
15724        try {
15725            synchronized (this) {
15726                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15727                // its own permission.
15728                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15729                        != PackageManager.PERMISSION_GRANTED) {
15730                    throw new SecurityException("Requires permission "
15731                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15732                }
15733
15734                if (start && fd == null) {
15735                    throw new IllegalArgumentException("null fd");
15736                }
15737
15738                ProcessRecord proc = null;
15739                if (process != null) {
15740                    proc = findProcessLocked(process, userId, "profileControl");
15741                }
15742
15743                if (start && (proc == null || proc.thread == null)) {
15744                    throw new IllegalArgumentException("Unknown process: " + process);
15745                }
15746
15747                if (start) {
15748                    stopProfilerLocked(null, null, 0);
15749                    setProfileApp(proc.info, proc.processName, path, fd, false);
15750                    mProfileProc = proc;
15751                    mProfileType = profileType;
15752                    try {
15753                        fd = fd.dup();
15754                    } catch (IOException e) {
15755                        fd = null;
15756                    }
15757                    proc.thread.profilerControl(start, path, fd, profileType);
15758                    fd = null;
15759                    mProfileFd = null;
15760                } else {
15761                    stopProfilerLocked(proc, path, profileType);
15762                    if (fd != null) {
15763                        try {
15764                            fd.close();
15765                        } catch (IOException e) {
15766                        }
15767                    }
15768                }
15769
15770                return true;
15771            }
15772        } catch (RemoteException e) {
15773            throw new IllegalStateException("Process disappeared");
15774        } finally {
15775            if (fd != null) {
15776                try {
15777                    fd.close();
15778                } catch (IOException e) {
15779                }
15780            }
15781        }
15782    }
15783
15784    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15785        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15786                userId, true, true, callName, null);
15787        ProcessRecord proc = null;
15788        try {
15789            int pid = Integer.parseInt(process);
15790            synchronized (mPidsSelfLocked) {
15791                proc = mPidsSelfLocked.get(pid);
15792            }
15793        } catch (NumberFormatException e) {
15794        }
15795
15796        if (proc == null) {
15797            ArrayMap<String, SparseArray<ProcessRecord>> all
15798                    = mProcessNames.getMap();
15799            SparseArray<ProcessRecord> procs = all.get(process);
15800            if (procs != null && procs.size() > 0) {
15801                proc = procs.valueAt(0);
15802                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
15803                    for (int i=1; i<procs.size(); i++) {
15804                        ProcessRecord thisProc = procs.valueAt(i);
15805                        if (thisProc.userId == userId) {
15806                            proc = thisProc;
15807                            break;
15808                        }
15809                    }
15810                }
15811            }
15812        }
15813
15814        return proc;
15815    }
15816
15817    public boolean dumpHeap(String process, int userId, boolean managed,
15818            String path, ParcelFileDescriptor fd) throws RemoteException {
15819
15820        try {
15821            synchronized (this) {
15822                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15823                // its own permission (same as profileControl).
15824                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15825                        != PackageManager.PERMISSION_GRANTED) {
15826                    throw new SecurityException("Requires permission "
15827                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15828                }
15829
15830                if (fd == null) {
15831                    throw new IllegalArgumentException("null fd");
15832                }
15833
15834                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
15835                if (proc == null || proc.thread == null) {
15836                    throw new IllegalArgumentException("Unknown process: " + process);
15837                }
15838
15839                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15840                if (!isDebuggable) {
15841                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15842                        throw new SecurityException("Process not debuggable: " + proc);
15843                    }
15844                }
15845
15846                proc.thread.dumpHeap(managed, path, fd);
15847                fd = null;
15848                return true;
15849            }
15850        } catch (RemoteException e) {
15851            throw new IllegalStateException("Process disappeared");
15852        } finally {
15853            if (fd != null) {
15854                try {
15855                    fd.close();
15856                } catch (IOException e) {
15857                }
15858            }
15859        }
15860    }
15861
15862    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15863    public void monitor() {
15864        synchronized (this) { }
15865    }
15866
15867    void onCoreSettingsChange(Bundle settings) {
15868        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15869            ProcessRecord processRecord = mLruProcesses.get(i);
15870            try {
15871                if (processRecord.thread != null) {
15872                    processRecord.thread.setCoreSettings(settings);
15873                }
15874            } catch (RemoteException re) {
15875                /* ignore */
15876            }
15877        }
15878    }
15879
15880    // Multi-user methods
15881
15882    @Override
15883    public boolean switchUser(final int userId) {
15884        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
15885                != PackageManager.PERMISSION_GRANTED) {
15886            String msg = "Permission Denial: switchUser() from pid="
15887                    + Binder.getCallingPid()
15888                    + ", uid=" + Binder.getCallingUid()
15889                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
15890            Slog.w(TAG, msg);
15891            throw new SecurityException(msg);
15892        }
15893
15894        final long ident = Binder.clearCallingIdentity();
15895        try {
15896            synchronized (this) {
15897                final int oldUserId = mCurrentUserId;
15898                if (oldUserId == userId) {
15899                    return true;
15900                }
15901
15902                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
15903                if (userInfo == null) {
15904                    Slog.w(TAG, "No user info for user #" + userId);
15905                    return false;
15906                }
15907
15908                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
15909                        R.anim.screen_user_enter);
15910
15911                boolean needStart = false;
15912
15913                // If the user we are switching to is not currently started, then
15914                // we need to start it now.
15915                if (mStartedUsers.get(userId) == null) {
15916                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
15917                    updateStartedUserArrayLocked();
15918                    needStart = true;
15919                }
15920
15921                mCurrentUserId = userId;
15922                final Integer userIdInt = Integer.valueOf(userId);
15923                mUserLru.remove(userIdInt);
15924                mUserLru.add(userIdInt);
15925
15926                mWindowManager.setCurrentUser(userId);
15927
15928                // Once the internal notion of the active user has switched, we lock the device
15929                // with the option to show the user switcher on the keyguard.
15930                mWindowManager.lockNow(null);
15931
15932                final UserStartedState uss = mStartedUsers.get(userId);
15933
15934                // Make sure user is in the started state.  If it is currently
15935                // stopping, we need to knock that off.
15936                if (uss.mState == UserStartedState.STATE_STOPPING) {
15937                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
15938                    // so we can just fairly silently bring the user back from
15939                    // the almost-dead.
15940                    uss.mState = UserStartedState.STATE_RUNNING;
15941                    updateStartedUserArrayLocked();
15942                    needStart = true;
15943                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
15944                    // This means ACTION_SHUTDOWN has been sent, so we will
15945                    // need to treat this as a new boot of the user.
15946                    uss.mState = UserStartedState.STATE_BOOTING;
15947                    updateStartedUserArrayLocked();
15948                    needStart = true;
15949                }
15950
15951                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
15952                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
15953                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
15954                        oldUserId, userId, uss));
15955                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
15956                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
15957                if (needStart) {
15958                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
15959                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15960                            | Intent.FLAG_RECEIVER_FOREGROUND);
15961                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
15962                    broadcastIntentLocked(null, null, intent,
15963                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15964                            false, false, MY_PID, Process.SYSTEM_UID, userId);
15965                }
15966
15967                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
15968                    if (userId != 0) {
15969                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
15970                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15971                        broadcastIntentLocked(null, null, intent, null,
15972                                new IIntentReceiver.Stub() {
15973                                    public void performReceive(Intent intent, int resultCode,
15974                                            String data, Bundle extras, boolean ordered,
15975                                            boolean sticky, int sendingUser) {
15976                                        userInitialized(uss, userId);
15977                                    }
15978                                }, 0, null, null, null, AppOpsManager.OP_NONE,
15979                                true, false, MY_PID, Process.SYSTEM_UID,
15980                                userId);
15981                        uss.initializing = true;
15982                    } else {
15983                        getUserManagerLocked().makeInitialized(userInfo.id);
15984                    }
15985                }
15986
15987                boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
15988                if (homeInFront) {
15989                    startHomeActivityLocked(userId);
15990                } else {
15991                    mStackSupervisor.resumeTopActivitiesLocked();
15992                }
15993
15994                EventLogTags.writeAmSwitchUser(userId);
15995                getUserManagerLocked().userForeground(userId);
15996                sendUserSwitchBroadcastsLocked(oldUserId, userId);
15997                if (needStart) {
15998                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
15999                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16000                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16001                    broadcastIntentLocked(null, null, intent,
16002                            null, new IIntentReceiver.Stub() {
16003                                @Override
16004                                public void performReceive(Intent intent, int resultCode, String data,
16005                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16006                                        throws RemoteException {
16007                                }
16008                            }, 0, null, null,
16009                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16010                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16011                }
16012            }
16013        } finally {
16014            Binder.restoreCallingIdentity(ident);
16015        }
16016
16017        return true;
16018    }
16019
16020    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16021        long ident = Binder.clearCallingIdentity();
16022        try {
16023            Intent intent;
16024            if (oldUserId >= 0) {
16025                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16026                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16027                        | Intent.FLAG_RECEIVER_FOREGROUND);
16028                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16029                broadcastIntentLocked(null, null, intent,
16030                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16031                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16032            }
16033            if (newUserId >= 0) {
16034                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16035                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16036                        | Intent.FLAG_RECEIVER_FOREGROUND);
16037                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16038                broadcastIntentLocked(null, null, intent,
16039                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16040                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16041                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16042                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16043                        | Intent.FLAG_RECEIVER_FOREGROUND);
16044                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16045                broadcastIntentLocked(null, null, intent,
16046                        null, null, 0, null, null,
16047                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16048                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16049            }
16050        } finally {
16051            Binder.restoreCallingIdentity(ident);
16052        }
16053    }
16054
16055    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16056            final int newUserId) {
16057        final int N = mUserSwitchObservers.beginBroadcast();
16058        if (N > 0) {
16059            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16060                int mCount = 0;
16061                @Override
16062                public void sendResult(Bundle data) throws RemoteException {
16063                    synchronized (ActivityManagerService.this) {
16064                        if (mCurUserSwitchCallback == this) {
16065                            mCount++;
16066                            if (mCount == N) {
16067                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16068                            }
16069                        }
16070                    }
16071                }
16072            };
16073            synchronized (this) {
16074                uss.switching = true;
16075                mCurUserSwitchCallback = callback;
16076            }
16077            for (int i=0; i<N; i++) {
16078                try {
16079                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16080                            newUserId, callback);
16081                } catch (RemoteException e) {
16082                }
16083            }
16084        } else {
16085            synchronized (this) {
16086                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16087            }
16088        }
16089        mUserSwitchObservers.finishBroadcast();
16090    }
16091
16092    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16093        synchronized (this) {
16094            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16095            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16096        }
16097    }
16098
16099    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16100        mCurUserSwitchCallback = null;
16101        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16102        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16103                oldUserId, newUserId, uss));
16104    }
16105
16106    void userInitialized(UserStartedState uss, int newUserId) {
16107        completeSwitchAndInitalize(uss, newUserId, true, false);
16108    }
16109
16110    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16111        completeSwitchAndInitalize(uss, newUserId, false, true);
16112    }
16113
16114    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16115            boolean clearInitializing, boolean clearSwitching) {
16116        boolean unfrozen = false;
16117        synchronized (this) {
16118            if (clearInitializing) {
16119                uss.initializing = false;
16120                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16121            }
16122            if (clearSwitching) {
16123                uss.switching = false;
16124            }
16125            if (!uss.switching && !uss.initializing) {
16126                mWindowManager.stopFreezingScreen();
16127                unfrozen = true;
16128            }
16129        }
16130        if (unfrozen) {
16131            final int N = mUserSwitchObservers.beginBroadcast();
16132            for (int i=0; i<N; i++) {
16133                try {
16134                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16135                } catch (RemoteException e) {
16136                }
16137            }
16138            mUserSwitchObservers.finishBroadcast();
16139        }
16140    }
16141
16142    void finishUserSwitch(UserStartedState uss) {
16143        synchronized (this) {
16144            if (uss.mState == UserStartedState.STATE_BOOTING
16145                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16146                uss.mState = UserStartedState.STATE_RUNNING;
16147                final int userId = uss.mHandle.getIdentifier();
16148                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16149                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16150                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16151                broadcastIntentLocked(null, null, intent,
16152                        null, null, 0, null, null,
16153                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16154                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16155            }
16156            int num = mUserLru.size();
16157            int i = 0;
16158            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16159                Integer oldUserId = mUserLru.get(i);
16160                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16161                if (oldUss == null) {
16162                    // Shouldn't happen, but be sane if it does.
16163                    mUserLru.remove(i);
16164                    num--;
16165                    continue;
16166                }
16167                if (oldUss.mState == UserStartedState.STATE_STOPPING
16168                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16169                    // This user is already stopping, doesn't count.
16170                    num--;
16171                    i++;
16172                    continue;
16173                }
16174                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16175                    // Owner and current can't be stopped, but count as running.
16176                    i++;
16177                    continue;
16178                }
16179                // This is a user to be stopped.
16180                stopUserLocked(oldUserId, null);
16181                num--;
16182                i++;
16183            }
16184        }
16185    }
16186
16187    @Override
16188    public int stopUser(final int userId, final IStopUserCallback callback) {
16189        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16190                != PackageManager.PERMISSION_GRANTED) {
16191            String msg = "Permission Denial: switchUser() from pid="
16192                    + Binder.getCallingPid()
16193                    + ", uid=" + Binder.getCallingUid()
16194                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16195            Slog.w(TAG, msg);
16196            throw new SecurityException(msg);
16197        }
16198        if (userId <= 0) {
16199            throw new IllegalArgumentException("Can't stop primary user " + userId);
16200        }
16201        synchronized (this) {
16202            return stopUserLocked(userId, callback);
16203        }
16204    }
16205
16206    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16207        if (mCurrentUserId == userId) {
16208            return ActivityManager.USER_OP_IS_CURRENT;
16209        }
16210
16211        final UserStartedState uss = mStartedUsers.get(userId);
16212        if (uss == null) {
16213            // User is not started, nothing to do...  but we do need to
16214            // callback if requested.
16215            if (callback != null) {
16216                mHandler.post(new Runnable() {
16217                    @Override
16218                    public void run() {
16219                        try {
16220                            callback.userStopped(userId);
16221                        } catch (RemoteException e) {
16222                        }
16223                    }
16224                });
16225            }
16226            return ActivityManager.USER_OP_SUCCESS;
16227        }
16228
16229        if (callback != null) {
16230            uss.mStopCallbacks.add(callback);
16231        }
16232
16233        if (uss.mState != UserStartedState.STATE_STOPPING
16234                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16235            uss.mState = UserStartedState.STATE_STOPPING;
16236            updateStartedUserArrayLocked();
16237
16238            long ident = Binder.clearCallingIdentity();
16239            try {
16240                // We are going to broadcast ACTION_USER_STOPPING and then
16241                // once that is done send a final ACTION_SHUTDOWN and then
16242                // stop the user.
16243                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16244                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16245                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16246                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16247                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16248                // This is the result receiver for the final shutdown broadcast.
16249                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16250                    @Override
16251                    public void performReceive(Intent intent, int resultCode, String data,
16252                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16253                        finishUserStop(uss);
16254                    }
16255                };
16256                // This is the result receiver for the initial stopping broadcast.
16257                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16258                    @Override
16259                    public void performReceive(Intent intent, int resultCode, String data,
16260                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16261                        // On to the next.
16262                        synchronized (ActivityManagerService.this) {
16263                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16264                                // Whoops, we are being started back up.  Abort, abort!
16265                                return;
16266                            }
16267                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16268                        }
16269                        broadcastIntentLocked(null, null, shutdownIntent,
16270                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16271                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16272                    }
16273                };
16274                // Kick things off.
16275                broadcastIntentLocked(null, null, stoppingIntent,
16276                        null, stoppingReceiver, 0, null, null,
16277                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16278                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16279            } finally {
16280                Binder.restoreCallingIdentity(ident);
16281            }
16282        }
16283
16284        return ActivityManager.USER_OP_SUCCESS;
16285    }
16286
16287    void finishUserStop(UserStartedState uss) {
16288        final int userId = uss.mHandle.getIdentifier();
16289        boolean stopped;
16290        ArrayList<IStopUserCallback> callbacks;
16291        synchronized (this) {
16292            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16293            if (mStartedUsers.get(userId) != uss) {
16294                stopped = false;
16295            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16296                stopped = false;
16297            } else {
16298                stopped = true;
16299                // User can no longer run.
16300                mStartedUsers.remove(userId);
16301                mUserLru.remove(Integer.valueOf(userId));
16302                updateStartedUserArrayLocked();
16303
16304                // Clean up all state and processes associated with the user.
16305                // Kill all the processes for the user.
16306                forceStopUserLocked(userId, "finish user");
16307            }
16308        }
16309
16310        for (int i=0; i<callbacks.size(); i++) {
16311            try {
16312                if (stopped) callbacks.get(i).userStopped(userId);
16313                else callbacks.get(i).userStopAborted(userId);
16314            } catch (RemoteException e) {
16315            }
16316        }
16317
16318        mStackSupervisor.removeUserLocked(userId);
16319    }
16320
16321    @Override
16322    public UserInfo getCurrentUser() {
16323        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16324                != PackageManager.PERMISSION_GRANTED) && (
16325                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16326                != PackageManager.PERMISSION_GRANTED)) {
16327            String msg = "Permission Denial: getCurrentUser() from pid="
16328                    + Binder.getCallingPid()
16329                    + ", uid=" + Binder.getCallingUid()
16330                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16331            Slog.w(TAG, msg);
16332            throw new SecurityException(msg);
16333        }
16334        synchronized (this) {
16335            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16336        }
16337    }
16338
16339    int getCurrentUserIdLocked() {
16340        return mCurrentUserId;
16341    }
16342
16343    @Override
16344    public boolean isUserRunning(int userId, boolean orStopped) {
16345        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16346                != PackageManager.PERMISSION_GRANTED) {
16347            String msg = "Permission Denial: isUserRunning() from pid="
16348                    + Binder.getCallingPid()
16349                    + ", uid=" + Binder.getCallingUid()
16350                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16351            Slog.w(TAG, msg);
16352            throw new SecurityException(msg);
16353        }
16354        synchronized (this) {
16355            return isUserRunningLocked(userId, orStopped);
16356        }
16357    }
16358
16359    boolean isUserRunningLocked(int userId, boolean orStopped) {
16360        UserStartedState state = mStartedUsers.get(userId);
16361        if (state == null) {
16362            return false;
16363        }
16364        if (orStopped) {
16365            return true;
16366        }
16367        return state.mState != UserStartedState.STATE_STOPPING
16368                && state.mState != UserStartedState.STATE_SHUTDOWN;
16369    }
16370
16371    @Override
16372    public int[] getRunningUserIds() {
16373        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16374                != PackageManager.PERMISSION_GRANTED) {
16375            String msg = "Permission Denial: isUserRunning() from pid="
16376                    + Binder.getCallingPid()
16377                    + ", uid=" + Binder.getCallingUid()
16378                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16379            Slog.w(TAG, msg);
16380            throw new SecurityException(msg);
16381        }
16382        synchronized (this) {
16383            return mStartedUserArray;
16384        }
16385    }
16386
16387    private void updateStartedUserArrayLocked() {
16388        int num = 0;
16389        for (int i=0; i<mStartedUsers.size();  i++) {
16390            UserStartedState uss = mStartedUsers.valueAt(i);
16391            // This list does not include stopping users.
16392            if (uss.mState != UserStartedState.STATE_STOPPING
16393                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16394                num++;
16395            }
16396        }
16397        mStartedUserArray = new int[num];
16398        num = 0;
16399        for (int i=0; i<mStartedUsers.size();  i++) {
16400            UserStartedState uss = mStartedUsers.valueAt(i);
16401            if (uss.mState != UserStartedState.STATE_STOPPING
16402                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16403                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16404                num++;
16405            }
16406        }
16407    }
16408
16409    @Override
16410    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16411        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16412                != PackageManager.PERMISSION_GRANTED) {
16413            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16414                    + Binder.getCallingPid()
16415                    + ", uid=" + Binder.getCallingUid()
16416                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16417            Slog.w(TAG, msg);
16418            throw new SecurityException(msg);
16419        }
16420
16421        mUserSwitchObservers.register(observer);
16422    }
16423
16424    @Override
16425    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16426        mUserSwitchObservers.unregister(observer);
16427    }
16428
16429    private boolean userExists(int userId) {
16430        if (userId == 0) {
16431            return true;
16432        }
16433        UserManagerService ums = getUserManagerLocked();
16434        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16435    }
16436
16437    int[] getUsersLocked() {
16438        UserManagerService ums = getUserManagerLocked();
16439        return ums != null ? ums.getUserIds() : new int[] { 0 };
16440    }
16441
16442    UserManagerService getUserManagerLocked() {
16443        if (mUserManager == null) {
16444            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16445            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16446        }
16447        return mUserManager;
16448    }
16449
16450    private int applyUserId(int uid, int userId) {
16451        return UserHandle.getUid(userId, uid);
16452    }
16453
16454    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16455        if (info == null) return null;
16456        ApplicationInfo newInfo = new ApplicationInfo(info);
16457        newInfo.uid = applyUserId(info.uid, userId);
16458        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16459                + info.packageName;
16460        return newInfo;
16461    }
16462
16463    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16464        if (aInfo == null
16465                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16466            return aInfo;
16467        }
16468
16469        ActivityInfo info = new ActivityInfo(aInfo);
16470        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16471        return info;
16472    }
16473
16474    private final class LocalService extends ActivityManagerInternal {
16475        @Override
16476        public void goingToSleep() {
16477            ActivityManagerService.this.goingToSleep();
16478        }
16479
16480        @Override
16481        public void wakingUp() {
16482            ActivityManagerService.this.wakingUp();
16483        }
16484    }
16485}
16486