ActivityManagerService.java revision 385124d8cee38dee00d4fac31e8fbe46fb30565b
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.readBooleanAttribute;
21import static com.android.internal.util.XmlUtils.readIntAttribute;
22import static com.android.internal.util.XmlUtils.readLongAttribute;
23import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
24import static com.android.internal.util.XmlUtils.writeIntAttribute;
25import static com.android.internal.util.XmlUtils.writeLongAttribute;
26import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
27import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
28import static org.xmlpull.v1.XmlPullParser.START_TAG;
29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
30
31import android.app.AppOpsManager;
32import android.app.IActivityContainer;
33import android.app.IActivityContainerCallback;
34import android.appwidget.AppWidgetManager;
35import android.graphics.Rect;
36import android.os.BatteryStats;
37import android.util.ArrayMap;
38
39import com.android.internal.R;
40import com.android.internal.annotations.GuardedBy;
41import com.android.internal.app.IAppOpsService;
42import com.android.internal.app.ProcessMap;
43import com.android.internal.app.ProcessStats;
44import com.android.internal.os.BackgroundThread;
45import com.android.internal.os.BatteryStatsImpl;
46import com.android.internal.os.ProcessCpuTracker;
47import com.android.internal.os.TransferPipe;
48import com.android.internal.os.Zygote;
49import com.android.internal.util.FastPrintWriter;
50import com.android.internal.util.FastXmlSerializer;
51import com.android.internal.util.MemInfoReader;
52import com.android.internal.util.Preconditions;
53import com.android.server.AppOpsService;
54import com.android.server.AttributeCache;
55import com.android.server.IntentResolver;
56import com.android.server.LocalServices;
57import com.android.server.ServiceThread;
58import com.android.server.SystemService;
59import com.android.server.Watchdog;
60import com.android.server.am.ActivityStack.ActivityState;
61import com.android.server.firewall.IntentFirewall;
62import com.android.server.pm.UserManagerService;
63import com.android.server.wm.AppTransition;
64import com.android.server.wm.WindowManagerService;
65import com.google.android.collect.Lists;
66import com.google.android.collect.Maps;
67
68import libcore.io.IoUtils;
69
70import org.xmlpull.v1.XmlPullParser;
71import org.xmlpull.v1.XmlPullParserException;
72import org.xmlpull.v1.XmlSerializer;
73
74import android.app.Activity;
75import android.app.ActivityManager;
76import android.app.ActivityManager.RunningTaskInfo;
77import android.app.ActivityManager.StackInfo;
78import android.app.ActivityManagerInternal;
79import android.app.ActivityManagerNative;
80import android.app.ActivityOptions;
81import android.app.ActivityThread;
82import android.app.AlertDialog;
83import android.app.AppGlobals;
84import android.app.ApplicationErrorReport;
85import android.app.Dialog;
86import android.app.IActivityController;
87import android.app.IApplicationThread;
88import android.app.IInstrumentationWatcher;
89import android.app.INotificationManager;
90import android.app.IProcessObserver;
91import android.app.IServiceConnection;
92import android.app.IStopUserCallback;
93import android.app.IThumbnailReceiver;
94import android.app.IUiAutomationConnection;
95import android.app.IUserSwitchObserver;
96import android.app.Instrumentation;
97import android.app.Notification;
98import android.app.NotificationManager;
99import android.app.PendingIntent;
100import android.app.backup.IBackupManager;
101import android.content.ActivityNotFoundException;
102import android.content.BroadcastReceiver;
103import android.content.ClipData;
104import android.content.ComponentCallbacks2;
105import android.content.ComponentName;
106import android.content.ContentProvider;
107import android.content.ContentResolver;
108import android.content.Context;
109import android.content.DialogInterface;
110import android.content.IContentProvider;
111import android.content.IIntentReceiver;
112import android.content.IIntentSender;
113import android.content.Intent;
114import android.content.IntentFilter;
115import android.content.IntentSender;
116import android.content.pm.ActivityInfo;
117import android.content.pm.ApplicationInfo;
118import android.content.pm.ConfigurationInfo;
119import android.content.pm.IPackageDataObserver;
120import android.content.pm.IPackageManager;
121import android.content.pm.InstrumentationInfo;
122import android.content.pm.PackageInfo;
123import android.content.pm.PackageManager;
124import android.content.pm.ParceledListSlice;
125import android.content.pm.UserInfo;
126import android.content.pm.PackageManager.NameNotFoundException;
127import android.content.pm.PathPermission;
128import android.content.pm.ProviderInfo;
129import android.content.pm.ResolveInfo;
130import android.content.pm.ServiceInfo;
131import android.content.res.CompatibilityInfo;
132import android.content.res.Configuration;
133import android.graphics.Bitmap;
134import android.net.Proxy;
135import android.net.ProxyProperties;
136import android.net.Uri;
137import android.os.Binder;
138import android.os.Build;
139import android.os.Bundle;
140import android.os.Debug;
141import android.os.DropBoxManager;
142import android.os.Environment;
143import android.os.FactoryTest;
144import android.os.FileObserver;
145import android.os.FileUtils;
146import android.os.Handler;
147import android.os.IBinder;
148import android.os.IPermissionController;
149import android.os.IRemoteCallback;
150import android.os.IUserManager;
151import android.os.Looper;
152import android.os.Message;
153import android.os.Parcel;
154import android.os.ParcelFileDescriptor;
155import android.os.Process;
156import android.os.RemoteCallbackList;
157import android.os.RemoteException;
158import android.os.SELinux;
159import android.os.ServiceManager;
160import android.os.StrictMode;
161import android.os.SystemClock;
162import android.os.SystemProperties;
163import android.os.UpdateLock;
164import android.os.UserHandle;
165import android.provider.Settings;
166import android.text.format.DateUtils;
167import android.text.format.Time;
168import android.util.AtomicFile;
169import android.util.EventLog;
170import android.util.Log;
171import android.util.Pair;
172import android.util.PrintWriterPrinter;
173import android.util.Slog;
174import android.util.SparseArray;
175import android.util.TimeUtils;
176import android.util.Xml;
177import android.view.Gravity;
178import android.view.LayoutInflater;
179import android.view.View;
180import android.view.WindowManager;
181
182import java.io.BufferedInputStream;
183import java.io.BufferedOutputStream;
184import java.io.DataInputStream;
185import java.io.DataOutputStream;
186import java.io.File;
187import java.io.FileDescriptor;
188import java.io.FileInputStream;
189import java.io.FileNotFoundException;
190import java.io.FileOutputStream;
191import java.io.IOException;
192import java.io.InputStreamReader;
193import java.io.PrintWriter;
194import java.io.StringWriter;
195import java.lang.ref.WeakReference;
196import java.util.ArrayList;
197import java.util.Arrays;
198import java.util.Collections;
199import java.util.Comparator;
200import java.util.HashMap;
201import java.util.HashSet;
202import java.util.Iterator;
203import java.util.List;
204import java.util.Locale;
205import java.util.Map;
206import java.util.Set;
207import java.util.concurrent.atomic.AtomicBoolean;
208import java.util.concurrent.atomic.AtomicLong;
209
210public final class ActivityManagerService extends ActivityManagerNative
211        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
212    private static final String USER_DATA_DIR = "/data/user/";
213    static final String TAG = "ActivityManager";
214    static final String TAG_MU = "ActivityManagerServiceMU";
215    static final boolean DEBUG = false;
216    static final boolean localLOGV = DEBUG;
217    static final boolean DEBUG_BACKUP = localLOGV || false;
218    static final boolean DEBUG_BROADCAST = localLOGV || false;
219    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
220    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
221    static final boolean DEBUG_CLEANUP = localLOGV || false;
222    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
223    static final boolean DEBUG_FOCUS = false;
224    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
225    static final boolean DEBUG_MU = localLOGV || false;
226    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
227    static final boolean DEBUG_LRU = localLOGV || false;
228    static final boolean DEBUG_PAUSE = localLOGV || false;
229    static final boolean DEBUG_POWER = localLOGV || false;
230    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
231    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
232    static final boolean DEBUG_PROCESSES = localLOGV || false;
233    static final boolean DEBUG_PROVIDER = localLOGV || false;
234    static final boolean DEBUG_RESULTS = localLOGV || false;
235    static final boolean DEBUG_SERVICE = localLOGV || false;
236    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
237    static final boolean DEBUG_STACK = localLOGV || false;
238    static final boolean DEBUG_SWITCH = localLOGV || false;
239    static final boolean DEBUG_TASKS = localLOGV || false;
240    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
241    static final boolean DEBUG_TRANSITION = localLOGV || false;
242    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
243    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
244    static final boolean DEBUG_VISBILITY = localLOGV || false;
245    static final boolean DEBUG_PSS = localLOGV || false;
246    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
247    static final boolean VALIDATE_TOKENS = false;
248    static final boolean SHOW_ACTIVITY_START_TIME = true;
249
250    // Control over CPU and battery monitoring.
251    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
252    static final boolean MONITOR_CPU_USAGE = true;
253    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
254    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
255    static final boolean MONITOR_THREAD_CPU_USAGE = false;
256
257    // The flags that are set for all calls we make to the package manager.
258    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
259
260    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
261
262    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
263
264    // Maximum number of recent tasks that we can remember.
265    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
266
267    // Amount of time after a call to stopAppSwitches() during which we will
268    // prevent further untrusted switches from happening.
269    static final long APP_SWITCH_DELAY_TIME = 5*1000;
270
271    // How long we wait for a launched process to attach to the activity manager
272    // before we decide it's never going to come up for real.
273    static final int PROC_START_TIMEOUT = 10*1000;
274
275    // How long we wait for a launched process to attach to the activity manager
276    // before we decide it's never going to come up for real, when the process was
277    // started with a wrapper for instrumentation (such as Valgrind) because it
278    // could take much longer than usual.
279    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
280
281    // How long to wait after going idle before forcing apps to GC.
282    static final int GC_TIMEOUT = 5*1000;
283
284    // The minimum amount of time between successive GC requests for a process.
285    static final int GC_MIN_INTERVAL = 60*1000;
286
287    // The minimum amount of time between successive PSS requests for a process.
288    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
289
290    // The minimum amount of time between successive PSS requests for a process
291    // when the request is due to the memory state being lowered.
292    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
293
294    // The rate at which we check for apps using excessive power -- 15 mins.
295    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
296
297    // The minimum sample duration we will allow before deciding we have
298    // enough data on wake locks to start killing things.
299    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
300
301    // The minimum sample duration we will allow before deciding we have
302    // enough data on CPU usage to start killing things.
303    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
304
305    // How long we allow a receiver to run before giving up on it.
306    static final int BROADCAST_FG_TIMEOUT = 10*1000;
307    static final int BROADCAST_BG_TIMEOUT = 60*1000;
308
309    // How long we wait until we timeout on key dispatching.
310    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
311
312    // How long we wait until we timeout on key dispatching during instrumentation.
313    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
314
315    // Amount of time we wait for observers to handle a user switch before
316    // giving up on them and unfreezing the screen.
317    static final int USER_SWITCH_TIMEOUT = 2*1000;
318
319    // Maximum number of users we allow to be running at a time.
320    static final int MAX_RUNNING_USERS = 3;
321
322    // How long to wait in getAssistContextExtras for the activity and foreground services
323    // to respond with the result.
324    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
325
326    // Maximum number of persisted Uri grants a package is allowed
327    static final int MAX_PERSISTED_URI_GRANTS = 128;
328
329    static final int MY_PID = Process.myPid();
330
331    static final String[] EMPTY_STRING_ARRAY = new String[0];
332
333    // How many bytes to write into the dropbox log before truncating
334    static final int DROPBOX_MAX_SIZE = 256 * 1024;
335
336    /** Run all ActivityStacks through this */
337    ActivityStackSupervisor mStackSupervisor;
338
339    public IntentFirewall mIntentFirewall;
340
341    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
342    // default actuion automatically.  Important for devices without direct input
343    // devices.
344    private boolean mShowDialogs = true;
345
346    /**
347     * Description of a request to start a new activity, which has been held
348     * due to app switches being disabled.
349     */
350    static class PendingActivityLaunch {
351        final ActivityRecord r;
352        final ActivityRecord sourceRecord;
353        final int startFlags;
354        final ActivityStack stack;
355
356        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
357                int _startFlags, ActivityStack _stack) {
358            r = _r;
359            sourceRecord = _sourceRecord;
360            startFlags = _startFlags;
361            stack = _stack;
362        }
363    }
364
365    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
366            = new ArrayList<PendingActivityLaunch>();
367
368    BroadcastQueue mFgBroadcastQueue;
369    BroadcastQueue mBgBroadcastQueue;
370    // Convenient for easy iteration over the queues. Foreground is first
371    // so that dispatch of foreground broadcasts gets precedence.
372    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
373
374    BroadcastQueue broadcastQueueForIntent(Intent intent) {
375        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
376        if (DEBUG_BACKGROUND_BROADCAST) {
377            Slog.i(TAG, "Broadcast intent " + intent + " on "
378                    + (isFg ? "foreground" : "background")
379                    + " queue");
380        }
381        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
382    }
383
384    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
385        for (BroadcastQueue queue : mBroadcastQueues) {
386            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
387            if (r != null) {
388                return r;
389            }
390        }
391        return null;
392    }
393
394    /**
395     * Activity we have told the window manager to have key focus.
396     */
397    ActivityRecord mFocusedActivity = null;
398
399    /**
400     * List of intents that were used to start the most recent tasks.
401     */
402    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
403
404    public class PendingAssistExtras extends Binder implements Runnable {
405        public final ActivityRecord activity;
406        public boolean haveResult = false;
407        public Bundle result = null;
408        public PendingAssistExtras(ActivityRecord _activity) {
409            activity = _activity;
410        }
411        @Override
412        public void run() {
413            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
414            synchronized (this) {
415                haveResult = true;
416                notifyAll();
417            }
418        }
419    }
420
421    final ArrayList<PendingAssistExtras> mPendingAssistExtras
422            = new ArrayList<PendingAssistExtras>();
423
424    /**
425     * Process management.
426     */
427    final ProcessList mProcessList = new ProcessList();
428
429    /**
430     * All of the applications we currently have running organized by name.
431     * The keys are strings of the application package name (as
432     * returned by the package manager), and the keys are ApplicationRecord
433     * objects.
434     */
435    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
436
437    /**
438     * Tracking long-term execution of processes to look for abuse and other
439     * bad app behavior.
440     */
441    final ProcessStatsService mProcessStats;
442
443    /**
444     * The currently running isolated processes.
445     */
446    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
447
448    /**
449     * Counter for assigning isolated process uids, to avoid frequently reusing the
450     * same ones.
451     */
452    int mNextIsolatedProcessUid = 0;
453
454    /**
455     * The currently running heavy-weight process, if any.
456     */
457    ProcessRecord mHeavyWeightProcess = null;
458
459    /**
460     * The last time that various processes have crashed.
461     */
462    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
463
464    /**
465     * Information about a process that is currently marked as bad.
466     */
467    static final class BadProcessInfo {
468        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
469            this.time = time;
470            this.shortMsg = shortMsg;
471            this.longMsg = longMsg;
472            this.stack = stack;
473        }
474
475        final long time;
476        final String shortMsg;
477        final String longMsg;
478        final String stack;
479    }
480
481    /**
482     * Set of applications that we consider to be bad, and will reject
483     * incoming broadcasts from (which the user has no control over).
484     * Processes are added to this set when they have crashed twice within
485     * a minimum amount of time; they are removed from it when they are
486     * later restarted (hopefully due to some user action).  The value is the
487     * time it was added to the list.
488     */
489    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
490
491    /**
492     * All of the processes we currently have running organized by pid.
493     * The keys are the pid running the application.
494     *
495     * <p>NOTE: This object is protected by its own lock, NOT the global
496     * activity manager lock!
497     */
498    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
499
500    /**
501     * All of the processes that have been forced to be foreground.  The key
502     * is the pid of the caller who requested it (we hold a death
503     * link on it).
504     */
505    abstract class ForegroundToken implements IBinder.DeathRecipient {
506        int pid;
507        IBinder token;
508    }
509    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
510
511    /**
512     * List of records for processes that someone had tried to start before the
513     * system was ready.  We don't start them at that point, but ensure they
514     * are started by the time booting is complete.
515     */
516    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
517
518    /**
519     * List of persistent applications that are in the process
520     * of being started.
521     */
522    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
523
524    /**
525     * Processes that are being forcibly torn down.
526     */
527    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
528
529    /**
530     * List of running applications, sorted by recent usage.
531     * The first entry in the list is the least recently used.
532     */
533    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
534
535    /**
536     * Where in mLruProcesses that the processes hosting activities start.
537     */
538    int mLruProcessActivityStart = 0;
539
540    /**
541     * Where in mLruProcesses that the processes hosting services start.
542     * This is after (lower index) than mLruProcessesActivityStart.
543     */
544    int mLruProcessServiceStart = 0;
545
546    /**
547     * List of processes that should gc as soon as things are idle.
548     */
549    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
550
551    /**
552     * Processes we want to collect PSS data from.
553     */
554    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
555
556    /**
557     * Last time we requested PSS data of all processes.
558     */
559    long mLastFullPssTime = SystemClock.uptimeMillis();
560
561    /**
562     * This is the process holding what we currently consider to be
563     * the "home" activity.
564     */
565    ProcessRecord mHomeProcess;
566
567    /**
568     * This is the process holding the activity the user last visited that
569     * is in a different process from the one they are currently in.
570     */
571    ProcessRecord mPreviousProcess;
572
573    /**
574     * The time at which the previous process was last visible.
575     */
576    long mPreviousProcessVisibleTime;
577
578    /**
579     * Which uses have been started, so are allowed to run code.
580     */
581    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
582
583    /**
584     * LRU list of history of current users.  Most recently current is at the end.
585     */
586    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
587
588    /**
589     * Constant array of the users that are currently started.
590     */
591    int[] mStartedUserArray = new int[] { 0 };
592
593    /**
594     * Registered observers of the user switching mechanics.
595     */
596    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
597            = new RemoteCallbackList<IUserSwitchObserver>();
598
599    /**
600     * Currently active user switch.
601     */
602    Object mCurUserSwitchCallback;
603
604    /**
605     * Packages that the user has asked to have run in screen size
606     * compatibility mode instead of filling the screen.
607     */
608    final CompatModePackages mCompatModePackages;
609
610    /**
611     * Set of IntentSenderRecord objects that are currently active.
612     */
613    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
614            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
615
616    /**
617     * Fingerprints (hashCode()) of stack traces that we've
618     * already logged DropBox entries for.  Guarded by itself.  If
619     * something (rogue user app) forces this over
620     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
621     */
622    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
623    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
624
625    /**
626     * Strict Mode background batched logging state.
627     *
628     * The string buffer is guarded by itself, and its lock is also
629     * used to determine if another batched write is already
630     * in-flight.
631     */
632    private final StringBuilder mStrictModeBuffer = new StringBuilder();
633
634    /**
635     * Keeps track of all IIntentReceivers that have been registered for
636     * broadcasts.  Hash keys are the receiver IBinder, hash value is
637     * a ReceiverList.
638     */
639    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
640            new HashMap<IBinder, ReceiverList>();
641
642    /**
643     * Resolver for broadcast intents to registered receivers.
644     * Holds BroadcastFilter (subclass of IntentFilter).
645     */
646    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
647            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
648        @Override
649        protected boolean allowFilterResult(
650                BroadcastFilter filter, List<BroadcastFilter> dest) {
651            IBinder target = filter.receiverList.receiver.asBinder();
652            for (int i=dest.size()-1; i>=0; i--) {
653                if (dest.get(i).receiverList.receiver.asBinder() == target) {
654                    return false;
655                }
656            }
657            return true;
658        }
659
660        @Override
661        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
662            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
663                    || userId == filter.owningUserId) {
664                return super.newResult(filter, match, userId);
665            }
666            return null;
667        }
668
669        @Override
670        protected BroadcastFilter[] newArray(int size) {
671            return new BroadcastFilter[size];
672        }
673
674        @Override
675        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
676            return packageName.equals(filter.packageName);
677        }
678    };
679
680    /**
681     * State of all active sticky broadcasts per user.  Keys are the action of the
682     * sticky Intent, values are an ArrayList of all broadcasted intents with
683     * that action (which should usually be one).  The SparseArray is keyed
684     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
685     * for stickies that are sent to all users.
686     */
687    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
688            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
689
690    final ActiveServices mServices;
691
692    /**
693     * Backup/restore process management
694     */
695    String mBackupAppName = null;
696    BackupRecord mBackupTarget = null;
697
698    /**
699     * List of PendingThumbnailsRecord objects of clients who are still
700     * waiting to receive all of the thumbnails for a task.
701     */
702    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
703            new ArrayList<PendingThumbnailsRecord>();
704
705    final ProviderMap mProviderMap;
706
707    /**
708     * List of content providers who have clients waiting for them.  The
709     * application is currently being launched and the provider will be
710     * removed from this list once it is published.
711     */
712    final ArrayList<ContentProviderRecord> mLaunchingProviders
713            = new ArrayList<ContentProviderRecord>();
714
715    /**
716     * File storing persisted {@link #mGrantedUriPermissions}.
717     */
718    private final AtomicFile mGrantFile;
719
720    /** XML constants used in {@link #mGrantFile} */
721    private static final String TAG_URI_GRANTS = "uri-grants";
722    private static final String TAG_URI_GRANT = "uri-grant";
723    private static final String ATTR_USER_HANDLE = "userHandle";
724    private static final String ATTR_SOURCE_PKG = "sourcePkg";
725    private static final String ATTR_TARGET_PKG = "targetPkg";
726    private static final String ATTR_URI = "uri";
727    private static final String ATTR_MODE_FLAGS = "modeFlags";
728    private static final String ATTR_CREATED_TIME = "createdTime";
729    private static final String ATTR_PREFIX = "prefix";
730
731    /**
732     * Global set of specific {@link Uri} permissions that have been granted.
733     * This optimized lookup structure maps from {@link UriPermission#targetUid}
734     * to {@link UriPermission#uri} to {@link UriPermission}.
735     */
736    @GuardedBy("this")
737    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
738            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
739
740    public static class GrantUri {
741        public final Uri uri;
742        public final boolean prefix;
743
744        public GrantUri(Uri uri, boolean prefix) {
745            this.uri = uri;
746            this.prefix = prefix;
747        }
748
749        @Override
750        public int hashCode() {
751            return toString().hashCode();
752        }
753
754        @Override
755        public boolean equals(Object o) {
756            if (o instanceof GrantUri) {
757                GrantUri other = (GrantUri) o;
758                return uri.equals(other.uri) && prefix == other.prefix;
759            }
760            return false;
761        }
762
763        @Override
764        public String toString() {
765            if (prefix) {
766                return uri.toString() + " [prefix]";
767            } else {
768                return uri.toString();
769            }
770        }
771    }
772
773    CoreSettingsObserver mCoreSettingsObserver;
774
775    /**
776     * Thread-local storage used to carry caller permissions over through
777     * indirect content-provider access.
778     */
779    private class Identity {
780        public int pid;
781        public int uid;
782
783        Identity(int _pid, int _uid) {
784            pid = _pid;
785            uid = _uid;
786        }
787    }
788
789    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
790
791    /**
792     * All information we have collected about the runtime performance of
793     * any user id that can impact battery performance.
794     */
795    final BatteryStatsService mBatteryStatsService;
796
797    /**
798     * Information about component usage
799     */
800    final UsageStatsService mUsageStatsService;
801
802    /**
803     * Information about and control over application operations
804     */
805    final AppOpsService mAppOpsService;
806
807    /**
808     * Current configuration information.  HistoryRecord objects are given
809     * a reference to this object to indicate which configuration they are
810     * currently running in, so this object must be kept immutable.
811     */
812    Configuration mConfiguration = new Configuration();
813
814    /**
815     * Current sequencing integer of the configuration, for skipping old
816     * configurations.
817     */
818    int mConfigurationSeq = 0;
819
820    /**
821     * Hardware-reported OpenGLES version.
822     */
823    final int GL_ES_VERSION;
824
825    /**
826     * List of initialization arguments to pass to all processes when binding applications to them.
827     * For example, references to the commonly used services.
828     */
829    HashMap<String, IBinder> mAppBindArgs;
830
831    /**
832     * Temporary to avoid allocations.  Protected by main lock.
833     */
834    final StringBuilder mStringBuilder = new StringBuilder(256);
835
836    /**
837     * Used to control how we initialize the service.
838     */
839    ComponentName mTopComponent;
840    String mTopAction = Intent.ACTION_MAIN;
841    String mTopData;
842    boolean mProcessesReady = false;
843    boolean mSystemReady = false;
844    boolean mBooting = false;
845    boolean mWaitingUpdate = false;
846    boolean mDidUpdate = false;
847    boolean mOnBattery = false;
848    boolean mLaunchWarningShown = false;
849
850    Context mContext;
851
852    int mFactoryTest;
853
854    boolean mCheckedForSetup;
855
856    /**
857     * The time at which we will allow normal application switches again,
858     * after a call to {@link #stopAppSwitches()}.
859     */
860    long mAppSwitchesAllowedTime;
861
862    /**
863     * This is set to true after the first switch after mAppSwitchesAllowedTime
864     * is set; any switches after that will clear the time.
865     */
866    boolean mDidAppSwitch;
867
868    /**
869     * Last time (in realtime) at which we checked for power usage.
870     */
871    long mLastPowerCheckRealtime;
872
873    /**
874     * Last time (in uptime) at which we checked for power usage.
875     */
876    long mLastPowerCheckUptime;
877
878    /**
879     * Set while we are wanting to sleep, to prevent any
880     * activities from being started/resumed.
881     */
882    boolean mSleeping = false;
883
884    /**
885     * State of external calls telling us if the device is asleep.
886     */
887    boolean mWentToSleep = false;
888
889    /**
890     * State of external call telling us if the lock screen is shown.
891     */
892    boolean mLockScreenShown = false;
893
894    /**
895     * Set if we are shutting down the system, similar to sleeping.
896     */
897    boolean mShuttingDown = false;
898
899    /**
900     * Current sequence id for oom_adj computation traversal.
901     */
902    int mAdjSeq = 0;
903
904    /**
905     * Current sequence id for process LRU updating.
906     */
907    int mLruSeq = 0;
908
909    /**
910     * Keep track of the non-cached/empty process we last found, to help
911     * determine how to distribute cached/empty processes next time.
912     */
913    int mNumNonCachedProcs = 0;
914
915    /**
916     * Keep track of the number of cached hidden procs, to balance oom adj
917     * distribution between those and empty procs.
918     */
919    int mNumCachedHiddenProcs = 0;
920
921    /**
922     * Keep track of the number of service processes we last found, to
923     * determine on the next iteration which should be B services.
924     */
925    int mNumServiceProcs = 0;
926    int mNewNumAServiceProcs = 0;
927    int mNewNumServiceProcs = 0;
928
929    /**
930     * Allow the current computed overall memory level of the system to go down?
931     * This is set to false when we are killing processes for reasons other than
932     * memory management, so that the now smaller process list will not be taken as
933     * an indication that memory is tighter.
934     */
935    boolean mAllowLowerMemLevel = false;
936
937    /**
938     * The last computed memory level, for holding when we are in a state that
939     * processes are going away for other reasons.
940     */
941    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
942
943    /**
944     * The last total number of process we have, to determine if changes actually look
945     * like a shrinking number of process due to lower RAM.
946     */
947    int mLastNumProcesses;
948
949    /**
950     * The uptime of the last time we performed idle maintenance.
951     */
952    long mLastIdleTime = SystemClock.uptimeMillis();
953
954    /**
955     * Total time spent with RAM that has been added in the past since the last idle time.
956     */
957    long mLowRamTimeSinceLastIdle = 0;
958
959    /**
960     * If RAM is currently low, when that horrible situation started.
961     */
962    long mLowRamStartTime = 0;
963
964    /**
965     * For reporting to battery stats the current top application.
966     */
967    private String mCurResumedPackage = null;
968    private int mCurResumedUid = -1;
969
970    /**
971     * For reporting to battery stats the apps currently running foreground
972     * service.  The ProcessMap is package/uid tuples; each of these contain
973     * an array of the currently foreground processes.
974     */
975    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
976            = new ProcessMap<ArrayList<ProcessRecord>>();
977
978    /**
979     * This is set if we had to do a delayed dexopt of an app before launching
980     * it, to increasing the ANR timeouts in that case.
981     */
982    boolean mDidDexOpt;
983
984    /**
985     * Set if the systemServer made a call to enterSafeMode.
986     */
987    boolean mSafeMode;
988
989    String mDebugApp = null;
990    boolean mWaitForDebugger = false;
991    boolean mDebugTransient = false;
992    String mOrigDebugApp = null;
993    boolean mOrigWaitForDebugger = false;
994    boolean mAlwaysFinishActivities = false;
995    IActivityController mController = null;
996    String mProfileApp = null;
997    ProcessRecord mProfileProc = null;
998    String mProfileFile;
999    ParcelFileDescriptor mProfileFd;
1000    int mProfileType = 0;
1001    boolean mAutoStopProfiler = false;
1002    String mOpenGlTraceApp = null;
1003
1004    static class ProcessChangeItem {
1005        static final int CHANGE_ACTIVITIES = 1<<0;
1006        static final int CHANGE_IMPORTANCE= 1<<1;
1007        int changes;
1008        int uid;
1009        int pid;
1010        int importance;
1011        boolean foregroundActivities;
1012    }
1013
1014    final RemoteCallbackList<IProcessObserver> mProcessObservers
1015            = new RemoteCallbackList<IProcessObserver>();
1016    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1017
1018    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1019            = new ArrayList<ProcessChangeItem>();
1020    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1021            = new ArrayList<ProcessChangeItem>();
1022
1023    /**
1024     * Runtime CPU use collection thread.  This object's lock is used to
1025     * protect all related state.
1026     */
1027    final Thread mProcessCpuThread;
1028
1029    /**
1030     * Used to collect process stats when showing not responding dialog.
1031     * Protected by mProcessCpuThread.
1032     */
1033    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1034            MONITOR_THREAD_CPU_USAGE);
1035    final AtomicLong mLastCpuTime = new AtomicLong(0);
1036    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1037
1038    long mLastWriteTime = 0;
1039
1040    /**
1041     * Used to retain an update lock when the foreground activity is in
1042     * immersive mode.
1043     */
1044    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1045
1046    /**
1047     * Set to true after the system has finished booting.
1048     */
1049    boolean mBooted = false;
1050
1051    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1052    int mProcessLimitOverride = -1;
1053
1054    WindowManagerService mWindowManager;
1055
1056    final ActivityThread mSystemThread;
1057
1058    int mCurrentUserId = 0;
1059    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1060    private UserManagerService mUserManager;
1061
1062    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1063        final ProcessRecord mApp;
1064        final int mPid;
1065        final IApplicationThread mAppThread;
1066
1067        AppDeathRecipient(ProcessRecord app, int pid,
1068                IApplicationThread thread) {
1069            if (localLOGV) Slog.v(
1070                TAG, "New death recipient " + this
1071                + " for thread " + thread.asBinder());
1072            mApp = app;
1073            mPid = pid;
1074            mAppThread = thread;
1075        }
1076
1077        @Override
1078        public void binderDied() {
1079            if (localLOGV) Slog.v(
1080                TAG, "Death received in " + this
1081                + " for thread " + mAppThread.asBinder());
1082            synchronized(ActivityManagerService.this) {
1083                appDiedLocked(mApp, mPid, mAppThread);
1084            }
1085        }
1086    }
1087
1088    static final int SHOW_ERROR_MSG = 1;
1089    static final int SHOW_NOT_RESPONDING_MSG = 2;
1090    static final int SHOW_FACTORY_ERROR_MSG = 3;
1091    static final int UPDATE_CONFIGURATION_MSG = 4;
1092    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1093    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1094    static final int SERVICE_TIMEOUT_MSG = 12;
1095    static final int UPDATE_TIME_ZONE = 13;
1096    static final int SHOW_UID_ERROR_MSG = 14;
1097    static final int IM_FEELING_LUCKY_MSG = 15;
1098    static final int PROC_START_TIMEOUT_MSG = 20;
1099    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1100    static final int KILL_APPLICATION_MSG = 22;
1101    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1102    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1103    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1104    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1105    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1106    static final int CLEAR_DNS_CACHE_MSG = 28;
1107    static final int UPDATE_HTTP_PROXY_MSG = 29;
1108    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1109    static final int DISPATCH_PROCESSES_CHANGED = 31;
1110    static final int DISPATCH_PROCESS_DIED = 32;
1111    static final int REPORT_MEM_USAGE_MSG = 33;
1112    static final int REPORT_USER_SWITCH_MSG = 34;
1113    static final int CONTINUE_USER_SWITCH_MSG = 35;
1114    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1115    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1116    static final int PERSIST_URI_GRANTS_MSG = 38;
1117    static final int REQUEST_ALL_PSS_MSG = 39;
1118    static final int START_PROFILES_MSG = 40;
1119    static final int UPDATE_TIME = 41;
1120
1121    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1122    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1123    static final int FIRST_COMPAT_MODE_MSG = 300;
1124    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1125
1126    AlertDialog mUidAlert;
1127    CompatModeDialog mCompatModeDialog;
1128    long mLastMemUsageReportTime = 0;
1129
1130    /**
1131     * Flag whether the current user is a "monkey", i.e. whether
1132     * the UI is driven by a UI automation tool.
1133     */
1134    private boolean mUserIsMonkey;
1135
1136    final ServiceThread mHandlerThread;
1137    final MainHandler mHandler;
1138
1139    final class MainHandler extends Handler {
1140        public MainHandler(Looper looper) {
1141            super(looper, null, true);
1142        }
1143
1144        @Override
1145        public void handleMessage(Message msg) {
1146            switch (msg.what) {
1147            case SHOW_ERROR_MSG: {
1148                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1149                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1150                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1151                synchronized (ActivityManagerService.this) {
1152                    ProcessRecord proc = (ProcessRecord)data.get("app");
1153                    AppErrorResult res = (AppErrorResult) data.get("result");
1154                    if (proc != null && proc.crashDialog != null) {
1155                        Slog.e(TAG, "App already has crash dialog: " + proc);
1156                        if (res != null) {
1157                            res.set(0);
1158                        }
1159                        return;
1160                    }
1161                    if (!showBackground && UserHandle.getAppId(proc.uid)
1162                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1163                            && proc.pid != MY_PID) {
1164                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1165                        if (res != null) {
1166                            res.set(0);
1167                        }
1168                        return;
1169                    }
1170                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1171                        Dialog d = new AppErrorDialog(mContext,
1172                                ActivityManagerService.this, res, proc);
1173                        d.show();
1174                        proc.crashDialog = d;
1175                    } else {
1176                        // The device is asleep, so just pretend that the user
1177                        // saw a crash dialog and hit "force quit".
1178                        if (res != null) {
1179                            res.set(0);
1180                        }
1181                    }
1182                }
1183
1184                ensureBootCompleted();
1185            } break;
1186            case SHOW_NOT_RESPONDING_MSG: {
1187                synchronized (ActivityManagerService.this) {
1188                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1189                    ProcessRecord proc = (ProcessRecord)data.get("app");
1190                    if (proc != null && proc.anrDialog != null) {
1191                        Slog.e(TAG, "App already has anr dialog: " + proc);
1192                        return;
1193                    }
1194
1195                    Intent intent = new Intent("android.intent.action.ANR");
1196                    if (!mProcessesReady) {
1197                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1198                                | Intent.FLAG_RECEIVER_FOREGROUND);
1199                    }
1200                    broadcastIntentLocked(null, null, intent,
1201                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1202                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1203
1204                    if (mShowDialogs) {
1205                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1206                                mContext, proc, (ActivityRecord)data.get("activity"),
1207                                msg.arg1 != 0);
1208                        d.show();
1209                        proc.anrDialog = d;
1210                    } else {
1211                        // Just kill the app if there is no dialog to be shown.
1212                        killAppAtUsersRequest(proc, null);
1213                    }
1214                }
1215
1216                ensureBootCompleted();
1217            } break;
1218            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1219                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1220                synchronized (ActivityManagerService.this) {
1221                    ProcessRecord proc = (ProcessRecord) data.get("app");
1222                    if (proc == null) {
1223                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1224                        break;
1225                    }
1226                    if (proc.crashDialog != null) {
1227                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1228                        return;
1229                    }
1230                    AppErrorResult res = (AppErrorResult) data.get("result");
1231                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1232                        Dialog d = new StrictModeViolationDialog(mContext,
1233                                ActivityManagerService.this, res, proc);
1234                        d.show();
1235                        proc.crashDialog = d;
1236                    } else {
1237                        // The device is asleep, so just pretend that the user
1238                        // saw a crash dialog and hit "force quit".
1239                        res.set(0);
1240                    }
1241                }
1242                ensureBootCompleted();
1243            } break;
1244            case SHOW_FACTORY_ERROR_MSG: {
1245                Dialog d = new FactoryErrorDialog(
1246                    mContext, msg.getData().getCharSequence("msg"));
1247                d.show();
1248                ensureBootCompleted();
1249            } break;
1250            case UPDATE_CONFIGURATION_MSG: {
1251                final ContentResolver resolver = mContext.getContentResolver();
1252                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1253            } break;
1254            case GC_BACKGROUND_PROCESSES_MSG: {
1255                synchronized (ActivityManagerService.this) {
1256                    performAppGcsIfAppropriateLocked();
1257                }
1258            } break;
1259            case WAIT_FOR_DEBUGGER_MSG: {
1260                synchronized (ActivityManagerService.this) {
1261                    ProcessRecord app = (ProcessRecord)msg.obj;
1262                    if (msg.arg1 != 0) {
1263                        if (!app.waitedForDebugger) {
1264                            Dialog d = new AppWaitingForDebuggerDialog(
1265                                    ActivityManagerService.this,
1266                                    mContext, app);
1267                            app.waitDialog = d;
1268                            app.waitedForDebugger = true;
1269                            d.show();
1270                        }
1271                    } else {
1272                        if (app.waitDialog != null) {
1273                            app.waitDialog.dismiss();
1274                            app.waitDialog = null;
1275                        }
1276                    }
1277                }
1278            } break;
1279            case SERVICE_TIMEOUT_MSG: {
1280                if (mDidDexOpt) {
1281                    mDidDexOpt = false;
1282                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1283                    nmsg.obj = msg.obj;
1284                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1285                    return;
1286                }
1287                mServices.serviceTimeout((ProcessRecord)msg.obj);
1288            } break;
1289            case UPDATE_TIME_ZONE: {
1290                synchronized (ActivityManagerService.this) {
1291                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1292                        ProcessRecord r = mLruProcesses.get(i);
1293                        if (r.thread != null) {
1294                            try {
1295                                r.thread.updateTimeZone();
1296                            } catch (RemoteException ex) {
1297                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1298                            }
1299                        }
1300                    }
1301                }
1302            } break;
1303            case CLEAR_DNS_CACHE_MSG: {
1304                synchronized (ActivityManagerService.this) {
1305                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1306                        ProcessRecord r = mLruProcesses.get(i);
1307                        if (r.thread != null) {
1308                            try {
1309                                r.thread.clearDnsCache();
1310                            } catch (RemoteException ex) {
1311                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1312                            }
1313                        }
1314                    }
1315                }
1316            } break;
1317            case UPDATE_HTTP_PROXY_MSG: {
1318                ProxyProperties proxy = (ProxyProperties)msg.obj;
1319                String host = "";
1320                String port = "";
1321                String exclList = "";
1322                String pacFileUrl = null;
1323                if (proxy != null) {
1324                    host = proxy.getHost();
1325                    port = Integer.toString(proxy.getPort());
1326                    exclList = proxy.getExclusionList();
1327                    pacFileUrl = proxy.getPacFileUrl();
1328                }
1329                synchronized (ActivityManagerService.this) {
1330                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1331                        ProcessRecord r = mLruProcesses.get(i);
1332                        if (r.thread != null) {
1333                            try {
1334                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1335                            } catch (RemoteException ex) {
1336                                Slog.w(TAG, "Failed to update http proxy for: " +
1337                                        r.info.processName);
1338                            }
1339                        }
1340                    }
1341                }
1342            } break;
1343            case SHOW_UID_ERROR_MSG: {
1344                String title = "System UIDs Inconsistent";
1345                String text = "UIDs on the system are inconsistent, you need to wipe your"
1346                        + " data partition or your device will be unstable.";
1347                Log.e(TAG, title + ": " + text);
1348                if (mShowDialogs) {
1349                    // XXX This is a temporary dialog, no need to localize.
1350                    AlertDialog d = new BaseErrorDialog(mContext);
1351                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1352                    d.setCancelable(false);
1353                    d.setTitle(title);
1354                    d.setMessage(text);
1355                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1356                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1357                    mUidAlert = d;
1358                    d.show();
1359                }
1360            } break;
1361            case IM_FEELING_LUCKY_MSG: {
1362                if (mUidAlert != null) {
1363                    mUidAlert.dismiss();
1364                    mUidAlert = null;
1365                }
1366            } break;
1367            case PROC_START_TIMEOUT_MSG: {
1368                if (mDidDexOpt) {
1369                    mDidDexOpt = false;
1370                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1371                    nmsg.obj = msg.obj;
1372                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1373                    return;
1374                }
1375                ProcessRecord app = (ProcessRecord)msg.obj;
1376                synchronized (ActivityManagerService.this) {
1377                    processStartTimedOutLocked(app);
1378                }
1379            } break;
1380            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1381                synchronized (ActivityManagerService.this) {
1382                    doPendingActivityLaunchesLocked(true);
1383                }
1384            } break;
1385            case KILL_APPLICATION_MSG: {
1386                synchronized (ActivityManagerService.this) {
1387                    int appid = msg.arg1;
1388                    boolean restart = (msg.arg2 == 1);
1389                    Bundle bundle = (Bundle)msg.obj;
1390                    String pkg = bundle.getString("pkg");
1391                    String reason = bundle.getString("reason");
1392                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1393                            false, UserHandle.USER_ALL, reason);
1394                }
1395            } break;
1396            case FINALIZE_PENDING_INTENT_MSG: {
1397                ((PendingIntentRecord)msg.obj).completeFinalize();
1398            } break;
1399            case POST_HEAVY_NOTIFICATION_MSG: {
1400                INotificationManager inm = NotificationManager.getService();
1401                if (inm == null) {
1402                    return;
1403                }
1404
1405                ActivityRecord root = (ActivityRecord)msg.obj;
1406                ProcessRecord process = root.app;
1407                if (process == null) {
1408                    return;
1409                }
1410
1411                try {
1412                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1413                    String text = mContext.getString(R.string.heavy_weight_notification,
1414                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1415                    Notification notification = new Notification();
1416                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1417                    notification.when = 0;
1418                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1419                    notification.tickerText = text;
1420                    notification.defaults = 0; // please be quiet
1421                    notification.sound = null;
1422                    notification.vibrate = null;
1423                    notification.setLatestEventInfo(context, text,
1424                            mContext.getText(R.string.heavy_weight_notification_detail),
1425                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1426                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1427                                    new UserHandle(root.userId)));
1428
1429                    try {
1430                        int[] outId = new int[1];
1431                        inm.enqueueNotificationWithTag("android", "android", null,
1432                                R.string.heavy_weight_notification,
1433                                notification, outId, root.userId);
1434                    } catch (RuntimeException e) {
1435                        Slog.w(ActivityManagerService.TAG,
1436                                "Error showing notification for heavy-weight app", e);
1437                    } catch (RemoteException e) {
1438                    }
1439                } catch (NameNotFoundException e) {
1440                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1441                }
1442            } break;
1443            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1444                INotificationManager inm = NotificationManager.getService();
1445                if (inm == null) {
1446                    return;
1447                }
1448                try {
1449                    inm.cancelNotificationWithTag("android", null,
1450                            R.string.heavy_weight_notification,  msg.arg1);
1451                } catch (RuntimeException e) {
1452                    Slog.w(ActivityManagerService.TAG,
1453                            "Error canceling notification for service", e);
1454                } catch (RemoteException e) {
1455                }
1456            } break;
1457            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1458                synchronized (ActivityManagerService.this) {
1459                    checkExcessivePowerUsageLocked(true);
1460                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1461                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1462                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1463                }
1464            } break;
1465            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1466                synchronized (ActivityManagerService.this) {
1467                    ActivityRecord ar = (ActivityRecord)msg.obj;
1468                    if (mCompatModeDialog != null) {
1469                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1470                                ar.info.applicationInfo.packageName)) {
1471                            return;
1472                        }
1473                        mCompatModeDialog.dismiss();
1474                        mCompatModeDialog = null;
1475                    }
1476                    if (ar != null && false) {
1477                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1478                                ar.packageName)) {
1479                            int mode = mCompatModePackages.computeCompatModeLocked(
1480                                    ar.info.applicationInfo);
1481                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1482                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1483                                mCompatModeDialog = new CompatModeDialog(
1484                                        ActivityManagerService.this, mContext,
1485                                        ar.info.applicationInfo);
1486                                mCompatModeDialog.show();
1487                            }
1488                        }
1489                    }
1490                }
1491                break;
1492            }
1493            case DISPATCH_PROCESSES_CHANGED: {
1494                dispatchProcessesChanged();
1495                break;
1496            }
1497            case DISPATCH_PROCESS_DIED: {
1498                final int pid = msg.arg1;
1499                final int uid = msg.arg2;
1500                dispatchProcessDied(pid, uid);
1501                break;
1502            }
1503            case REPORT_MEM_USAGE_MSG: {
1504                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1505                Thread thread = new Thread() {
1506                    @Override public void run() {
1507                        final SparseArray<ProcessMemInfo> infoMap
1508                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1509                        for (int i=0, N=memInfos.size(); i<N; i++) {
1510                            ProcessMemInfo mi = memInfos.get(i);
1511                            infoMap.put(mi.pid, mi);
1512                        }
1513                        updateCpuStatsNow();
1514                        synchronized (mProcessCpuThread) {
1515                            final int N = mProcessCpuTracker.countStats();
1516                            for (int i=0; i<N; i++) {
1517                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1518                                if (st.vsize > 0) {
1519                                    long pss = Debug.getPss(st.pid, null);
1520                                    if (pss > 0) {
1521                                        if (infoMap.indexOfKey(st.pid) < 0) {
1522                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1523                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1524                                            mi.pss = pss;
1525                                            memInfos.add(mi);
1526                                        }
1527                                    }
1528                                }
1529                            }
1530                        }
1531
1532                        long totalPss = 0;
1533                        for (int i=0, N=memInfos.size(); i<N; i++) {
1534                            ProcessMemInfo mi = memInfos.get(i);
1535                            if (mi.pss == 0) {
1536                                mi.pss = Debug.getPss(mi.pid, null);
1537                            }
1538                            totalPss += mi.pss;
1539                        }
1540                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1541                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1542                                if (lhs.oomAdj != rhs.oomAdj) {
1543                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1544                                }
1545                                if (lhs.pss != rhs.pss) {
1546                                    return lhs.pss < rhs.pss ? 1 : -1;
1547                                }
1548                                return 0;
1549                            }
1550                        });
1551
1552                        StringBuilder tag = new StringBuilder(128);
1553                        StringBuilder stack = new StringBuilder(128);
1554                        tag.append("Low on memory -- ");
1555                        appendMemBucket(tag, totalPss, "total", false);
1556                        appendMemBucket(stack, totalPss, "total", true);
1557
1558                        StringBuilder logBuilder = new StringBuilder(1024);
1559                        logBuilder.append("Low on memory:\n");
1560
1561                        boolean firstLine = true;
1562                        int lastOomAdj = Integer.MIN_VALUE;
1563                        for (int i=0, N=memInfos.size(); i<N; i++) {
1564                            ProcessMemInfo mi = memInfos.get(i);
1565
1566                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1567                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1568                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1569                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1570                                if (lastOomAdj != mi.oomAdj) {
1571                                    lastOomAdj = mi.oomAdj;
1572                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1573                                        tag.append(" / ");
1574                                    }
1575                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1576                                        if (firstLine) {
1577                                            stack.append(":");
1578                                            firstLine = false;
1579                                        }
1580                                        stack.append("\n\t at ");
1581                                    } else {
1582                                        stack.append("$");
1583                                    }
1584                                } else {
1585                                    tag.append(" ");
1586                                    stack.append("$");
1587                                }
1588                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1589                                    appendMemBucket(tag, mi.pss, mi.name, false);
1590                                }
1591                                appendMemBucket(stack, mi.pss, mi.name, true);
1592                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1593                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1594                                    stack.append("(");
1595                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1596                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1597                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1598                                            stack.append(":");
1599                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1600                                        }
1601                                    }
1602                                    stack.append(")");
1603                                }
1604                            }
1605
1606                            logBuilder.append("  ");
1607                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1608                            logBuilder.append(' ');
1609                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1610                            logBuilder.append(' ');
1611                            ProcessList.appendRamKb(logBuilder, mi.pss);
1612                            logBuilder.append(" kB: ");
1613                            logBuilder.append(mi.name);
1614                            logBuilder.append(" (");
1615                            logBuilder.append(mi.pid);
1616                            logBuilder.append(") ");
1617                            logBuilder.append(mi.adjType);
1618                            logBuilder.append('\n');
1619                            if (mi.adjReason != null) {
1620                                logBuilder.append("                      ");
1621                                logBuilder.append(mi.adjReason);
1622                                logBuilder.append('\n');
1623                            }
1624                        }
1625
1626                        logBuilder.append("           ");
1627                        ProcessList.appendRamKb(logBuilder, totalPss);
1628                        logBuilder.append(" kB: TOTAL\n");
1629
1630                        long[] infos = new long[Debug.MEMINFO_COUNT];
1631                        Debug.getMemInfo(infos);
1632                        logBuilder.append("  MemInfo: ");
1633                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1634                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1635                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1636                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1637                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1638                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1639                            logBuilder.append("  ZRAM: ");
1640                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1641                            logBuilder.append(" kB RAM, ");
1642                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1643                            logBuilder.append(" kB swap total, ");
1644                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1645                            logBuilder.append(" kB swap free\n");
1646                        }
1647                        Slog.i(TAG, logBuilder.toString());
1648
1649                        StringBuilder dropBuilder = new StringBuilder(1024);
1650                        /*
1651                        StringWriter oomSw = new StringWriter();
1652                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1653                        StringWriter catSw = new StringWriter();
1654                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1655                        String[] emptyArgs = new String[] { };
1656                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1657                        oomPw.flush();
1658                        String oomString = oomSw.toString();
1659                        */
1660                        dropBuilder.append(stack);
1661                        dropBuilder.append('\n');
1662                        dropBuilder.append('\n');
1663                        dropBuilder.append(logBuilder);
1664                        dropBuilder.append('\n');
1665                        /*
1666                        dropBuilder.append(oomString);
1667                        dropBuilder.append('\n');
1668                        */
1669                        StringWriter catSw = new StringWriter();
1670                        synchronized (ActivityManagerService.this) {
1671                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1672                            String[] emptyArgs = new String[] { };
1673                            catPw.println();
1674                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1675                            catPw.println();
1676                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1677                                    false, false, null);
1678                            catPw.println();
1679                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1680                            catPw.flush();
1681                        }
1682                        dropBuilder.append(catSw.toString());
1683                        addErrorToDropBox("lowmem", null, "system_server", null,
1684                                null, tag.toString(), dropBuilder.toString(), null, null);
1685                        //Slog.i(TAG, "Sent to dropbox:");
1686                        //Slog.i(TAG, dropBuilder.toString());
1687                        synchronized (ActivityManagerService.this) {
1688                            long now = SystemClock.uptimeMillis();
1689                            if (mLastMemUsageReportTime < now) {
1690                                mLastMemUsageReportTime = now;
1691                            }
1692                        }
1693                    }
1694                };
1695                thread.start();
1696                break;
1697            }
1698            case REPORT_USER_SWITCH_MSG: {
1699                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1700                break;
1701            }
1702            case CONTINUE_USER_SWITCH_MSG: {
1703                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1704                break;
1705            }
1706            case USER_SWITCH_TIMEOUT_MSG: {
1707                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1708                break;
1709            }
1710            case IMMERSIVE_MODE_LOCK_MSG: {
1711                final boolean nextState = (msg.arg1 != 0);
1712                if (mUpdateLock.isHeld() != nextState) {
1713                    if (DEBUG_IMMERSIVE) {
1714                        final ActivityRecord r = (ActivityRecord) msg.obj;
1715                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1716                    }
1717                    if (nextState) {
1718                        mUpdateLock.acquire();
1719                    } else {
1720                        mUpdateLock.release();
1721                    }
1722                }
1723                break;
1724            }
1725            case PERSIST_URI_GRANTS_MSG: {
1726                writeGrantedUriPermissions();
1727                break;
1728            }
1729            case REQUEST_ALL_PSS_MSG: {
1730                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1731                break;
1732            }
1733            case START_PROFILES_MSG: {
1734                synchronized (ActivityManagerService.this) {
1735                    startProfilesLocked();
1736                }
1737                break;
1738            }
1739            case UPDATE_TIME: {
1740                synchronized (ActivityManagerService.this) {
1741                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1742                        ProcessRecord r = mLruProcesses.get(i);
1743                        if (r.thread != null) {
1744                            try {
1745                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1746                            } catch (RemoteException ex) {
1747                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1748                            }
1749                        }
1750                    }
1751                }
1752                break;
1753            }
1754            }
1755        }
1756    };
1757
1758    static final int COLLECT_PSS_BG_MSG = 1;
1759
1760    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1761        @Override
1762        public void handleMessage(Message msg) {
1763            switch (msg.what) {
1764            case COLLECT_PSS_BG_MSG: {
1765                int i=0, num=0;
1766                long start = SystemClock.uptimeMillis();
1767                long[] tmp = new long[1];
1768                do {
1769                    ProcessRecord proc;
1770                    int procState;
1771                    int pid;
1772                    synchronized (ActivityManagerService.this) {
1773                        if (i >= mPendingPssProcesses.size()) {
1774                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1775                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1776                            mPendingPssProcesses.clear();
1777                            return;
1778                        }
1779                        proc = mPendingPssProcesses.get(i);
1780                        procState = proc.pssProcState;
1781                        if (proc.thread != null && procState == proc.setProcState) {
1782                            pid = proc.pid;
1783                        } else {
1784                            proc = null;
1785                            pid = 0;
1786                        }
1787                        i++;
1788                    }
1789                    if (proc != null) {
1790                        long pss = Debug.getPss(pid, tmp);
1791                        synchronized (ActivityManagerService.this) {
1792                            if (proc.thread != null && proc.setProcState == procState
1793                                    && proc.pid == pid) {
1794                                num++;
1795                                proc.lastPssTime = SystemClock.uptimeMillis();
1796                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1797                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1798                                        + ": " + pss + " lastPss=" + proc.lastPss
1799                                        + " state=" + ProcessList.makeProcStateString(procState));
1800                                if (proc.initialIdlePss == 0) {
1801                                    proc.initialIdlePss = pss;
1802                                }
1803                                proc.lastPss = pss;
1804                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1805                                    proc.lastCachedPss = pss;
1806                                }
1807                            }
1808                        }
1809                    }
1810                } while (true);
1811            }
1812            }
1813        }
1814    };
1815
1816    public void setSystemProcess() {
1817        try {
1818            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1819            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1820            ServiceManager.addService("meminfo", new MemBinder(this));
1821            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1822            ServiceManager.addService("dbinfo", new DbBinder(this));
1823            if (MONITOR_CPU_USAGE) {
1824                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1825            }
1826            ServiceManager.addService("permission", new PermissionController(this));
1827
1828            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1829                    "android", STOCK_PM_FLAGS);
1830            mSystemThread.installSystemApplicationInfo(info);
1831
1832            synchronized (this) {
1833                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1834                app.persistent = true;
1835                app.pid = MY_PID;
1836                app.maxAdj = ProcessList.SYSTEM_ADJ;
1837                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1838                mProcessNames.put(app.processName, app.uid, app);
1839                synchronized (mPidsSelfLocked) {
1840                    mPidsSelfLocked.put(app.pid, app);
1841                }
1842                updateLruProcessLocked(app, false, null);
1843                updateOomAdjLocked();
1844            }
1845        } catch (PackageManager.NameNotFoundException e) {
1846            throw new RuntimeException(
1847                    "Unable to find android system package", e);
1848        }
1849    }
1850
1851    public void setWindowManager(WindowManagerService wm) {
1852        mWindowManager = wm;
1853        mStackSupervisor.setWindowManager(wm);
1854    }
1855
1856    public void startObservingNativeCrashes() {
1857        final NativeCrashListener ncl = new NativeCrashListener(this);
1858        ncl.start();
1859    }
1860
1861    public IAppOpsService getAppOpsService() {
1862        return mAppOpsService;
1863    }
1864
1865    static class MemBinder extends Binder {
1866        ActivityManagerService mActivityManagerService;
1867        MemBinder(ActivityManagerService activityManagerService) {
1868            mActivityManagerService = activityManagerService;
1869        }
1870
1871        @Override
1872        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1873            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1874                    != PackageManager.PERMISSION_GRANTED) {
1875                pw.println("Permission Denial: can't dump meminfo from from pid="
1876                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1877                        + " without permission " + android.Manifest.permission.DUMP);
1878                return;
1879            }
1880
1881            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1882        }
1883    }
1884
1885    static class GraphicsBinder extends Binder {
1886        ActivityManagerService mActivityManagerService;
1887        GraphicsBinder(ActivityManagerService activityManagerService) {
1888            mActivityManagerService = activityManagerService;
1889        }
1890
1891        @Override
1892        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1893            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1894                    != PackageManager.PERMISSION_GRANTED) {
1895                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1896                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1897                        + " without permission " + android.Manifest.permission.DUMP);
1898                return;
1899            }
1900
1901            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1902        }
1903    }
1904
1905    static class DbBinder extends Binder {
1906        ActivityManagerService mActivityManagerService;
1907        DbBinder(ActivityManagerService activityManagerService) {
1908            mActivityManagerService = activityManagerService;
1909        }
1910
1911        @Override
1912        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1913            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1914                    != PackageManager.PERMISSION_GRANTED) {
1915                pw.println("Permission Denial: can't dump dbinfo from from pid="
1916                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1917                        + " without permission " + android.Manifest.permission.DUMP);
1918                return;
1919            }
1920
1921            mActivityManagerService.dumpDbInfo(fd, pw, args);
1922        }
1923    }
1924
1925    static class CpuBinder extends Binder {
1926        ActivityManagerService mActivityManagerService;
1927        CpuBinder(ActivityManagerService activityManagerService) {
1928            mActivityManagerService = activityManagerService;
1929        }
1930
1931        @Override
1932        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1933            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1934                    != PackageManager.PERMISSION_GRANTED) {
1935                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1936                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1937                        + " without permission " + android.Manifest.permission.DUMP);
1938                return;
1939            }
1940
1941            synchronized (mActivityManagerService.mProcessCpuThread) {
1942                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1943                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1944                        SystemClock.uptimeMillis()));
1945            }
1946        }
1947    }
1948
1949    public static final class Lifecycle extends SystemService {
1950        private final ActivityManagerService mService;
1951
1952        public Lifecycle(Context context) {
1953            super(context);
1954            mService = new ActivityManagerService(context);
1955        }
1956
1957        @Override
1958        public void onStart() {
1959            mService.start();
1960        }
1961
1962        public ActivityManagerService getService() {
1963            return mService;
1964        }
1965    }
1966
1967    // Note: This method is invoked on the main thread but may need to attach various
1968    // handlers to other threads.  So take care to be explicit about the looper.
1969    public ActivityManagerService(Context systemContext) {
1970        mContext = systemContext;
1971        mFactoryTest = FactoryTest.getMode();
1972        mSystemThread = ActivityThread.currentActivityThread();
1973
1974        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1975
1976        mHandlerThread = new ServiceThread(TAG,
1977                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1978        mHandlerThread.start();
1979        mHandler = new MainHandler(mHandlerThread.getLooper());
1980
1981        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1982                "foreground", BROADCAST_FG_TIMEOUT, false);
1983        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1984                "background", BROADCAST_BG_TIMEOUT, true);
1985        mBroadcastQueues[0] = mFgBroadcastQueue;
1986        mBroadcastQueues[1] = mBgBroadcastQueue;
1987
1988        mServices = new ActiveServices(this);
1989        mProviderMap = new ProviderMap(this);
1990
1991        // TODO: Move creation of battery stats service outside of activity manager service.
1992        File dataDir = Environment.getDataDirectory();
1993        File systemDir = new File(dataDir, "system");
1994        systemDir.mkdirs();
1995        mBatteryStatsService = new BatteryStatsService(new File(
1996                systemDir, "batterystats.bin").toString(), mHandler);
1997        mBatteryStatsService.getActiveStatistics().readLocked();
1998        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1999        mOnBattery = DEBUG_POWER ? true
2000                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2001        mBatteryStatsService.getActiveStatistics().setCallback(this);
2002
2003        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2004
2005        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2006        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2007
2008        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2009
2010        // User 0 is the first and only user that runs at boot.
2011        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2012        mUserLru.add(Integer.valueOf(0));
2013        updateStartedUserArrayLocked();
2014
2015        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2016            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2017
2018        mConfiguration.setToDefaults();
2019        mConfiguration.setLocale(Locale.getDefault());
2020
2021        mConfigurationSeq = mConfiguration.seq = 1;
2022        mProcessCpuTracker.init();
2023
2024        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2025        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2026        mStackSupervisor = new ActivityStackSupervisor(this);
2027
2028        mProcessCpuThread = new Thread("CpuTracker") {
2029            @Override
2030            public void run() {
2031                while (true) {
2032                    try {
2033                        try {
2034                            synchronized(this) {
2035                                final long now = SystemClock.uptimeMillis();
2036                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2037                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2038                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2039                                //        + ", write delay=" + nextWriteDelay);
2040                                if (nextWriteDelay < nextCpuDelay) {
2041                                    nextCpuDelay = nextWriteDelay;
2042                                }
2043                                if (nextCpuDelay > 0) {
2044                                    mProcessCpuMutexFree.set(true);
2045                                    this.wait(nextCpuDelay);
2046                                }
2047                            }
2048                        } catch (InterruptedException e) {
2049                        }
2050                        updateCpuStatsNow();
2051                    } catch (Exception e) {
2052                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2053                    }
2054                }
2055            }
2056        };
2057
2058        Watchdog.getInstance().addMonitor(this);
2059        Watchdog.getInstance().addThread(mHandler);
2060    }
2061
2062    private void start() {
2063        mProcessCpuThread.start();
2064
2065        mBatteryStatsService.publish(mContext);
2066        mUsageStatsService.publish(mContext);
2067        mAppOpsService.publish(mContext);
2068
2069        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2070    }
2071
2072    @Override
2073    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2074            throws RemoteException {
2075        if (code == SYSPROPS_TRANSACTION) {
2076            // We need to tell all apps about the system property change.
2077            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2078            synchronized(this) {
2079                final int NP = mProcessNames.getMap().size();
2080                for (int ip=0; ip<NP; ip++) {
2081                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2082                    final int NA = apps.size();
2083                    for (int ia=0; ia<NA; ia++) {
2084                        ProcessRecord app = apps.valueAt(ia);
2085                        if (app.thread != null) {
2086                            procs.add(app.thread.asBinder());
2087                        }
2088                    }
2089                }
2090            }
2091
2092            int N = procs.size();
2093            for (int i=0; i<N; i++) {
2094                Parcel data2 = Parcel.obtain();
2095                try {
2096                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2097                } catch (RemoteException e) {
2098                }
2099                data2.recycle();
2100            }
2101        }
2102        try {
2103            return super.onTransact(code, data, reply, flags);
2104        } catch (RuntimeException e) {
2105            // The activity manager only throws security exceptions, so let's
2106            // log all others.
2107            if (!(e instanceof SecurityException)) {
2108                Slog.wtf(TAG, "Activity Manager Crash", e);
2109            }
2110            throw e;
2111        }
2112    }
2113
2114    void updateCpuStats() {
2115        final long now = SystemClock.uptimeMillis();
2116        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2117            return;
2118        }
2119        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2120            synchronized (mProcessCpuThread) {
2121                mProcessCpuThread.notify();
2122            }
2123        }
2124    }
2125
2126    void updateCpuStatsNow() {
2127        synchronized (mProcessCpuThread) {
2128            mProcessCpuMutexFree.set(false);
2129            final long now = SystemClock.uptimeMillis();
2130            boolean haveNewCpuStats = false;
2131
2132            if (MONITOR_CPU_USAGE &&
2133                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2134                mLastCpuTime.set(now);
2135                haveNewCpuStats = true;
2136                mProcessCpuTracker.update();
2137                //Slog.i(TAG, mProcessCpu.printCurrentState());
2138                //Slog.i(TAG, "Total CPU usage: "
2139                //        + mProcessCpu.getTotalCpuPercent() + "%");
2140
2141                // Slog the cpu usage if the property is set.
2142                if ("true".equals(SystemProperties.get("events.cpu"))) {
2143                    int user = mProcessCpuTracker.getLastUserTime();
2144                    int system = mProcessCpuTracker.getLastSystemTime();
2145                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2146                    int irq = mProcessCpuTracker.getLastIrqTime();
2147                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2148                    int idle = mProcessCpuTracker.getLastIdleTime();
2149
2150                    int total = user + system + iowait + irq + softIrq + idle;
2151                    if (total == 0) total = 1;
2152
2153                    EventLog.writeEvent(EventLogTags.CPU,
2154                            ((user+system+iowait+irq+softIrq) * 100) / total,
2155                            (user * 100) / total,
2156                            (system * 100) / total,
2157                            (iowait * 100) / total,
2158                            (irq * 100) / total,
2159                            (softIrq * 100) / total);
2160                }
2161            }
2162
2163            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2164            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2165            synchronized(bstats) {
2166                synchronized(mPidsSelfLocked) {
2167                    if (haveNewCpuStats) {
2168                        if (mOnBattery) {
2169                            int perc = bstats.startAddingCpuLocked();
2170                            int totalUTime = 0;
2171                            int totalSTime = 0;
2172                            final int N = mProcessCpuTracker.countStats();
2173                            for (int i=0; i<N; i++) {
2174                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2175                                if (!st.working) {
2176                                    continue;
2177                                }
2178                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2179                                int otherUTime = (st.rel_utime*perc)/100;
2180                                int otherSTime = (st.rel_stime*perc)/100;
2181                                totalUTime += otherUTime;
2182                                totalSTime += otherSTime;
2183                                if (pr != null) {
2184                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2185                                    if (ps == null || !ps.isActive()) {
2186                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2187                                                pr.info.uid, pr.processName);
2188                                    }
2189                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2190                                            st.rel_stime-otherSTime);
2191                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2192                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2193                                } else {
2194                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2195                                    if (ps == null || !ps.isActive()) {
2196                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2197                                                bstats.mapUid(st.uid), st.name);
2198                                    }
2199                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2200                                            st.rel_stime-otherSTime);
2201                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2202                                }
2203                            }
2204                            bstats.finishAddingCpuLocked(perc, totalUTime,
2205                                    totalSTime, cpuSpeedTimes);
2206                        }
2207                    }
2208                }
2209
2210                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2211                    mLastWriteTime = now;
2212                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2213                }
2214            }
2215        }
2216    }
2217
2218    @Override
2219    public void batteryNeedsCpuUpdate() {
2220        updateCpuStatsNow();
2221    }
2222
2223    @Override
2224    public void batteryPowerChanged(boolean onBattery) {
2225        // When plugging in, update the CPU stats first before changing
2226        // the plug state.
2227        updateCpuStatsNow();
2228        synchronized (this) {
2229            synchronized(mPidsSelfLocked) {
2230                mOnBattery = DEBUG_POWER ? true : onBattery;
2231            }
2232        }
2233    }
2234
2235    /**
2236     * Initialize the application bind args. These are passed to each
2237     * process when the bindApplication() IPC is sent to the process. They're
2238     * lazily setup to make sure the services are running when they're asked for.
2239     */
2240    private HashMap<String, IBinder> getCommonServicesLocked() {
2241        if (mAppBindArgs == null) {
2242            mAppBindArgs = new HashMap<String, IBinder>();
2243
2244            // Setup the application init args
2245            mAppBindArgs.put("package", ServiceManager.getService("package"));
2246            mAppBindArgs.put("window", ServiceManager.getService("window"));
2247            mAppBindArgs.put(Context.ALARM_SERVICE,
2248                    ServiceManager.getService(Context.ALARM_SERVICE));
2249        }
2250        return mAppBindArgs;
2251    }
2252
2253    final void setFocusedActivityLocked(ActivityRecord r) {
2254        if (mFocusedActivity != r) {
2255            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2256            mFocusedActivity = r;
2257            mStackSupervisor.setFocusedStack(r);
2258            if (r != null) {
2259                mWindowManager.setFocusedApp(r.appToken, true);
2260            }
2261            applyUpdateLockStateLocked(r);
2262        }
2263    }
2264
2265    @Override
2266    public void setFocusedStack(int stackId) {
2267        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2268        synchronized (ActivityManagerService.this) {
2269            ActivityStack stack = mStackSupervisor.getStack(stackId);
2270            if (stack != null) {
2271                ActivityRecord r = stack.topRunningActivityLocked(null);
2272                if (r != null) {
2273                    setFocusedActivityLocked(r);
2274                }
2275            }
2276        }
2277    }
2278
2279    @Override
2280    public void notifyActivityDrawn(IBinder token) {
2281        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2282        synchronized (this) {
2283            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2284            if (r != null) {
2285                r.task.stack.notifyActivityDrawnLocked(r);
2286            }
2287        }
2288    }
2289
2290    final void applyUpdateLockStateLocked(ActivityRecord r) {
2291        // Modifications to the UpdateLock state are done on our handler, outside
2292        // the activity manager's locks.  The new state is determined based on the
2293        // state *now* of the relevant activity record.  The object is passed to
2294        // the handler solely for logging detail, not to be consulted/modified.
2295        final boolean nextState = r != null && r.immersive;
2296        mHandler.sendMessage(
2297                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2298    }
2299
2300    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2301        Message msg = Message.obtain();
2302        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2303        msg.obj = r.task.askedCompatMode ? null : r;
2304        mHandler.sendMessage(msg);
2305    }
2306
2307    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2308            String what, Object obj, ProcessRecord srcApp) {
2309        app.lastActivityTime = now;
2310
2311        if (app.activities.size() > 0) {
2312            // Don't want to touch dependent processes that are hosting activities.
2313            return index;
2314        }
2315
2316        int lrui = mLruProcesses.lastIndexOf(app);
2317        if (lrui < 0) {
2318            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2319                    + what + " " + obj + " from " + srcApp);
2320            return index;
2321        }
2322
2323        if (lrui >= index) {
2324            // Don't want to cause this to move dependent processes *back* in the
2325            // list as if they were less frequently used.
2326            return index;
2327        }
2328
2329        if (lrui >= mLruProcessActivityStart) {
2330            // Don't want to touch dependent processes that are hosting activities.
2331            return index;
2332        }
2333
2334        mLruProcesses.remove(lrui);
2335        if (index > 0) {
2336            index--;
2337        }
2338        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2339                + " in LRU list: " + app);
2340        mLruProcesses.add(index, app);
2341        return index;
2342    }
2343
2344    final void removeLruProcessLocked(ProcessRecord app) {
2345        int lrui = mLruProcesses.lastIndexOf(app);
2346        if (lrui >= 0) {
2347            if (lrui <= mLruProcessActivityStart) {
2348                mLruProcessActivityStart--;
2349            }
2350            if (lrui <= mLruProcessServiceStart) {
2351                mLruProcessServiceStart--;
2352            }
2353            mLruProcesses.remove(lrui);
2354        }
2355    }
2356
2357    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2358            ProcessRecord client) {
2359        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2360                || app.treatLikeActivity;
2361        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2362        if (!activityChange && hasActivity) {
2363            // The process has activities, so we are only allowing activity-based adjustments
2364            // to move it.  It should be kept in the front of the list with other
2365            // processes that have activities, and we don't want those to change their
2366            // order except due to activity operations.
2367            return;
2368        }
2369
2370        mLruSeq++;
2371        final long now = SystemClock.uptimeMillis();
2372        app.lastActivityTime = now;
2373
2374        // First a quick reject: if the app is already at the position we will
2375        // put it, then there is nothing to do.
2376        if (hasActivity) {
2377            final int N = mLruProcesses.size();
2378            if (N > 0 && mLruProcesses.get(N-1) == app) {
2379                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2380                return;
2381            }
2382        } else {
2383            if (mLruProcessServiceStart > 0
2384                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2385                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2386                return;
2387            }
2388        }
2389
2390        int lrui = mLruProcesses.lastIndexOf(app);
2391
2392        if (app.persistent && lrui >= 0) {
2393            // We don't care about the position of persistent processes, as long as
2394            // they are in the list.
2395            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2396            return;
2397        }
2398
2399        /* In progress: compute new position first, so we can avoid doing work
2400           if the process is not actually going to move.  Not yet working.
2401        int addIndex;
2402        int nextIndex;
2403        boolean inActivity = false, inService = false;
2404        if (hasActivity) {
2405            // Process has activities, put it at the very tipsy-top.
2406            addIndex = mLruProcesses.size();
2407            nextIndex = mLruProcessServiceStart;
2408            inActivity = true;
2409        } else if (hasService) {
2410            // Process has services, put it at the top of the service list.
2411            addIndex = mLruProcessActivityStart;
2412            nextIndex = mLruProcessServiceStart;
2413            inActivity = true;
2414            inService = true;
2415        } else  {
2416            // Process not otherwise of interest, it goes to the top of the non-service area.
2417            addIndex = mLruProcessServiceStart;
2418            if (client != null) {
2419                int clientIndex = mLruProcesses.lastIndexOf(client);
2420                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2421                        + app);
2422                if (clientIndex >= 0 && addIndex > clientIndex) {
2423                    addIndex = clientIndex;
2424                }
2425            }
2426            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2427        }
2428
2429        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2430                + mLruProcessActivityStart + "): " + app);
2431        */
2432
2433        if (lrui >= 0) {
2434            if (lrui < mLruProcessActivityStart) {
2435                mLruProcessActivityStart--;
2436            }
2437            if (lrui < mLruProcessServiceStart) {
2438                mLruProcessServiceStart--;
2439            }
2440            /*
2441            if (addIndex > lrui) {
2442                addIndex--;
2443            }
2444            if (nextIndex > lrui) {
2445                nextIndex--;
2446            }
2447            */
2448            mLruProcesses.remove(lrui);
2449        }
2450
2451        /*
2452        mLruProcesses.add(addIndex, app);
2453        if (inActivity) {
2454            mLruProcessActivityStart++;
2455        }
2456        if (inService) {
2457            mLruProcessActivityStart++;
2458        }
2459        */
2460
2461        int nextIndex;
2462        if (hasActivity) {
2463            final int N = mLruProcesses.size();
2464            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2465                // Process doesn't have activities, but has clients with
2466                // activities...  move it up, but one below the top (the top
2467                // should always have a real activity).
2468                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2469                mLruProcesses.add(N-1, app);
2470                // To keep it from spamming the LRU list (by making a bunch of clients),
2471                // we will push down any other entries owned by the app.
2472                final int uid = app.info.uid;
2473                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2474                    ProcessRecord subProc = mLruProcesses.get(i);
2475                    if (subProc.info.uid == uid) {
2476                        // We want to push this one down the list.  If the process after
2477                        // it is for the same uid, however, don't do so, because we don't
2478                        // want them internally to be re-ordered.
2479                        if (mLruProcesses.get(i-1).info.uid != uid) {
2480                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2481                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2482                            ProcessRecord tmp = mLruProcesses.get(i);
2483                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2484                            mLruProcesses.set(i-1, tmp);
2485                            i--;
2486                        }
2487                    } else {
2488                        // A gap, we can stop here.
2489                        break;
2490                    }
2491                }
2492            } else {
2493                // Process has activities, put it at the very tipsy-top.
2494                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2495                mLruProcesses.add(app);
2496            }
2497            nextIndex = mLruProcessServiceStart;
2498        } else if (hasService) {
2499            // Process has services, put it at the top of the service list.
2500            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2501            mLruProcesses.add(mLruProcessActivityStart, app);
2502            nextIndex = mLruProcessServiceStart;
2503            mLruProcessActivityStart++;
2504        } else  {
2505            // Process not otherwise of interest, it goes to the top of the non-service area.
2506            int index = mLruProcessServiceStart;
2507            if (client != null) {
2508                // If there is a client, don't allow the process to be moved up higher
2509                // in the list than that client.
2510                int clientIndex = mLruProcesses.lastIndexOf(client);
2511                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2512                        + " when updating " + app);
2513                if (clientIndex <= lrui) {
2514                    // Don't allow the client index restriction to push it down farther in the
2515                    // list than it already is.
2516                    clientIndex = lrui;
2517                }
2518                if (clientIndex >= 0 && index > clientIndex) {
2519                    index = clientIndex;
2520                }
2521            }
2522            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2523            mLruProcesses.add(index, app);
2524            nextIndex = index-1;
2525            mLruProcessActivityStart++;
2526            mLruProcessServiceStart++;
2527        }
2528
2529        // If the app is currently using a content provider or service,
2530        // bump those processes as well.
2531        for (int j=app.connections.size()-1; j>=0; j--) {
2532            ConnectionRecord cr = app.connections.valueAt(j);
2533            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2534                    && cr.binding.service.app != null
2535                    && cr.binding.service.app.lruSeq != mLruSeq
2536                    && !cr.binding.service.app.persistent) {
2537                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2538                        "service connection", cr, app);
2539            }
2540        }
2541        for (int j=app.conProviders.size()-1; j>=0; j--) {
2542            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2543            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2544                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2545                        "provider reference", cpr, app);
2546            }
2547        }
2548    }
2549
2550    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2551        if (uid == Process.SYSTEM_UID) {
2552            // The system gets to run in any process.  If there are multiple
2553            // processes with the same uid, just pick the first (this
2554            // should never happen).
2555            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2556            if (procs == null) return null;
2557            final int N = procs.size();
2558            for (int i = 0; i < N; i++) {
2559                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2560            }
2561        }
2562        ProcessRecord proc = mProcessNames.get(processName, uid);
2563        if (false && proc != null && !keepIfLarge
2564                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2565                && proc.lastCachedPss >= 4000) {
2566            // Turn this condition on to cause killing to happen regularly, for testing.
2567            if (proc.baseProcessTracker != null) {
2568                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2569            }
2570            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2571                    + "k from cached");
2572        } else if (proc != null && !keepIfLarge
2573                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2574                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2575            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2576            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2577                if (proc.baseProcessTracker != null) {
2578                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2579                }
2580                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2581                        + "k from cached");
2582            }
2583        }
2584        return proc;
2585    }
2586
2587    void ensurePackageDexOpt(String packageName) {
2588        IPackageManager pm = AppGlobals.getPackageManager();
2589        try {
2590            if (pm.performDexOpt(packageName)) {
2591                mDidDexOpt = true;
2592            }
2593        } catch (RemoteException e) {
2594        }
2595    }
2596
2597    boolean isNextTransitionForward() {
2598        int transit = mWindowManager.getPendingAppTransition();
2599        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2600                || transit == AppTransition.TRANSIT_TASK_OPEN
2601                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2602    }
2603
2604    final ProcessRecord startProcessLocked(String processName,
2605            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2606            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2607            boolean isolated, boolean keepIfLarge) {
2608        ProcessRecord app;
2609        if (!isolated) {
2610            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2611        } else {
2612            // If this is an isolated process, it can't re-use an existing process.
2613            app = null;
2614        }
2615        // We don't have to do anything more if:
2616        // (1) There is an existing application record; and
2617        // (2) The caller doesn't think it is dead, OR there is no thread
2618        //     object attached to it so we know it couldn't have crashed; and
2619        // (3) There is a pid assigned to it, so it is either starting or
2620        //     already running.
2621        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2622                + " app=" + app + " knownToBeDead=" + knownToBeDead
2623                + " thread=" + (app != null ? app.thread : null)
2624                + " pid=" + (app != null ? app.pid : -1));
2625        if (app != null && app.pid > 0) {
2626            if (!knownToBeDead || app.thread == null) {
2627                // We already have the app running, or are waiting for it to
2628                // come up (we have a pid but not yet its thread), so keep it.
2629                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2630                // If this is a new package in the process, add the package to the list
2631                app.addPackage(info.packageName, mProcessStats);
2632                return app;
2633            }
2634
2635            // An application record is attached to a previous process,
2636            // clean it up now.
2637            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2638            handleAppDiedLocked(app, true, true);
2639        }
2640
2641        String hostingNameStr = hostingName != null
2642                ? hostingName.flattenToShortString() : null;
2643
2644        if (!isolated) {
2645            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2646                // If we are in the background, then check to see if this process
2647                // is bad.  If so, we will just silently fail.
2648                if (mBadProcesses.get(info.processName, info.uid) != null) {
2649                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2650                            + "/" + info.processName);
2651                    return null;
2652                }
2653            } else {
2654                // When the user is explicitly starting a process, then clear its
2655                // crash count so that we won't make it bad until they see at
2656                // least one crash dialog again, and make the process good again
2657                // if it had been bad.
2658                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2659                        + "/" + info.processName);
2660                mProcessCrashTimes.remove(info.processName, info.uid);
2661                if (mBadProcesses.get(info.processName, info.uid) != null) {
2662                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2663                            UserHandle.getUserId(info.uid), info.uid,
2664                            info.processName);
2665                    mBadProcesses.remove(info.processName, info.uid);
2666                    if (app != null) {
2667                        app.bad = false;
2668                    }
2669                }
2670            }
2671        }
2672
2673        if (app == null) {
2674            app = newProcessRecordLocked(info, processName, isolated);
2675            if (app == null) {
2676                Slog.w(TAG, "Failed making new process record for "
2677                        + processName + "/" + info.uid + " isolated=" + isolated);
2678                return null;
2679            }
2680            mProcessNames.put(processName, app.uid, app);
2681            if (isolated) {
2682                mIsolatedProcesses.put(app.uid, app);
2683            }
2684        } else {
2685            // If this is a new package in the process, add the package to the list
2686            app.addPackage(info.packageName, mProcessStats);
2687        }
2688
2689        // If the system is not ready yet, then hold off on starting this
2690        // process until it is.
2691        if (!mProcessesReady
2692                && !isAllowedWhileBooting(info)
2693                && !allowWhileBooting) {
2694            if (!mProcessesOnHold.contains(app)) {
2695                mProcessesOnHold.add(app);
2696            }
2697            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2698            return app;
2699        }
2700
2701        startProcessLocked(app, hostingType, hostingNameStr);
2702        return (app.pid != 0) ? app : null;
2703    }
2704
2705    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2706        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2707    }
2708
2709    private final void startProcessLocked(ProcessRecord app,
2710            String hostingType, String hostingNameStr) {
2711        if (app.pid > 0 && app.pid != MY_PID) {
2712            synchronized (mPidsSelfLocked) {
2713                mPidsSelfLocked.remove(app.pid);
2714                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2715            }
2716            app.setPid(0);
2717        }
2718
2719        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2720                "startProcessLocked removing on hold: " + app);
2721        mProcessesOnHold.remove(app);
2722
2723        updateCpuStats();
2724
2725        try {
2726            int uid = app.uid;
2727
2728            int[] gids = null;
2729            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2730            if (!app.isolated) {
2731                int[] permGids = null;
2732                try {
2733                    final PackageManager pm = mContext.getPackageManager();
2734                    permGids = pm.getPackageGids(app.info.packageName);
2735
2736                    if (Environment.isExternalStorageEmulated()) {
2737                        if (pm.checkPermission(
2738                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2739                                app.info.packageName) == PERMISSION_GRANTED) {
2740                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2741                        } else {
2742                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2743                        }
2744                    }
2745                } catch (PackageManager.NameNotFoundException e) {
2746                    Slog.w(TAG, "Unable to retrieve gids", e);
2747                }
2748
2749                /*
2750                 * Add shared application GID so applications can share some
2751                 * resources like shared libraries
2752                 */
2753                if (permGids == null) {
2754                    gids = new int[1];
2755                } else {
2756                    gids = new int[permGids.length + 1];
2757                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2758                }
2759                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2760            }
2761            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2762                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2763                        && mTopComponent != null
2764                        && app.processName.equals(mTopComponent.getPackageName())) {
2765                    uid = 0;
2766                }
2767                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2768                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2769                    uid = 0;
2770                }
2771            }
2772            int debugFlags = 0;
2773            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2774                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2775                // Also turn on CheckJNI for debuggable apps. It's quite
2776                // awkward to turn on otherwise.
2777                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2778            }
2779            // Run the app in safe mode if its manifest requests so or the
2780            // system is booted in safe mode.
2781            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2782                mSafeMode == true) {
2783                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2784            }
2785            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2786                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2787            }
2788            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2789                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2790            }
2791            if ("1".equals(SystemProperties.get("debug.assert"))) {
2792                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2793            }
2794
2795            String requiredAbi = app.info.requiredCpuAbi;
2796            if (requiredAbi == null) {
2797                requiredAbi = Build.SUPPORTED_ABIS[0];
2798            }
2799
2800            // Start the process.  It will either succeed and return a result containing
2801            // the PID of the new process, or else throw a RuntimeException.
2802            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2803                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2804                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2805
2806            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2807            synchronized (bs) {
2808                if (bs.isOnBattery()) {
2809                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2810                }
2811            }
2812
2813            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2814                    UserHandle.getUserId(uid), startResult.pid, uid,
2815                    app.processName, hostingType,
2816                    hostingNameStr != null ? hostingNameStr : "");
2817
2818            if (app.persistent) {
2819                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2820            }
2821
2822            StringBuilder buf = mStringBuilder;
2823            buf.setLength(0);
2824            buf.append("Start proc ");
2825            buf.append(app.processName);
2826            buf.append(" for ");
2827            buf.append(hostingType);
2828            if (hostingNameStr != null) {
2829                buf.append(" ");
2830                buf.append(hostingNameStr);
2831            }
2832            buf.append(": pid=");
2833            buf.append(startResult.pid);
2834            buf.append(" uid=");
2835            buf.append(uid);
2836            buf.append(" gids={");
2837            if (gids != null) {
2838                for (int gi=0; gi<gids.length; gi++) {
2839                    if (gi != 0) buf.append(", ");
2840                    buf.append(gids[gi]);
2841
2842                }
2843            }
2844            buf.append("}");
2845            Slog.i(TAG, buf.toString());
2846            app.setPid(startResult.pid);
2847            app.usingWrapper = startResult.usingWrapper;
2848            app.removed = false;
2849            synchronized (mPidsSelfLocked) {
2850                this.mPidsSelfLocked.put(startResult.pid, app);
2851                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2852                msg.obj = app;
2853                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2854                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2855            }
2856            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2857                    app.processName, app.info.uid);
2858            if (app.isolated) {
2859                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2860            }
2861        } catch (RuntimeException e) {
2862            // XXX do better error recovery.
2863            app.setPid(0);
2864            Slog.e(TAG, "Failure starting process " + app.processName, e);
2865        }
2866    }
2867
2868    void updateUsageStats(ActivityRecord component, boolean resumed) {
2869        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2870        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2871        if (resumed) {
2872            mUsageStatsService.noteResumeComponent(component.realActivity);
2873            synchronized (stats) {
2874                stats.noteActivityResumedLocked(component.app.uid);
2875            }
2876        } else {
2877            mUsageStatsService.notePauseComponent(component.realActivity);
2878            synchronized (stats) {
2879                stats.noteActivityPausedLocked(component.app.uid);
2880            }
2881        }
2882    }
2883
2884    Intent getHomeIntent() {
2885        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2886        intent.setComponent(mTopComponent);
2887        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2888            intent.addCategory(Intent.CATEGORY_HOME);
2889        }
2890        return intent;
2891    }
2892
2893    boolean startHomeActivityLocked(int userId) {
2894        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2895                && mTopAction == null) {
2896            // We are running in factory test mode, but unable to find
2897            // the factory test app, so just sit around displaying the
2898            // error message and don't try to start anything.
2899            return false;
2900        }
2901        Intent intent = getHomeIntent();
2902        ActivityInfo aInfo =
2903            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2904        if (aInfo != null) {
2905            intent.setComponent(new ComponentName(
2906                    aInfo.applicationInfo.packageName, aInfo.name));
2907            // Don't do this if the home app is currently being
2908            // instrumented.
2909            aInfo = new ActivityInfo(aInfo);
2910            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2911            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2912                    aInfo.applicationInfo.uid, true);
2913            if (app == null || app.instrumentationClass == null) {
2914                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2915                mStackSupervisor.startHomeActivity(intent, aInfo);
2916            }
2917        }
2918
2919        return true;
2920    }
2921
2922    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2923        ActivityInfo ai = null;
2924        ComponentName comp = intent.getComponent();
2925        try {
2926            if (comp != null) {
2927                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2928            } else {
2929                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2930                        intent,
2931                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2932                            flags, userId);
2933
2934                if (info != null) {
2935                    ai = info.activityInfo;
2936                }
2937            }
2938        } catch (RemoteException e) {
2939            // ignore
2940        }
2941
2942        return ai;
2943    }
2944
2945    /**
2946     * Starts the "new version setup screen" if appropriate.
2947     */
2948    void startSetupActivityLocked() {
2949        // Only do this once per boot.
2950        if (mCheckedForSetup) {
2951            return;
2952        }
2953
2954        // We will show this screen if the current one is a different
2955        // version than the last one shown, and we are not running in
2956        // low-level factory test mode.
2957        final ContentResolver resolver = mContext.getContentResolver();
2958        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2959                Settings.Global.getInt(resolver,
2960                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2961            mCheckedForSetup = true;
2962
2963            // See if we should be showing the platform update setup UI.
2964            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2965            List<ResolveInfo> ris = mContext.getPackageManager()
2966                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2967
2968            // We don't allow third party apps to replace this.
2969            ResolveInfo ri = null;
2970            for (int i=0; ris != null && i<ris.size(); i++) {
2971                if ((ris.get(i).activityInfo.applicationInfo.flags
2972                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2973                    ri = ris.get(i);
2974                    break;
2975                }
2976            }
2977
2978            if (ri != null) {
2979                String vers = ri.activityInfo.metaData != null
2980                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2981                        : null;
2982                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2983                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2984                            Intent.METADATA_SETUP_VERSION);
2985                }
2986                String lastVers = Settings.Secure.getString(
2987                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2988                if (vers != null && !vers.equals(lastVers)) {
2989                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2990                    intent.setComponent(new ComponentName(
2991                            ri.activityInfo.packageName, ri.activityInfo.name));
2992                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2993                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2994                }
2995            }
2996        }
2997    }
2998
2999    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3000        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3001    }
3002
3003    void enforceNotIsolatedCaller(String caller) {
3004        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3005            throw new SecurityException("Isolated process not allowed to call " + caller);
3006        }
3007    }
3008
3009    @Override
3010    public int getFrontActivityScreenCompatMode() {
3011        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3012        synchronized (this) {
3013            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3014        }
3015    }
3016
3017    @Override
3018    public void setFrontActivityScreenCompatMode(int mode) {
3019        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3020                "setFrontActivityScreenCompatMode");
3021        synchronized (this) {
3022            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3023        }
3024    }
3025
3026    @Override
3027    public int getPackageScreenCompatMode(String packageName) {
3028        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3029        synchronized (this) {
3030            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3031        }
3032    }
3033
3034    @Override
3035    public void setPackageScreenCompatMode(String packageName, int mode) {
3036        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3037                "setPackageScreenCompatMode");
3038        synchronized (this) {
3039            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3040        }
3041    }
3042
3043    @Override
3044    public boolean getPackageAskScreenCompat(String packageName) {
3045        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3046        synchronized (this) {
3047            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3048        }
3049    }
3050
3051    @Override
3052    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3053        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3054                "setPackageAskScreenCompat");
3055        synchronized (this) {
3056            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3057        }
3058    }
3059
3060    private void dispatchProcessesChanged() {
3061        int N;
3062        synchronized (this) {
3063            N = mPendingProcessChanges.size();
3064            if (mActiveProcessChanges.length < N) {
3065                mActiveProcessChanges = new ProcessChangeItem[N];
3066            }
3067            mPendingProcessChanges.toArray(mActiveProcessChanges);
3068            mAvailProcessChanges.addAll(mPendingProcessChanges);
3069            mPendingProcessChanges.clear();
3070            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3071        }
3072
3073        int i = mProcessObservers.beginBroadcast();
3074        while (i > 0) {
3075            i--;
3076            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3077            if (observer != null) {
3078                try {
3079                    for (int j=0; j<N; j++) {
3080                        ProcessChangeItem item = mActiveProcessChanges[j];
3081                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3082                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3083                                    + item.pid + " uid=" + item.uid + ": "
3084                                    + item.foregroundActivities);
3085                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3086                                    item.foregroundActivities);
3087                        }
3088                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3089                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3090                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3091                            observer.onImportanceChanged(item.pid, item.uid,
3092                                    item.importance);
3093                        }
3094                    }
3095                } catch (RemoteException e) {
3096                }
3097            }
3098        }
3099        mProcessObservers.finishBroadcast();
3100    }
3101
3102    private void dispatchProcessDied(int pid, int uid) {
3103        int i = mProcessObservers.beginBroadcast();
3104        while (i > 0) {
3105            i--;
3106            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3107            if (observer != null) {
3108                try {
3109                    observer.onProcessDied(pid, uid);
3110                } catch (RemoteException e) {
3111                }
3112            }
3113        }
3114        mProcessObservers.finishBroadcast();
3115    }
3116
3117    final void doPendingActivityLaunchesLocked(boolean doResume) {
3118        final int N = mPendingActivityLaunches.size();
3119        if (N <= 0) {
3120            return;
3121        }
3122        for (int i=0; i<N; i++) {
3123            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3124            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3125                    doResume && i == (N-1), null);
3126        }
3127        mPendingActivityLaunches.clear();
3128    }
3129
3130    @Override
3131    public final int startActivity(IApplicationThread caller, String callingPackage,
3132            Intent intent, String resolvedType, IBinder resultTo,
3133            String resultWho, int requestCode, int startFlags,
3134            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3135        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3136                resultWho, requestCode,
3137                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3138    }
3139
3140    @Override
3141    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3142            Intent intent, String resolvedType, IBinder resultTo,
3143            String resultWho, int requestCode, int startFlags,
3144            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3145        enforceNotIsolatedCaller("startActivity");
3146        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3147                false, true, "startActivity", null);
3148        // TODO: Switch to user app stacks here.
3149        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3150                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3151                null, null, options, userId, null);
3152    }
3153
3154    @Override
3155    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3156            Intent intent, String resolvedType, IBinder resultTo,
3157            String resultWho, int requestCode, int startFlags, String profileFile,
3158            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3159        enforceNotIsolatedCaller("startActivityAndWait");
3160        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3161                false, true, "startActivityAndWait", null);
3162        WaitResult res = new WaitResult();
3163        // TODO: Switch to user app stacks here.
3164        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3165                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3166                res, null, options, UserHandle.getCallingUserId(), null);
3167        return res;
3168    }
3169
3170    @Override
3171    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3172            Intent intent, String resolvedType, IBinder resultTo,
3173            String resultWho, int requestCode, int startFlags, Configuration config,
3174            Bundle options, int userId) {
3175        enforceNotIsolatedCaller("startActivityWithConfig");
3176        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3177                false, true, "startActivityWithConfig", null);
3178        // TODO: Switch to user app stacks here.
3179        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3180                resolvedType, resultTo, resultWho, requestCode, startFlags,
3181                null, null, null, config, options, userId, null);
3182        return ret;
3183    }
3184
3185    @Override
3186    public int startActivityIntentSender(IApplicationThread caller,
3187            IntentSender intent, Intent fillInIntent, String resolvedType,
3188            IBinder resultTo, String resultWho, int requestCode,
3189            int flagsMask, int flagsValues, Bundle options) {
3190        enforceNotIsolatedCaller("startActivityIntentSender");
3191        // Refuse possible leaked file descriptors
3192        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3193            throw new IllegalArgumentException("File descriptors passed in Intent");
3194        }
3195
3196        IIntentSender sender = intent.getTarget();
3197        if (!(sender instanceof PendingIntentRecord)) {
3198            throw new IllegalArgumentException("Bad PendingIntent object");
3199        }
3200
3201        PendingIntentRecord pir = (PendingIntentRecord)sender;
3202
3203        synchronized (this) {
3204            // If this is coming from the currently resumed activity, it is
3205            // effectively saying that app switches are allowed at this point.
3206            final ActivityStack stack = getFocusedStack();
3207            if (stack.mResumedActivity != null &&
3208                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3209                mAppSwitchesAllowedTime = 0;
3210            }
3211        }
3212        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3213                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3214        return ret;
3215    }
3216
3217    @Override
3218    public boolean startNextMatchingActivity(IBinder callingActivity,
3219            Intent intent, Bundle options) {
3220        // Refuse possible leaked file descriptors
3221        if (intent != null && intent.hasFileDescriptors() == true) {
3222            throw new IllegalArgumentException("File descriptors passed in Intent");
3223        }
3224
3225        synchronized (this) {
3226            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3227            if (r == null) {
3228                ActivityOptions.abort(options);
3229                return false;
3230            }
3231            if (r.app == null || r.app.thread == null) {
3232                // The caller is not running...  d'oh!
3233                ActivityOptions.abort(options);
3234                return false;
3235            }
3236            intent = new Intent(intent);
3237            // The caller is not allowed to change the data.
3238            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3239            // And we are resetting to find the next component...
3240            intent.setComponent(null);
3241
3242            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3243
3244            ActivityInfo aInfo = null;
3245            try {
3246                List<ResolveInfo> resolves =
3247                    AppGlobals.getPackageManager().queryIntentActivities(
3248                            intent, r.resolvedType,
3249                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3250                            UserHandle.getCallingUserId());
3251
3252                // Look for the original activity in the list...
3253                final int N = resolves != null ? resolves.size() : 0;
3254                for (int i=0; i<N; i++) {
3255                    ResolveInfo rInfo = resolves.get(i);
3256                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3257                            && rInfo.activityInfo.name.equals(r.info.name)) {
3258                        // We found the current one...  the next matching is
3259                        // after it.
3260                        i++;
3261                        if (i<N) {
3262                            aInfo = resolves.get(i).activityInfo;
3263                        }
3264                        if (debug) {
3265                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3266                                    + "/" + r.info.name);
3267                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3268                                    + "/" + aInfo.name);
3269                        }
3270                        break;
3271                    }
3272                }
3273            } catch (RemoteException e) {
3274            }
3275
3276            if (aInfo == null) {
3277                // Nobody who is next!
3278                ActivityOptions.abort(options);
3279                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3280                return false;
3281            }
3282
3283            intent.setComponent(new ComponentName(
3284                    aInfo.applicationInfo.packageName, aInfo.name));
3285            intent.setFlags(intent.getFlags()&~(
3286                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3287                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3288                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3289                    Intent.FLAG_ACTIVITY_NEW_TASK));
3290
3291            // Okay now we need to start the new activity, replacing the
3292            // currently running activity.  This is a little tricky because
3293            // we want to start the new one as if the current one is finished,
3294            // but not finish the current one first so that there is no flicker.
3295            // And thus...
3296            final boolean wasFinishing = r.finishing;
3297            r.finishing = true;
3298
3299            // Propagate reply information over to the new activity.
3300            final ActivityRecord resultTo = r.resultTo;
3301            final String resultWho = r.resultWho;
3302            final int requestCode = r.requestCode;
3303            r.resultTo = null;
3304            if (resultTo != null) {
3305                resultTo.removeResultsLocked(r, resultWho, requestCode);
3306            }
3307
3308            final long origId = Binder.clearCallingIdentity();
3309            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3310                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3311                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3312                    options, false, null, null);
3313            Binder.restoreCallingIdentity(origId);
3314
3315            r.finishing = wasFinishing;
3316            if (res != ActivityManager.START_SUCCESS) {
3317                return false;
3318            }
3319            return true;
3320        }
3321    }
3322
3323    final int startActivityInPackage(int uid, String callingPackage,
3324            Intent intent, String resolvedType, IBinder resultTo,
3325            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3326                    IActivityContainer container) {
3327
3328        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3329                false, true, "startActivityInPackage", null);
3330
3331        // TODO: Switch to user app stacks here.
3332        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3333                resultTo, resultWho, requestCode, startFlags,
3334                null, null, null, null, options, userId, container);
3335        return ret;
3336    }
3337
3338    @Override
3339    public final int startActivities(IApplicationThread caller, String callingPackage,
3340            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3341            int userId) {
3342        enforceNotIsolatedCaller("startActivities");
3343        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3344                false, true, "startActivity", null);
3345        // TODO: Switch to user app stacks here.
3346        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3347                resolvedTypes, resultTo, options, userId);
3348        return ret;
3349    }
3350
3351    final int startActivitiesInPackage(int uid, String callingPackage,
3352            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3353            Bundle options, int userId) {
3354
3355        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3356                false, true, "startActivityInPackage", null);
3357        // TODO: Switch to user app stacks here.
3358        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3359                resultTo, options, userId);
3360        return ret;
3361    }
3362
3363    final void addRecentTaskLocked(TaskRecord task) {
3364        int N = mRecentTasks.size();
3365        // Quick case: check if the top-most recent task is the same.
3366        if (N > 0 && mRecentTasks.get(0) == task) {
3367            return;
3368        }
3369        // Remove any existing entries that are the same kind of task.
3370        final Intent intent = task.intent;
3371        final boolean document = intent != null && intent.isDocument();
3372        for (int i=0; i<N; i++) {
3373            TaskRecord tr = mRecentTasks.get(i);
3374            if (task != tr) {
3375                if (task.userId != tr.userId) {
3376                    continue;
3377                }
3378                final Intent trIntent = tr.intent;
3379                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3380                    (intent == null || !intent.filterEquals(trIntent))) {
3381                    continue;
3382                }
3383                if (document || trIntent != null && trIntent.isDocument()) {
3384                    // Document tasks do not match other tasks.
3385                    continue;
3386                }
3387            }
3388
3389            // Either task and tr are the same or, their affinities match or their intents match
3390            // and neither of them is a document.
3391            tr.disposeThumbnail();
3392            mRecentTasks.remove(i);
3393            i--;
3394            N--;
3395            if (task.intent == null) {
3396                // If the new recent task we are adding is not fully
3397                // specified, then replace it with the existing recent task.
3398                task = tr;
3399            }
3400        }
3401        if (N >= MAX_RECENT_TASKS) {
3402            mRecentTasks.remove(N-1).disposeThumbnail();
3403        }
3404        mRecentTasks.add(0, task);
3405    }
3406
3407    @Override
3408    public void reportActivityFullyDrawn(IBinder token) {
3409        synchronized (this) {
3410            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3411            if (r == null) {
3412                return;
3413            }
3414            r.reportFullyDrawnLocked();
3415        }
3416    }
3417
3418    @Override
3419    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3420        synchronized (this) {
3421            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3422            if (r == null) {
3423                return;
3424            }
3425            final long origId = Binder.clearCallingIdentity();
3426            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3427            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3428                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3429            if (config != null) {
3430                r.frozenBeforeDestroy = true;
3431                if (!updateConfigurationLocked(config, r, false, false)) {
3432                    mStackSupervisor.resumeTopActivitiesLocked();
3433                }
3434            }
3435            Binder.restoreCallingIdentity(origId);
3436        }
3437    }
3438
3439    @Override
3440    public int getRequestedOrientation(IBinder token) {
3441        synchronized (this) {
3442            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3443            if (r == null) {
3444                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3445            }
3446            return mWindowManager.getAppOrientation(r.appToken);
3447        }
3448    }
3449
3450    /**
3451     * This is the internal entry point for handling Activity.finish().
3452     *
3453     * @param token The Binder token referencing the Activity we want to finish.
3454     * @param resultCode Result code, if any, from this Activity.
3455     * @param resultData Result data (Intent), if any, from this Activity.
3456     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3457     *            the root Activity in the task.
3458     *
3459     * @return Returns true if the activity successfully finished, or false if it is still running.
3460     */
3461    @Override
3462    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3463            boolean finishTask) {
3464        // Refuse possible leaked file descriptors
3465        if (resultData != null && resultData.hasFileDescriptors() == true) {
3466            throw new IllegalArgumentException("File descriptors passed in Intent");
3467        }
3468
3469        synchronized(this) {
3470            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3471            if (r == null) {
3472                return true;
3473            }
3474            // Keep track of the root activity of the task before we finish it
3475            TaskRecord tr = r.task;
3476            ActivityRecord rootR = tr.getRootActivity();
3477            if (mController != null) {
3478                // Find the first activity that is not finishing.
3479                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3480                if (next != null) {
3481                    // ask watcher if this is allowed
3482                    boolean resumeOK = true;
3483                    try {
3484                        resumeOK = mController.activityResuming(next.packageName);
3485                    } catch (RemoteException e) {
3486                        mController = null;
3487                        Watchdog.getInstance().setActivityController(null);
3488                    }
3489
3490                    if (!resumeOK) {
3491                        return false;
3492                    }
3493                }
3494            }
3495            final long origId = Binder.clearCallingIdentity();
3496            try {
3497                boolean res;
3498                if (finishTask && r == rootR) {
3499                    // If requested, remove the task that is associated to this activity only if it
3500                    // was the root activity in the task.  The result code and data is ignored because
3501                    // we don't support returning them across task boundaries.
3502                    res = removeTaskByIdLocked(tr.taskId, 0);
3503                } else {
3504                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3505                            resultData, "app-request", true);
3506                }
3507                return res;
3508            } finally {
3509                Binder.restoreCallingIdentity(origId);
3510            }
3511        }
3512    }
3513
3514    @Override
3515    public final void finishHeavyWeightApp() {
3516        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3517                != PackageManager.PERMISSION_GRANTED) {
3518            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3519                    + Binder.getCallingPid()
3520                    + ", uid=" + Binder.getCallingUid()
3521                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3522            Slog.w(TAG, msg);
3523            throw new SecurityException(msg);
3524        }
3525
3526        synchronized(this) {
3527            if (mHeavyWeightProcess == null) {
3528                return;
3529            }
3530
3531            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3532                    mHeavyWeightProcess.activities);
3533            for (int i=0; i<activities.size(); i++) {
3534                ActivityRecord r = activities.get(i);
3535                if (!r.finishing) {
3536                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3537                            null, "finish-heavy", true);
3538                }
3539            }
3540
3541            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3542                    mHeavyWeightProcess.userId, 0));
3543            mHeavyWeightProcess = null;
3544        }
3545    }
3546
3547    @Override
3548    public void crashApplication(int uid, int initialPid, String packageName,
3549            String message) {
3550        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3551                != PackageManager.PERMISSION_GRANTED) {
3552            String msg = "Permission Denial: crashApplication() from pid="
3553                    + Binder.getCallingPid()
3554                    + ", uid=" + Binder.getCallingUid()
3555                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3556            Slog.w(TAG, msg);
3557            throw new SecurityException(msg);
3558        }
3559
3560        synchronized(this) {
3561            ProcessRecord proc = null;
3562
3563            // Figure out which process to kill.  We don't trust that initialPid
3564            // still has any relation to current pids, so must scan through the
3565            // list.
3566            synchronized (mPidsSelfLocked) {
3567                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3568                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3569                    if (p.uid != uid) {
3570                        continue;
3571                    }
3572                    if (p.pid == initialPid) {
3573                        proc = p;
3574                        break;
3575                    }
3576                    if (p.pkgList.containsKey(packageName)) {
3577                        proc = p;
3578                    }
3579                }
3580            }
3581
3582            if (proc == null) {
3583                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3584                        + " initialPid=" + initialPid
3585                        + " packageName=" + packageName);
3586                return;
3587            }
3588
3589            if (proc.thread != null) {
3590                if (proc.pid == Process.myPid()) {
3591                    Log.w(TAG, "crashApplication: trying to crash self!");
3592                    return;
3593                }
3594                long ident = Binder.clearCallingIdentity();
3595                try {
3596                    proc.thread.scheduleCrash(message);
3597                } catch (RemoteException e) {
3598                }
3599                Binder.restoreCallingIdentity(ident);
3600            }
3601        }
3602    }
3603
3604    @Override
3605    public final void finishSubActivity(IBinder token, String resultWho,
3606            int requestCode) {
3607        synchronized(this) {
3608            final long origId = Binder.clearCallingIdentity();
3609            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3610            if (r != null) {
3611                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3612            }
3613            Binder.restoreCallingIdentity(origId);
3614        }
3615    }
3616
3617    @Override
3618    public boolean finishActivityAffinity(IBinder token) {
3619        synchronized(this) {
3620            final long origId = Binder.clearCallingIdentity();
3621            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3622            boolean res = false;
3623            if (r != null) {
3624                res = r.task.stack.finishActivityAffinityLocked(r);
3625            }
3626            Binder.restoreCallingIdentity(origId);
3627            return res;
3628        }
3629    }
3630
3631    @Override
3632    public boolean willActivityBeVisible(IBinder token) {
3633        synchronized(this) {
3634            ActivityStack stack = ActivityRecord.getStackLocked(token);
3635            if (stack != null) {
3636                return stack.willActivityBeVisibleLocked(token);
3637            }
3638            return false;
3639        }
3640    }
3641
3642    @Override
3643    public void overridePendingTransition(IBinder token, String packageName,
3644            int enterAnim, int exitAnim) {
3645        synchronized(this) {
3646            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3647            if (self == null) {
3648                return;
3649            }
3650
3651            final long origId = Binder.clearCallingIdentity();
3652
3653            if (self.state == ActivityState.RESUMED
3654                    || self.state == ActivityState.PAUSING) {
3655                mWindowManager.overridePendingAppTransition(packageName,
3656                        enterAnim, exitAnim, null);
3657            }
3658
3659            Binder.restoreCallingIdentity(origId);
3660        }
3661    }
3662
3663    /**
3664     * Main function for removing an existing process from the activity manager
3665     * as a result of that process going away.  Clears out all connections
3666     * to the process.
3667     */
3668    private final void handleAppDiedLocked(ProcessRecord app,
3669            boolean restarting, boolean allowRestart) {
3670        int pid = app.pid;
3671        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3672        if (!restarting) {
3673            removeLruProcessLocked(app);
3674            if (pid > 0) {
3675                ProcessList.remove(pid);
3676            }
3677        }
3678
3679        if (mProfileProc == app) {
3680            clearProfilerLocked();
3681        }
3682
3683        // Remove this application's activities from active lists.
3684        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3685
3686        app.activities.clear();
3687
3688        if (app.instrumentationClass != null) {
3689            Slog.w(TAG, "Crash of app " + app.processName
3690                  + " running instrumentation " + app.instrumentationClass);
3691            Bundle info = new Bundle();
3692            info.putString("shortMsg", "Process crashed.");
3693            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3694        }
3695
3696        if (!restarting) {
3697            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3698                // If there was nothing to resume, and we are not already
3699                // restarting this process, but there is a visible activity that
3700                // is hosted by the process...  then make sure all visible
3701                // activities are running, taking care of restarting this
3702                // process.
3703                if (hasVisibleActivities) {
3704                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3705                }
3706            }
3707        }
3708    }
3709
3710    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3711        IBinder threadBinder = thread.asBinder();
3712        // Find the application record.
3713        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3714            ProcessRecord rec = mLruProcesses.get(i);
3715            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3716                return i;
3717            }
3718        }
3719        return -1;
3720    }
3721
3722    final ProcessRecord getRecordForAppLocked(
3723            IApplicationThread thread) {
3724        if (thread == null) {
3725            return null;
3726        }
3727
3728        int appIndex = getLRURecordIndexForAppLocked(thread);
3729        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3730    }
3731
3732    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3733        // If there are no longer any background processes running,
3734        // and the app that died was not running instrumentation,
3735        // then tell everyone we are now low on memory.
3736        boolean haveBg = false;
3737        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3738            ProcessRecord rec = mLruProcesses.get(i);
3739            if (rec.thread != null
3740                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3741                haveBg = true;
3742                break;
3743            }
3744        }
3745
3746        if (!haveBg) {
3747            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3748            if (doReport) {
3749                long now = SystemClock.uptimeMillis();
3750                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3751                    doReport = false;
3752                } else {
3753                    mLastMemUsageReportTime = now;
3754                }
3755            }
3756            final ArrayList<ProcessMemInfo> memInfos
3757                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3758            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3759            long now = SystemClock.uptimeMillis();
3760            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3761                ProcessRecord rec = mLruProcesses.get(i);
3762                if (rec == dyingProc || rec.thread == null) {
3763                    continue;
3764                }
3765                if (doReport) {
3766                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3767                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3768                }
3769                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3770                    // The low memory report is overriding any current
3771                    // state for a GC request.  Make sure to do
3772                    // heavy/important/visible/foreground processes first.
3773                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3774                        rec.lastRequestedGc = 0;
3775                    } else {
3776                        rec.lastRequestedGc = rec.lastLowMemory;
3777                    }
3778                    rec.reportLowMemory = true;
3779                    rec.lastLowMemory = now;
3780                    mProcessesToGc.remove(rec);
3781                    addProcessToGcListLocked(rec);
3782                }
3783            }
3784            if (doReport) {
3785                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3786                mHandler.sendMessage(msg);
3787            }
3788            scheduleAppGcsLocked();
3789        }
3790    }
3791
3792    final void appDiedLocked(ProcessRecord app, int pid,
3793            IApplicationThread thread) {
3794
3795        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3796        synchronized (stats) {
3797            stats.noteProcessDiedLocked(app.info.uid, pid);
3798        }
3799
3800        // Clean up already done if the process has been re-started.
3801        if (app.pid == pid && app.thread != null &&
3802                app.thread.asBinder() == thread.asBinder()) {
3803            boolean doLowMem = app.instrumentationClass == null;
3804            boolean doOomAdj = doLowMem;
3805            if (!app.killedByAm) {
3806                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3807                        + ") has died.");
3808                mAllowLowerMemLevel = true;
3809            } else {
3810                // Note that we always want to do oom adj to update our state with the
3811                // new number of procs.
3812                mAllowLowerMemLevel = false;
3813                doLowMem = false;
3814            }
3815            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3816            if (DEBUG_CLEANUP) Slog.v(
3817                TAG, "Dying app: " + app + ", pid: " + pid
3818                + ", thread: " + thread.asBinder());
3819            handleAppDiedLocked(app, false, true);
3820
3821            if (doOomAdj) {
3822                updateOomAdjLocked();
3823            }
3824            if (doLowMem) {
3825                doLowMemReportIfNeededLocked(app);
3826            }
3827        } else if (app.pid != pid) {
3828            // A new process has already been started.
3829            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3830                    + ") has died and restarted (pid " + app.pid + ").");
3831            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3832        } else if (DEBUG_PROCESSES) {
3833            Slog.d(TAG, "Received spurious death notification for thread "
3834                    + thread.asBinder());
3835        }
3836    }
3837
3838    /**
3839     * If a stack trace dump file is configured, dump process stack traces.
3840     * @param clearTraces causes the dump file to be erased prior to the new
3841     *    traces being written, if true; when false, the new traces will be
3842     *    appended to any existing file content.
3843     * @param firstPids of dalvik VM processes to dump stack traces for first
3844     * @param lastPids of dalvik VM processes to dump stack traces for last
3845     * @param nativeProcs optional list of native process names to dump stack crawls
3846     * @return file containing stack traces, or null if no dump file is configured
3847     */
3848    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3849            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3850        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3851        if (tracesPath == null || tracesPath.length() == 0) {
3852            return null;
3853        }
3854
3855        File tracesFile = new File(tracesPath);
3856        try {
3857            File tracesDir = tracesFile.getParentFile();
3858            if (!tracesDir.exists()) {
3859                tracesFile.mkdirs();
3860                if (!SELinux.restorecon(tracesDir)) {
3861                    return null;
3862                }
3863            }
3864            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3865
3866            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3867            tracesFile.createNewFile();
3868            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3869        } catch (IOException e) {
3870            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3871            return null;
3872        }
3873
3874        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3875        return tracesFile;
3876    }
3877
3878    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3879            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3880        // Use a FileObserver to detect when traces finish writing.
3881        // The order of traces is considered important to maintain for legibility.
3882        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3883            @Override
3884            public synchronized void onEvent(int event, String path) { notify(); }
3885        };
3886
3887        try {
3888            observer.startWatching();
3889
3890            // First collect all of the stacks of the most important pids.
3891            if (firstPids != null) {
3892                try {
3893                    int num = firstPids.size();
3894                    for (int i = 0; i < num; i++) {
3895                        synchronized (observer) {
3896                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3897                            observer.wait(200);  // Wait for write-close, give up after 200msec
3898                        }
3899                    }
3900                } catch (InterruptedException e) {
3901                    Log.wtf(TAG, e);
3902                }
3903            }
3904
3905            // Next collect the stacks of the native pids
3906            if (nativeProcs != null) {
3907                int[] pids = Process.getPidsForCommands(nativeProcs);
3908                if (pids != null) {
3909                    for (int pid : pids) {
3910                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3911                    }
3912                }
3913            }
3914
3915            // Lastly, measure CPU usage.
3916            if (processCpuTracker != null) {
3917                processCpuTracker.init();
3918                System.gc();
3919                processCpuTracker.update();
3920                try {
3921                    synchronized (processCpuTracker) {
3922                        processCpuTracker.wait(500); // measure over 1/2 second.
3923                    }
3924                } catch (InterruptedException e) {
3925                }
3926                processCpuTracker.update();
3927
3928                // We'll take the stack crawls of just the top apps using CPU.
3929                final int N = processCpuTracker.countWorkingStats();
3930                int numProcs = 0;
3931                for (int i=0; i<N && numProcs<5; i++) {
3932                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3933                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3934                        numProcs++;
3935                        try {
3936                            synchronized (observer) {
3937                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3938                                observer.wait(200);  // Wait for write-close, give up after 200msec
3939                            }
3940                        } catch (InterruptedException e) {
3941                            Log.wtf(TAG, e);
3942                        }
3943
3944                    }
3945                }
3946            }
3947        } finally {
3948            observer.stopWatching();
3949        }
3950    }
3951
3952    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3953        if (true || IS_USER_BUILD) {
3954            return;
3955        }
3956        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3957        if (tracesPath == null || tracesPath.length() == 0) {
3958            return;
3959        }
3960
3961        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3962        StrictMode.allowThreadDiskWrites();
3963        try {
3964            final File tracesFile = new File(tracesPath);
3965            final File tracesDir = tracesFile.getParentFile();
3966            final File tracesTmp = new File(tracesDir, "__tmp__");
3967            try {
3968                if (!tracesDir.exists()) {
3969                    tracesFile.mkdirs();
3970                    if (!SELinux.restorecon(tracesDir.getPath())) {
3971                        return;
3972                    }
3973                }
3974                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3975
3976                if (tracesFile.exists()) {
3977                    tracesTmp.delete();
3978                    tracesFile.renameTo(tracesTmp);
3979                }
3980                StringBuilder sb = new StringBuilder();
3981                Time tobj = new Time();
3982                tobj.set(System.currentTimeMillis());
3983                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3984                sb.append(": ");
3985                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3986                sb.append(" since ");
3987                sb.append(msg);
3988                FileOutputStream fos = new FileOutputStream(tracesFile);
3989                fos.write(sb.toString().getBytes());
3990                if (app == null) {
3991                    fos.write("\n*** No application process!".getBytes());
3992                }
3993                fos.close();
3994                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3995            } catch (IOException e) {
3996                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3997                return;
3998            }
3999
4000            if (app != null) {
4001                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4002                firstPids.add(app.pid);
4003                dumpStackTraces(tracesPath, firstPids, null, null, null);
4004            }
4005
4006            File lastTracesFile = null;
4007            File curTracesFile = null;
4008            for (int i=9; i>=0; i--) {
4009                String name = String.format(Locale.US, "slow%02d.txt", i);
4010                curTracesFile = new File(tracesDir, name);
4011                if (curTracesFile.exists()) {
4012                    if (lastTracesFile != null) {
4013                        curTracesFile.renameTo(lastTracesFile);
4014                    } else {
4015                        curTracesFile.delete();
4016                    }
4017                }
4018                lastTracesFile = curTracesFile;
4019            }
4020            tracesFile.renameTo(curTracesFile);
4021            if (tracesTmp.exists()) {
4022                tracesTmp.renameTo(tracesFile);
4023            }
4024        } finally {
4025            StrictMode.setThreadPolicy(oldPolicy);
4026        }
4027    }
4028
4029    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4030            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4031        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4032        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4033
4034        if (mController != null) {
4035            try {
4036                // 0 == continue, -1 = kill process immediately
4037                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4038                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4039            } catch (RemoteException e) {
4040                mController = null;
4041                Watchdog.getInstance().setActivityController(null);
4042            }
4043        }
4044
4045        long anrTime = SystemClock.uptimeMillis();
4046        if (MONITOR_CPU_USAGE) {
4047            updateCpuStatsNow();
4048        }
4049
4050        synchronized (this) {
4051            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4052            if (mShuttingDown) {
4053                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4054                return;
4055            } else if (app.notResponding) {
4056                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4057                return;
4058            } else if (app.crashing) {
4059                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4060                return;
4061            }
4062
4063            // In case we come through here for the same app before completing
4064            // this one, mark as anring now so we will bail out.
4065            app.notResponding = true;
4066
4067            // Log the ANR to the event log.
4068            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4069                    app.processName, app.info.flags, annotation);
4070
4071            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4072            firstPids.add(app.pid);
4073
4074            int parentPid = app.pid;
4075            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4076            if (parentPid != app.pid) firstPids.add(parentPid);
4077
4078            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4079
4080            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4081                ProcessRecord r = mLruProcesses.get(i);
4082                if (r != null && r.thread != null) {
4083                    int pid = r.pid;
4084                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4085                        if (r.persistent) {
4086                            firstPids.add(pid);
4087                        } else {
4088                            lastPids.put(pid, Boolean.TRUE);
4089                        }
4090                    }
4091                }
4092            }
4093        }
4094
4095        // Log the ANR to the main log.
4096        StringBuilder info = new StringBuilder();
4097        info.setLength(0);
4098        info.append("ANR in ").append(app.processName);
4099        if (activity != null && activity.shortComponentName != null) {
4100            info.append(" (").append(activity.shortComponentName).append(")");
4101        }
4102        info.append("\n");
4103        info.append("PID: ").append(app.pid).append("\n");
4104        if (annotation != null) {
4105            info.append("Reason: ").append(annotation).append("\n");
4106        }
4107        if (parent != null && parent != activity) {
4108            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4109        }
4110
4111        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4112
4113        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4114                NATIVE_STACKS_OF_INTEREST);
4115
4116        String cpuInfo = null;
4117        if (MONITOR_CPU_USAGE) {
4118            updateCpuStatsNow();
4119            synchronized (mProcessCpuThread) {
4120                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4121            }
4122            info.append(processCpuTracker.printCurrentLoad());
4123            info.append(cpuInfo);
4124        }
4125
4126        info.append(processCpuTracker.printCurrentState(anrTime));
4127
4128        Slog.e(TAG, info.toString());
4129        if (tracesFile == null) {
4130            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4131            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4132        }
4133
4134        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4135                cpuInfo, tracesFile, null);
4136
4137        if (mController != null) {
4138            try {
4139                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4140                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4141                if (res != 0) {
4142                    if (res < 0 && app.pid != MY_PID) {
4143                        Process.killProcess(app.pid);
4144                    } else {
4145                        synchronized (this) {
4146                            mServices.scheduleServiceTimeoutLocked(app);
4147                        }
4148                    }
4149                    return;
4150                }
4151            } catch (RemoteException e) {
4152                mController = null;
4153                Watchdog.getInstance().setActivityController(null);
4154            }
4155        }
4156
4157        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4158        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4159                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4160
4161        synchronized (this) {
4162            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4163                killUnneededProcessLocked(app, "background ANR");
4164                return;
4165            }
4166
4167            // Set the app's notResponding state, and look up the errorReportReceiver
4168            makeAppNotRespondingLocked(app,
4169                    activity != null ? activity.shortComponentName : null,
4170                    annotation != null ? "ANR " + annotation : "ANR",
4171                    info.toString());
4172
4173            // Bring up the infamous App Not Responding dialog
4174            Message msg = Message.obtain();
4175            HashMap<String, Object> map = new HashMap<String, Object>();
4176            msg.what = SHOW_NOT_RESPONDING_MSG;
4177            msg.obj = map;
4178            msg.arg1 = aboveSystem ? 1 : 0;
4179            map.put("app", app);
4180            if (activity != null) {
4181                map.put("activity", activity);
4182            }
4183
4184            mHandler.sendMessage(msg);
4185        }
4186    }
4187
4188    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4189        if (!mLaunchWarningShown) {
4190            mLaunchWarningShown = true;
4191            mHandler.post(new Runnable() {
4192                @Override
4193                public void run() {
4194                    synchronized (ActivityManagerService.this) {
4195                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4196                        d.show();
4197                        mHandler.postDelayed(new Runnable() {
4198                            @Override
4199                            public void run() {
4200                                synchronized (ActivityManagerService.this) {
4201                                    d.dismiss();
4202                                    mLaunchWarningShown = false;
4203                                }
4204                            }
4205                        }, 4000);
4206                    }
4207                }
4208            });
4209        }
4210    }
4211
4212    @Override
4213    public boolean clearApplicationUserData(final String packageName,
4214            final IPackageDataObserver observer, int userId) {
4215        enforceNotIsolatedCaller("clearApplicationUserData");
4216        int uid = Binder.getCallingUid();
4217        int pid = Binder.getCallingPid();
4218        userId = handleIncomingUser(pid, uid,
4219                userId, false, true, "clearApplicationUserData", null);
4220        long callingId = Binder.clearCallingIdentity();
4221        try {
4222            IPackageManager pm = AppGlobals.getPackageManager();
4223            int pkgUid = -1;
4224            synchronized(this) {
4225                try {
4226                    pkgUid = pm.getPackageUid(packageName, userId);
4227                } catch (RemoteException e) {
4228                }
4229                if (pkgUid == -1) {
4230                    Slog.w(TAG, "Invalid packageName: " + packageName);
4231                    if (observer != null) {
4232                        try {
4233                            observer.onRemoveCompleted(packageName, false);
4234                        } catch (RemoteException e) {
4235                            Slog.i(TAG, "Observer no longer exists.");
4236                        }
4237                    }
4238                    return false;
4239                }
4240                if (uid == pkgUid || checkComponentPermission(
4241                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4242                        pid, uid, -1, true)
4243                        == PackageManager.PERMISSION_GRANTED) {
4244                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4245                } else {
4246                    throw new SecurityException("PID " + pid + " does not have permission "
4247                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4248                                    + " of package " + packageName);
4249                }
4250            }
4251
4252            try {
4253                // Clear application user data
4254                pm.clearApplicationUserData(packageName, observer, userId);
4255
4256                // Remove all permissions granted from/to this package
4257                removeUriPermissionsForPackageLocked(packageName, userId, true);
4258
4259                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4260                        Uri.fromParts("package", packageName, null));
4261                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4262                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4263                        null, null, 0, null, null, null, false, false, userId);
4264            } catch (RemoteException e) {
4265            }
4266        } finally {
4267            Binder.restoreCallingIdentity(callingId);
4268        }
4269        return true;
4270    }
4271
4272    @Override
4273    public void killBackgroundProcesses(final String packageName, int userId) {
4274        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4275                != PackageManager.PERMISSION_GRANTED &&
4276                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4277                        != PackageManager.PERMISSION_GRANTED) {
4278            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4279                    + Binder.getCallingPid()
4280                    + ", uid=" + Binder.getCallingUid()
4281                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4282            Slog.w(TAG, msg);
4283            throw new SecurityException(msg);
4284        }
4285
4286        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4287                userId, true, true, "killBackgroundProcesses", null);
4288        long callingId = Binder.clearCallingIdentity();
4289        try {
4290            IPackageManager pm = AppGlobals.getPackageManager();
4291            synchronized(this) {
4292                int appId = -1;
4293                try {
4294                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4295                } catch (RemoteException e) {
4296                }
4297                if (appId == -1) {
4298                    Slog.w(TAG, "Invalid packageName: " + packageName);
4299                    return;
4300                }
4301                killPackageProcessesLocked(packageName, appId, userId,
4302                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4303            }
4304        } finally {
4305            Binder.restoreCallingIdentity(callingId);
4306        }
4307    }
4308
4309    @Override
4310    public void killAllBackgroundProcesses() {
4311        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4312                != PackageManager.PERMISSION_GRANTED) {
4313            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4314                    + Binder.getCallingPid()
4315                    + ", uid=" + Binder.getCallingUid()
4316                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4317            Slog.w(TAG, msg);
4318            throw new SecurityException(msg);
4319        }
4320
4321        long callingId = Binder.clearCallingIdentity();
4322        try {
4323            synchronized(this) {
4324                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4325                final int NP = mProcessNames.getMap().size();
4326                for (int ip=0; ip<NP; ip++) {
4327                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4328                    final int NA = apps.size();
4329                    for (int ia=0; ia<NA; ia++) {
4330                        ProcessRecord app = apps.valueAt(ia);
4331                        if (app.persistent) {
4332                            // we don't kill persistent processes
4333                            continue;
4334                        }
4335                        if (app.removed) {
4336                            procs.add(app);
4337                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4338                            app.removed = true;
4339                            procs.add(app);
4340                        }
4341                    }
4342                }
4343
4344                int N = procs.size();
4345                for (int i=0; i<N; i++) {
4346                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4347                }
4348                mAllowLowerMemLevel = true;
4349                updateOomAdjLocked();
4350                doLowMemReportIfNeededLocked(null);
4351            }
4352        } finally {
4353            Binder.restoreCallingIdentity(callingId);
4354        }
4355    }
4356
4357    @Override
4358    public void forceStopPackage(final String packageName, int userId) {
4359        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4360                != PackageManager.PERMISSION_GRANTED) {
4361            String msg = "Permission Denial: forceStopPackage() from pid="
4362                    + Binder.getCallingPid()
4363                    + ", uid=" + Binder.getCallingUid()
4364                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4365            Slog.w(TAG, msg);
4366            throw new SecurityException(msg);
4367        }
4368        final int callingPid = Binder.getCallingPid();
4369        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4370                userId, true, true, "forceStopPackage", null);
4371        long callingId = Binder.clearCallingIdentity();
4372        try {
4373            IPackageManager pm = AppGlobals.getPackageManager();
4374            synchronized(this) {
4375                int[] users = userId == UserHandle.USER_ALL
4376                        ? getUsersLocked() : new int[] { userId };
4377                for (int user : users) {
4378                    int pkgUid = -1;
4379                    try {
4380                        pkgUid = pm.getPackageUid(packageName, user);
4381                    } catch (RemoteException e) {
4382                    }
4383                    if (pkgUid == -1) {
4384                        Slog.w(TAG, "Invalid packageName: " + packageName);
4385                        continue;
4386                    }
4387                    try {
4388                        pm.setPackageStoppedState(packageName, true, user);
4389                    } catch (RemoteException e) {
4390                    } catch (IllegalArgumentException e) {
4391                        Slog.w(TAG, "Failed trying to unstop package "
4392                                + packageName + ": " + e);
4393                    }
4394                    if (isUserRunningLocked(user, false)) {
4395                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4396                    }
4397                }
4398            }
4399        } finally {
4400            Binder.restoreCallingIdentity(callingId);
4401        }
4402    }
4403
4404    /*
4405     * The pkg name and app id have to be specified.
4406     */
4407    @Override
4408    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4409        if (pkg == null) {
4410            return;
4411        }
4412        // Make sure the uid is valid.
4413        if (appid < 0) {
4414            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4415            return;
4416        }
4417        int callerUid = Binder.getCallingUid();
4418        // Only the system server can kill an application
4419        if (callerUid == Process.SYSTEM_UID) {
4420            // Post an aysnc message to kill the application
4421            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4422            msg.arg1 = appid;
4423            msg.arg2 = 0;
4424            Bundle bundle = new Bundle();
4425            bundle.putString("pkg", pkg);
4426            bundle.putString("reason", reason);
4427            msg.obj = bundle;
4428            mHandler.sendMessage(msg);
4429        } else {
4430            throw new SecurityException(callerUid + " cannot kill pkg: " +
4431                    pkg);
4432        }
4433    }
4434
4435    @Override
4436    public void closeSystemDialogs(String reason) {
4437        enforceNotIsolatedCaller("closeSystemDialogs");
4438
4439        final int pid = Binder.getCallingPid();
4440        final int uid = Binder.getCallingUid();
4441        final long origId = Binder.clearCallingIdentity();
4442        try {
4443            synchronized (this) {
4444                // Only allow this from foreground processes, so that background
4445                // applications can't abuse it to prevent system UI from being shown.
4446                if (uid >= Process.FIRST_APPLICATION_UID) {
4447                    ProcessRecord proc;
4448                    synchronized (mPidsSelfLocked) {
4449                        proc = mPidsSelfLocked.get(pid);
4450                    }
4451                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4452                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4453                                + " from background process " + proc);
4454                        return;
4455                    }
4456                }
4457                closeSystemDialogsLocked(reason);
4458            }
4459        } finally {
4460            Binder.restoreCallingIdentity(origId);
4461        }
4462    }
4463
4464    void closeSystemDialogsLocked(String reason) {
4465        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4466        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4467                | Intent.FLAG_RECEIVER_FOREGROUND);
4468        if (reason != null) {
4469            intent.putExtra("reason", reason);
4470        }
4471        mWindowManager.closeSystemDialogs(reason);
4472
4473        mStackSupervisor.closeSystemDialogsLocked();
4474
4475        broadcastIntentLocked(null, null, intent, null,
4476                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4477                Process.SYSTEM_UID, UserHandle.USER_ALL);
4478    }
4479
4480    @Override
4481    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4482        enforceNotIsolatedCaller("getProcessMemoryInfo");
4483        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4484        for (int i=pids.length-1; i>=0; i--) {
4485            ProcessRecord proc;
4486            int oomAdj;
4487            synchronized (this) {
4488                synchronized (mPidsSelfLocked) {
4489                    proc = mPidsSelfLocked.get(pids[i]);
4490                    oomAdj = proc != null ? proc.setAdj : 0;
4491                }
4492            }
4493            infos[i] = new Debug.MemoryInfo();
4494            Debug.getMemoryInfo(pids[i], infos[i]);
4495            if (proc != null) {
4496                synchronized (this) {
4497                    if (proc.thread != null && proc.setAdj == oomAdj) {
4498                        // Record this for posterity if the process has been stable.
4499                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4500                                infos[i].getTotalUss(), false, proc.pkgList);
4501                    }
4502                }
4503            }
4504        }
4505        return infos;
4506    }
4507
4508    @Override
4509    public long[] getProcessPss(int[] pids) {
4510        enforceNotIsolatedCaller("getProcessPss");
4511        long[] pss = new long[pids.length];
4512        for (int i=pids.length-1; i>=0; i--) {
4513            ProcessRecord proc;
4514            int oomAdj;
4515            synchronized (this) {
4516                synchronized (mPidsSelfLocked) {
4517                    proc = mPidsSelfLocked.get(pids[i]);
4518                    oomAdj = proc != null ? proc.setAdj : 0;
4519                }
4520            }
4521            long[] tmpUss = new long[1];
4522            pss[i] = Debug.getPss(pids[i], tmpUss);
4523            if (proc != null) {
4524                synchronized (this) {
4525                    if (proc.thread != null && proc.setAdj == oomAdj) {
4526                        // Record this for posterity if the process has been stable.
4527                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4528                    }
4529                }
4530            }
4531        }
4532        return pss;
4533    }
4534
4535    @Override
4536    public void killApplicationProcess(String processName, int uid) {
4537        if (processName == null) {
4538            return;
4539        }
4540
4541        int callerUid = Binder.getCallingUid();
4542        // Only the system server can kill an application
4543        if (callerUid == Process.SYSTEM_UID) {
4544            synchronized (this) {
4545                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4546                if (app != null && app.thread != null) {
4547                    try {
4548                        app.thread.scheduleSuicide();
4549                    } catch (RemoteException e) {
4550                        // If the other end already died, then our work here is done.
4551                    }
4552                } else {
4553                    Slog.w(TAG, "Process/uid not found attempting kill of "
4554                            + processName + " / " + uid);
4555                }
4556            }
4557        } else {
4558            throw new SecurityException(callerUid + " cannot kill app process: " +
4559                    processName);
4560        }
4561    }
4562
4563    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4564        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4565                false, true, false, false, UserHandle.getUserId(uid), reason);
4566        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4567                Uri.fromParts("package", packageName, null));
4568        if (!mProcessesReady) {
4569            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4570                    | Intent.FLAG_RECEIVER_FOREGROUND);
4571        }
4572        intent.putExtra(Intent.EXTRA_UID, uid);
4573        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4574        broadcastIntentLocked(null, null, intent,
4575                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4576                false, false,
4577                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4578    }
4579
4580    private void forceStopUserLocked(int userId, String reason) {
4581        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4582        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4583        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4584                | Intent.FLAG_RECEIVER_FOREGROUND);
4585        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4586        broadcastIntentLocked(null, null, intent,
4587                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4588                false, false,
4589                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4590    }
4591
4592    private final boolean killPackageProcessesLocked(String packageName, int appId,
4593            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4594            boolean doit, boolean evenPersistent, String reason) {
4595        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4596
4597        // Remove all processes this package may have touched: all with the
4598        // same UID (except for the system or root user), and all whose name
4599        // matches the package name.
4600        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4601        final int NP = mProcessNames.getMap().size();
4602        for (int ip=0; ip<NP; ip++) {
4603            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4604            final int NA = apps.size();
4605            for (int ia=0; ia<NA; ia++) {
4606                ProcessRecord app = apps.valueAt(ia);
4607                if (app.persistent && !evenPersistent) {
4608                    // we don't kill persistent processes
4609                    continue;
4610                }
4611                if (app.removed) {
4612                    if (doit) {
4613                        procs.add(app);
4614                    }
4615                    continue;
4616                }
4617
4618                // Skip process if it doesn't meet our oom adj requirement.
4619                if (app.setAdj < minOomAdj) {
4620                    continue;
4621                }
4622
4623                // If no package is specified, we call all processes under the
4624                // give user id.
4625                if (packageName == null) {
4626                    if (app.userId != userId) {
4627                        continue;
4628                    }
4629                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4630                        continue;
4631                    }
4632                // Package has been specified, we want to hit all processes
4633                // that match it.  We need to qualify this by the processes
4634                // that are running under the specified app and user ID.
4635                } else {
4636                    if (UserHandle.getAppId(app.uid) != appId) {
4637                        continue;
4638                    }
4639                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4640                        continue;
4641                    }
4642                    if (!app.pkgList.containsKey(packageName)) {
4643                        continue;
4644                    }
4645                }
4646
4647                // Process has passed all conditions, kill it!
4648                if (!doit) {
4649                    return true;
4650                }
4651                app.removed = true;
4652                procs.add(app);
4653            }
4654        }
4655
4656        int N = procs.size();
4657        for (int i=0; i<N; i++) {
4658            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4659        }
4660        updateOomAdjLocked();
4661        return N > 0;
4662    }
4663
4664    private final boolean forceStopPackageLocked(String name, int appId,
4665            boolean callerWillRestart, boolean purgeCache, boolean doit,
4666            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4667        int i;
4668        int N;
4669
4670        if (userId == UserHandle.USER_ALL && name == null) {
4671            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4672        }
4673
4674        if (appId < 0 && name != null) {
4675            try {
4676                appId = UserHandle.getAppId(
4677                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4678            } catch (RemoteException e) {
4679            }
4680        }
4681
4682        if (doit) {
4683            if (name != null) {
4684                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4685                        + " user=" + userId + ": " + reason);
4686            } else {
4687                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4688            }
4689
4690            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4691            for (int ip=pmap.size()-1; ip>=0; ip--) {
4692                SparseArray<Long> ba = pmap.valueAt(ip);
4693                for (i=ba.size()-1; i>=0; i--) {
4694                    boolean remove = false;
4695                    final int entUid = ba.keyAt(i);
4696                    if (name != null) {
4697                        if (userId == UserHandle.USER_ALL) {
4698                            if (UserHandle.getAppId(entUid) == appId) {
4699                                remove = true;
4700                            }
4701                        } else {
4702                            if (entUid == UserHandle.getUid(userId, appId)) {
4703                                remove = true;
4704                            }
4705                        }
4706                    } else if (UserHandle.getUserId(entUid) == userId) {
4707                        remove = true;
4708                    }
4709                    if (remove) {
4710                        ba.removeAt(i);
4711                    }
4712                }
4713                if (ba.size() == 0) {
4714                    pmap.removeAt(ip);
4715                }
4716            }
4717        }
4718
4719        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4720                -100, callerWillRestart, true, doit, evenPersistent,
4721                name == null ? ("stop user " + userId) : ("stop " + name));
4722
4723        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4724            if (!doit) {
4725                return true;
4726            }
4727            didSomething = true;
4728        }
4729
4730        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4731            if (!doit) {
4732                return true;
4733            }
4734            didSomething = true;
4735        }
4736
4737        if (name == null) {
4738            // Remove all sticky broadcasts from this user.
4739            mStickyBroadcasts.remove(userId);
4740        }
4741
4742        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4743        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4744                userId, providers)) {
4745            if (!doit) {
4746                return true;
4747            }
4748            didSomething = true;
4749        }
4750        N = providers.size();
4751        for (i=0; i<N; i++) {
4752            removeDyingProviderLocked(null, providers.get(i), true);
4753        }
4754
4755        // Remove transient permissions granted from/to this package/user
4756        removeUriPermissionsForPackageLocked(name, userId, false);
4757
4758        if (name == null || uninstalling) {
4759            // Remove pending intents.  For now we only do this when force
4760            // stopping users, because we have some problems when doing this
4761            // for packages -- app widgets are not currently cleaned up for
4762            // such packages, so they can be left with bad pending intents.
4763            if (mIntentSenderRecords.size() > 0) {
4764                Iterator<WeakReference<PendingIntentRecord>> it
4765                        = mIntentSenderRecords.values().iterator();
4766                while (it.hasNext()) {
4767                    WeakReference<PendingIntentRecord> wpir = it.next();
4768                    if (wpir == null) {
4769                        it.remove();
4770                        continue;
4771                    }
4772                    PendingIntentRecord pir = wpir.get();
4773                    if (pir == null) {
4774                        it.remove();
4775                        continue;
4776                    }
4777                    if (name == null) {
4778                        // Stopping user, remove all objects for the user.
4779                        if (pir.key.userId != userId) {
4780                            // Not the same user, skip it.
4781                            continue;
4782                        }
4783                    } else {
4784                        if (UserHandle.getAppId(pir.uid) != appId) {
4785                            // Different app id, skip it.
4786                            continue;
4787                        }
4788                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4789                            // Different user, skip it.
4790                            continue;
4791                        }
4792                        if (!pir.key.packageName.equals(name)) {
4793                            // Different package, skip it.
4794                            continue;
4795                        }
4796                    }
4797                    if (!doit) {
4798                        return true;
4799                    }
4800                    didSomething = true;
4801                    it.remove();
4802                    pir.canceled = true;
4803                    if (pir.key.activity != null) {
4804                        pir.key.activity.pendingResults.remove(pir.ref);
4805                    }
4806                }
4807            }
4808        }
4809
4810        if (doit) {
4811            if (purgeCache && name != null) {
4812                AttributeCache ac = AttributeCache.instance();
4813                if (ac != null) {
4814                    ac.removePackage(name);
4815                }
4816            }
4817            if (mBooted) {
4818                mStackSupervisor.resumeTopActivitiesLocked();
4819                mStackSupervisor.scheduleIdleLocked();
4820            }
4821        }
4822
4823        return didSomething;
4824    }
4825
4826    private final boolean removeProcessLocked(ProcessRecord app,
4827            boolean callerWillRestart, boolean allowRestart, String reason) {
4828        final String name = app.processName;
4829        final int uid = app.uid;
4830        if (DEBUG_PROCESSES) Slog.d(
4831            TAG, "Force removing proc " + app.toShortString() + " (" + name
4832            + "/" + uid + ")");
4833
4834        mProcessNames.remove(name, uid);
4835        mIsolatedProcesses.remove(app.uid);
4836        if (mHeavyWeightProcess == app) {
4837            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4838                    mHeavyWeightProcess.userId, 0));
4839            mHeavyWeightProcess = null;
4840        }
4841        boolean needRestart = false;
4842        if (app.pid > 0 && app.pid != MY_PID) {
4843            int pid = app.pid;
4844            synchronized (mPidsSelfLocked) {
4845                mPidsSelfLocked.remove(pid);
4846                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4847            }
4848            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4849                    app.processName, app.info.uid);
4850            if (app.isolated) {
4851                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4852            }
4853            killUnneededProcessLocked(app, reason);
4854            handleAppDiedLocked(app, true, allowRestart);
4855            removeLruProcessLocked(app);
4856
4857            if (app.persistent && !app.isolated) {
4858                if (!callerWillRestart) {
4859                    addAppLocked(app.info, false);
4860                } else {
4861                    needRestart = true;
4862                }
4863            }
4864        } else {
4865            mRemovedProcesses.add(app);
4866        }
4867
4868        return needRestart;
4869    }
4870
4871    private final void processStartTimedOutLocked(ProcessRecord app) {
4872        final int pid = app.pid;
4873        boolean gone = false;
4874        synchronized (mPidsSelfLocked) {
4875            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4876            if (knownApp != null && knownApp.thread == null) {
4877                mPidsSelfLocked.remove(pid);
4878                gone = true;
4879            }
4880        }
4881
4882        if (gone) {
4883            Slog.w(TAG, "Process " + app + " failed to attach");
4884            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4885                    pid, app.uid, app.processName);
4886            mProcessNames.remove(app.processName, app.uid);
4887            mIsolatedProcesses.remove(app.uid);
4888            if (mHeavyWeightProcess == app) {
4889                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4890                        mHeavyWeightProcess.userId, 0));
4891                mHeavyWeightProcess = null;
4892            }
4893            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4894                    app.processName, app.info.uid);
4895            if (app.isolated) {
4896                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4897            }
4898            // Take care of any launching providers waiting for this process.
4899            checkAppInLaunchingProvidersLocked(app, true);
4900            // Take care of any services that are waiting for the process.
4901            mServices.processStartTimedOutLocked(app);
4902            killUnneededProcessLocked(app, "start timeout");
4903            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4904                Slog.w(TAG, "Unattached app died before backup, skipping");
4905                try {
4906                    IBackupManager bm = IBackupManager.Stub.asInterface(
4907                            ServiceManager.getService(Context.BACKUP_SERVICE));
4908                    bm.agentDisconnected(app.info.packageName);
4909                } catch (RemoteException e) {
4910                    // Can't happen; the backup manager is local
4911                }
4912            }
4913            if (isPendingBroadcastProcessLocked(pid)) {
4914                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4915                skipPendingBroadcastLocked(pid);
4916            }
4917        } else {
4918            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4919        }
4920    }
4921
4922    private final boolean attachApplicationLocked(IApplicationThread thread,
4923            int pid) {
4924
4925        // Find the application record that is being attached...  either via
4926        // the pid if we are running in multiple processes, or just pull the
4927        // next app record if we are emulating process with anonymous threads.
4928        ProcessRecord app;
4929        if (pid != MY_PID && pid >= 0) {
4930            synchronized (mPidsSelfLocked) {
4931                app = mPidsSelfLocked.get(pid);
4932            }
4933        } else {
4934            app = null;
4935        }
4936
4937        if (app == null) {
4938            Slog.w(TAG, "No pending application record for pid " + pid
4939                    + " (IApplicationThread " + thread + "); dropping process");
4940            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4941            if (pid > 0 && pid != MY_PID) {
4942                Process.killProcessQuiet(pid);
4943            } else {
4944                try {
4945                    thread.scheduleExit();
4946                } catch (Exception e) {
4947                    // Ignore exceptions.
4948                }
4949            }
4950            return false;
4951        }
4952
4953        // If this application record is still attached to a previous
4954        // process, clean it up now.
4955        if (app.thread != null) {
4956            handleAppDiedLocked(app, true, true);
4957        }
4958
4959        // Tell the process all about itself.
4960
4961        if (localLOGV) Slog.v(
4962                TAG, "Binding process pid " + pid + " to record " + app);
4963
4964        final String processName = app.processName;
4965        try {
4966            AppDeathRecipient adr = new AppDeathRecipient(
4967                    app, pid, thread);
4968            thread.asBinder().linkToDeath(adr, 0);
4969            app.deathRecipient = adr;
4970        } catch (RemoteException e) {
4971            app.resetPackageList(mProcessStats);
4972            startProcessLocked(app, "link fail", processName);
4973            return false;
4974        }
4975
4976        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4977
4978        app.makeActive(thread, mProcessStats);
4979        app.curAdj = app.setAdj = -100;
4980        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4981        app.forcingToForeground = null;
4982        updateProcessForegroundLocked(app, false, false);
4983        app.hasShownUi = false;
4984        app.debugging = false;
4985        app.cached = false;
4986
4987        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4988
4989        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4990        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4991
4992        if (!normalMode) {
4993            Slog.i(TAG, "Launching preboot mode app: " + app);
4994        }
4995
4996        if (localLOGV) Slog.v(
4997            TAG, "New app record " + app
4998            + " thread=" + thread.asBinder() + " pid=" + pid);
4999        try {
5000            int testMode = IApplicationThread.DEBUG_OFF;
5001            if (mDebugApp != null && mDebugApp.equals(processName)) {
5002                testMode = mWaitForDebugger
5003                    ? IApplicationThread.DEBUG_WAIT
5004                    : IApplicationThread.DEBUG_ON;
5005                app.debugging = true;
5006                if (mDebugTransient) {
5007                    mDebugApp = mOrigDebugApp;
5008                    mWaitForDebugger = mOrigWaitForDebugger;
5009                }
5010            }
5011            String profileFile = app.instrumentationProfileFile;
5012            ParcelFileDescriptor profileFd = null;
5013            boolean profileAutoStop = false;
5014            if (mProfileApp != null && mProfileApp.equals(processName)) {
5015                mProfileProc = app;
5016                profileFile = mProfileFile;
5017                profileFd = mProfileFd;
5018                profileAutoStop = mAutoStopProfiler;
5019            }
5020            boolean enableOpenGlTrace = false;
5021            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5022                enableOpenGlTrace = true;
5023                mOpenGlTraceApp = null;
5024            }
5025
5026            // If the app is being launched for restore or full backup, set it up specially
5027            boolean isRestrictedBackupMode = false;
5028            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5029                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5030                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5031                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5032            }
5033
5034            ensurePackageDexOpt(app.instrumentationInfo != null
5035                    ? app.instrumentationInfo.packageName
5036                    : app.info.packageName);
5037            if (app.instrumentationClass != null) {
5038                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5039            }
5040            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5041                    + processName + " with config " + mConfiguration);
5042            ApplicationInfo appInfo = app.instrumentationInfo != null
5043                    ? app.instrumentationInfo : app.info;
5044            app.compat = compatibilityInfoForPackageLocked(appInfo);
5045            if (profileFd != null) {
5046                profileFd = profileFd.dup();
5047            }
5048            thread.bindApplication(processName, appInfo, providers,
5049                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5050                    app.instrumentationArguments, app.instrumentationWatcher,
5051                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5052                    isRestrictedBackupMode || !normalMode, app.persistent,
5053                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5054                    mCoreSettingsObserver.getCoreSettingsLocked());
5055            updateLruProcessLocked(app, false, null);
5056            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5057        } catch (Exception e) {
5058            // todo: Yikes!  What should we do?  For now we will try to
5059            // start another process, but that could easily get us in
5060            // an infinite loop of restarting processes...
5061            Slog.w(TAG, "Exception thrown during bind!", e);
5062
5063            app.resetPackageList(mProcessStats);
5064            app.unlinkDeathRecipient();
5065            startProcessLocked(app, "bind fail", processName);
5066            return false;
5067        }
5068
5069        // Remove this record from the list of starting applications.
5070        mPersistentStartingProcesses.remove(app);
5071        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5072                "Attach application locked removing on hold: " + app);
5073        mProcessesOnHold.remove(app);
5074
5075        boolean badApp = false;
5076        boolean didSomething = false;
5077
5078        // See if the top visible activity is waiting to run in this process...
5079        if (normalMode) {
5080            try {
5081                if (mStackSupervisor.attachApplicationLocked(app)) {
5082                    didSomething = true;
5083                }
5084            } catch (Exception e) {
5085                badApp = true;
5086            }
5087        }
5088
5089        // Find any services that should be running in this process...
5090        if (!badApp) {
5091            try {
5092                didSomething |= mServices.attachApplicationLocked(app, processName);
5093            } catch (Exception e) {
5094                badApp = true;
5095            }
5096        }
5097
5098        // Check if a next-broadcast receiver is in this process...
5099        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5100            try {
5101                didSomething |= sendPendingBroadcastsLocked(app);
5102            } catch (Exception e) {
5103                // If the app died trying to launch the receiver we declare it 'bad'
5104                badApp = true;
5105            }
5106        }
5107
5108        // Check whether the next backup agent is in this process...
5109        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5110            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5111            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5112            try {
5113                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5114                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5115                        mBackupTarget.backupMode);
5116            } catch (Exception e) {
5117                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5118                e.printStackTrace();
5119            }
5120        }
5121
5122        if (badApp) {
5123            // todo: Also need to kill application to deal with all
5124            // kinds of exceptions.
5125            handleAppDiedLocked(app, false, true);
5126            return false;
5127        }
5128
5129        if (!didSomething) {
5130            updateOomAdjLocked();
5131        }
5132
5133        return true;
5134    }
5135
5136    @Override
5137    public final void attachApplication(IApplicationThread thread) {
5138        synchronized (this) {
5139            int callingPid = Binder.getCallingPid();
5140            final long origId = Binder.clearCallingIdentity();
5141            attachApplicationLocked(thread, callingPid);
5142            Binder.restoreCallingIdentity(origId);
5143        }
5144    }
5145
5146    @Override
5147    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5148        final long origId = Binder.clearCallingIdentity();
5149        synchronized (this) {
5150            ActivityStack stack = ActivityRecord.getStackLocked(token);
5151            if (stack != null) {
5152                ActivityRecord r =
5153                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5154                if (stopProfiling) {
5155                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5156                        try {
5157                            mProfileFd.close();
5158                        } catch (IOException e) {
5159                        }
5160                        clearProfilerLocked();
5161                    }
5162                }
5163            }
5164        }
5165        Binder.restoreCallingIdentity(origId);
5166    }
5167
5168    void enableScreenAfterBoot() {
5169        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5170                SystemClock.uptimeMillis());
5171        mWindowManager.enableScreenAfterBoot();
5172
5173        synchronized (this) {
5174            updateEventDispatchingLocked();
5175        }
5176    }
5177
5178    @Override
5179    public void showBootMessage(final CharSequence msg, final boolean always) {
5180        enforceNotIsolatedCaller("showBootMessage");
5181        mWindowManager.showBootMessage(msg, always);
5182    }
5183
5184    @Override
5185    public void dismissKeyguardOnNextActivity() {
5186        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5187        final long token = Binder.clearCallingIdentity();
5188        try {
5189            synchronized (this) {
5190                if (DEBUG_LOCKSCREEN) logLockScreen("");
5191                if (mLockScreenShown) {
5192                    mLockScreenShown = false;
5193                    comeOutOfSleepIfNeededLocked();
5194                }
5195                mStackSupervisor.setDismissKeyguard(true);
5196            }
5197        } finally {
5198            Binder.restoreCallingIdentity(token);
5199        }
5200    }
5201
5202    final void finishBooting() {
5203        IntentFilter pkgFilter = new IntentFilter();
5204        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5205        pkgFilter.addDataScheme("package");
5206        mContext.registerReceiver(new BroadcastReceiver() {
5207            @Override
5208            public void onReceive(Context context, Intent intent) {
5209                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5210                if (pkgs != null) {
5211                    for (String pkg : pkgs) {
5212                        synchronized (ActivityManagerService.this) {
5213                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5214                                    "finished booting")) {
5215                                setResultCode(Activity.RESULT_OK);
5216                                return;
5217                            }
5218                        }
5219                    }
5220                }
5221            }
5222        }, pkgFilter);
5223
5224        synchronized (this) {
5225            // Ensure that any processes we had put on hold are now started
5226            // up.
5227            final int NP = mProcessesOnHold.size();
5228            if (NP > 0) {
5229                ArrayList<ProcessRecord> procs =
5230                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5231                for (int ip=0; ip<NP; ip++) {
5232                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5233                            + procs.get(ip));
5234                    startProcessLocked(procs.get(ip), "on-hold", null);
5235                }
5236            }
5237
5238            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5239                // Start looking for apps that are abusing wake locks.
5240                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5241                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5242                // Tell anyone interested that we are done booting!
5243                SystemProperties.set("sys.boot_completed", "1");
5244                SystemProperties.set("dev.bootcomplete", "1");
5245                for (int i=0; i<mStartedUsers.size(); i++) {
5246                    UserStartedState uss = mStartedUsers.valueAt(i);
5247                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5248                        uss.mState = UserStartedState.STATE_RUNNING;
5249                        final int userId = mStartedUsers.keyAt(i);
5250                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5251                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5252                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5253                        broadcastIntentLocked(null, null, intent, null,
5254                                new IIntentReceiver.Stub() {
5255                                    @Override
5256                                    public void performReceive(Intent intent, int resultCode,
5257                                            String data, Bundle extras, boolean ordered,
5258                                            boolean sticky, int sendingUser) {
5259                                        synchronized (ActivityManagerService.this) {
5260                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5261                                                    true, false);
5262                                        }
5263                                    }
5264                                },
5265                                0, null, null,
5266                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5267                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5268                                userId);
5269                    }
5270                }
5271                scheduleStartProfilesLocked();
5272            }
5273        }
5274    }
5275
5276    final void ensureBootCompleted() {
5277        boolean booting;
5278        boolean enableScreen;
5279        synchronized (this) {
5280            booting = mBooting;
5281            mBooting = false;
5282            enableScreen = !mBooted;
5283            mBooted = true;
5284        }
5285
5286        if (booting) {
5287            finishBooting();
5288        }
5289
5290        if (enableScreen) {
5291            enableScreenAfterBoot();
5292        }
5293    }
5294
5295    @Override
5296    public final void activityResumed(IBinder token) {
5297        final long origId = Binder.clearCallingIdentity();
5298        synchronized(this) {
5299            ActivityStack stack = ActivityRecord.getStackLocked(token);
5300            if (stack != null) {
5301                ActivityRecord.activityResumedLocked(token);
5302            }
5303        }
5304        Binder.restoreCallingIdentity(origId);
5305    }
5306
5307    @Override
5308    public final void activityPaused(IBinder token) {
5309        final long origId = Binder.clearCallingIdentity();
5310        synchronized(this) {
5311            ActivityStack stack = ActivityRecord.getStackLocked(token);
5312            if (stack != null) {
5313                stack.activityPausedLocked(token, false);
5314            }
5315        }
5316        Binder.restoreCallingIdentity(origId);
5317    }
5318
5319    @Override
5320    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5321            CharSequence description) {
5322        if (localLOGV) Slog.v(
5323            TAG, "Activity stopped: token=" + token);
5324
5325        // Refuse possible leaked file descriptors
5326        if (icicle != null && icicle.hasFileDescriptors()) {
5327            throw new IllegalArgumentException("File descriptors passed in Bundle");
5328        }
5329
5330        ActivityRecord r = null;
5331
5332        final long origId = Binder.clearCallingIdentity();
5333
5334        synchronized (this) {
5335            r = ActivityRecord.isInStackLocked(token);
5336            if (r != null) {
5337                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5338            }
5339        }
5340
5341        if (r != null) {
5342            sendPendingThumbnail(r, null, null, null, false);
5343        }
5344
5345        trimApplications();
5346
5347        Binder.restoreCallingIdentity(origId);
5348    }
5349
5350    @Override
5351    public final void activityDestroyed(IBinder token) {
5352        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5353        synchronized (this) {
5354            ActivityStack stack = ActivityRecord.getStackLocked(token);
5355            if (stack != null) {
5356                stack.activityDestroyedLocked(token);
5357            }
5358        }
5359    }
5360
5361    @Override
5362    public String getCallingPackage(IBinder token) {
5363        synchronized (this) {
5364            ActivityRecord r = getCallingRecordLocked(token);
5365            return r != null ? r.info.packageName : null;
5366        }
5367    }
5368
5369    @Override
5370    public ComponentName getCallingActivity(IBinder token) {
5371        synchronized (this) {
5372            ActivityRecord r = getCallingRecordLocked(token);
5373            return r != null ? r.intent.getComponent() : null;
5374        }
5375    }
5376
5377    private ActivityRecord getCallingRecordLocked(IBinder token) {
5378        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5379        if (r == null) {
5380            return null;
5381        }
5382        return r.resultTo;
5383    }
5384
5385    @Override
5386    public ComponentName getActivityClassForToken(IBinder token) {
5387        synchronized(this) {
5388            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5389            if (r == null) {
5390                return null;
5391            }
5392            return r.intent.getComponent();
5393        }
5394    }
5395
5396    @Override
5397    public String getPackageForToken(IBinder token) {
5398        synchronized(this) {
5399            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5400            if (r == null) {
5401                return null;
5402            }
5403            return r.packageName;
5404        }
5405    }
5406
5407    @Override
5408    public IIntentSender getIntentSender(int type,
5409            String packageName, IBinder token, String resultWho,
5410            int requestCode, Intent[] intents, String[] resolvedTypes,
5411            int flags, Bundle options, int userId) {
5412        enforceNotIsolatedCaller("getIntentSender");
5413        // Refuse possible leaked file descriptors
5414        if (intents != null) {
5415            if (intents.length < 1) {
5416                throw new IllegalArgumentException("Intents array length must be >= 1");
5417            }
5418            for (int i=0; i<intents.length; i++) {
5419                Intent intent = intents[i];
5420                if (intent != null) {
5421                    if (intent.hasFileDescriptors()) {
5422                        throw new IllegalArgumentException("File descriptors passed in Intent");
5423                    }
5424                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5425                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5426                        throw new IllegalArgumentException(
5427                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5428                    }
5429                    intents[i] = new Intent(intent);
5430                }
5431            }
5432            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5433                throw new IllegalArgumentException(
5434                        "Intent array length does not match resolvedTypes length");
5435            }
5436        }
5437        if (options != null) {
5438            if (options.hasFileDescriptors()) {
5439                throw new IllegalArgumentException("File descriptors passed in options");
5440            }
5441        }
5442
5443        synchronized(this) {
5444            int callingUid = Binder.getCallingUid();
5445            int origUserId = userId;
5446            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5447                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5448                    "getIntentSender", null);
5449            if (origUserId == UserHandle.USER_CURRENT) {
5450                // We don't want to evaluate this until the pending intent is
5451                // actually executed.  However, we do want to always do the
5452                // security checking for it above.
5453                userId = UserHandle.USER_CURRENT;
5454            }
5455            try {
5456                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5457                    int uid = AppGlobals.getPackageManager()
5458                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5459                    if (!UserHandle.isSameApp(callingUid, uid)) {
5460                        String msg = "Permission Denial: getIntentSender() from pid="
5461                            + Binder.getCallingPid()
5462                            + ", uid=" + Binder.getCallingUid()
5463                            + ", (need uid=" + uid + ")"
5464                            + " is not allowed to send as package " + packageName;
5465                        Slog.w(TAG, msg);
5466                        throw new SecurityException(msg);
5467                    }
5468                }
5469
5470                return getIntentSenderLocked(type, packageName, callingUid, userId,
5471                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5472
5473            } catch (RemoteException e) {
5474                throw new SecurityException(e);
5475            }
5476        }
5477    }
5478
5479    IIntentSender getIntentSenderLocked(int type, String packageName,
5480            int callingUid, int userId, IBinder token, String resultWho,
5481            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5482            Bundle options) {
5483        if (DEBUG_MU)
5484            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5485        ActivityRecord activity = null;
5486        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5487            activity = ActivityRecord.isInStackLocked(token);
5488            if (activity == null) {
5489                return null;
5490            }
5491            if (activity.finishing) {
5492                return null;
5493            }
5494        }
5495
5496        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5497        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5498        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5499        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5500                |PendingIntent.FLAG_UPDATE_CURRENT);
5501
5502        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5503                type, packageName, activity, resultWho,
5504                requestCode, intents, resolvedTypes, flags, options, userId);
5505        WeakReference<PendingIntentRecord> ref;
5506        ref = mIntentSenderRecords.get(key);
5507        PendingIntentRecord rec = ref != null ? ref.get() : null;
5508        if (rec != null) {
5509            if (!cancelCurrent) {
5510                if (updateCurrent) {
5511                    if (rec.key.requestIntent != null) {
5512                        rec.key.requestIntent.replaceExtras(intents != null ?
5513                                intents[intents.length - 1] : null);
5514                    }
5515                    if (intents != null) {
5516                        intents[intents.length-1] = rec.key.requestIntent;
5517                        rec.key.allIntents = intents;
5518                        rec.key.allResolvedTypes = resolvedTypes;
5519                    } else {
5520                        rec.key.allIntents = null;
5521                        rec.key.allResolvedTypes = null;
5522                    }
5523                }
5524                return rec;
5525            }
5526            rec.canceled = true;
5527            mIntentSenderRecords.remove(key);
5528        }
5529        if (noCreate) {
5530            return rec;
5531        }
5532        rec = new PendingIntentRecord(this, key, callingUid);
5533        mIntentSenderRecords.put(key, rec.ref);
5534        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5535            if (activity.pendingResults == null) {
5536                activity.pendingResults
5537                        = new HashSet<WeakReference<PendingIntentRecord>>();
5538            }
5539            activity.pendingResults.add(rec.ref);
5540        }
5541        return rec;
5542    }
5543
5544    @Override
5545    public void cancelIntentSender(IIntentSender sender) {
5546        if (!(sender instanceof PendingIntentRecord)) {
5547            return;
5548        }
5549        synchronized(this) {
5550            PendingIntentRecord rec = (PendingIntentRecord)sender;
5551            try {
5552                int uid = AppGlobals.getPackageManager()
5553                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5554                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5555                    String msg = "Permission Denial: cancelIntentSender() from pid="
5556                        + Binder.getCallingPid()
5557                        + ", uid=" + Binder.getCallingUid()
5558                        + " is not allowed to cancel packges "
5559                        + rec.key.packageName;
5560                    Slog.w(TAG, msg);
5561                    throw new SecurityException(msg);
5562                }
5563            } catch (RemoteException e) {
5564                throw new SecurityException(e);
5565            }
5566            cancelIntentSenderLocked(rec, true);
5567        }
5568    }
5569
5570    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5571        rec.canceled = true;
5572        mIntentSenderRecords.remove(rec.key);
5573        if (cleanActivity && rec.key.activity != null) {
5574            rec.key.activity.pendingResults.remove(rec.ref);
5575        }
5576    }
5577
5578    @Override
5579    public String getPackageForIntentSender(IIntentSender pendingResult) {
5580        if (!(pendingResult instanceof PendingIntentRecord)) {
5581            return null;
5582        }
5583        try {
5584            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5585            return res.key.packageName;
5586        } catch (ClassCastException e) {
5587        }
5588        return null;
5589    }
5590
5591    @Override
5592    public int getUidForIntentSender(IIntentSender sender) {
5593        if (sender instanceof PendingIntentRecord) {
5594            try {
5595                PendingIntentRecord res = (PendingIntentRecord)sender;
5596                return res.uid;
5597            } catch (ClassCastException e) {
5598            }
5599        }
5600        return -1;
5601    }
5602
5603    @Override
5604    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5605        if (!(pendingResult instanceof PendingIntentRecord)) {
5606            return false;
5607        }
5608        try {
5609            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5610            if (res.key.allIntents == null) {
5611                return false;
5612            }
5613            for (int i=0; i<res.key.allIntents.length; i++) {
5614                Intent intent = res.key.allIntents[i];
5615                if (intent.getPackage() != null && intent.getComponent() != null) {
5616                    return false;
5617                }
5618            }
5619            return true;
5620        } catch (ClassCastException e) {
5621        }
5622        return false;
5623    }
5624
5625    @Override
5626    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5627        if (!(pendingResult instanceof PendingIntentRecord)) {
5628            return false;
5629        }
5630        try {
5631            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5632            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5633                return true;
5634            }
5635            return false;
5636        } catch (ClassCastException e) {
5637        }
5638        return false;
5639    }
5640
5641    @Override
5642    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5643        if (!(pendingResult instanceof PendingIntentRecord)) {
5644            return null;
5645        }
5646        try {
5647            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5648            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5649        } catch (ClassCastException e) {
5650        }
5651        return null;
5652    }
5653
5654    @Override
5655    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5656        if (!(pendingResult instanceof PendingIntentRecord)) {
5657            return null;
5658        }
5659        try {
5660            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5661            Intent intent = res.key.requestIntent;
5662            if (intent != null) {
5663                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5664                        || res.lastTagPrefix.equals(prefix))) {
5665                    return res.lastTag;
5666                }
5667                res.lastTagPrefix = prefix;
5668                StringBuilder sb = new StringBuilder(128);
5669                if (prefix != null) {
5670                    sb.append(prefix);
5671                }
5672                if (intent.getAction() != null) {
5673                    sb.append(intent.getAction());
5674                } else if (intent.getComponent() != null) {
5675                    intent.getComponent().appendShortString(sb);
5676                } else {
5677                    sb.append("?");
5678                }
5679                return res.lastTag = sb.toString();
5680            }
5681        } catch (ClassCastException e) {
5682        }
5683        return null;
5684    }
5685
5686    @Override
5687    public void setProcessLimit(int max) {
5688        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5689                "setProcessLimit()");
5690        synchronized (this) {
5691            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5692            mProcessLimitOverride = max;
5693        }
5694        trimApplications();
5695    }
5696
5697    @Override
5698    public int getProcessLimit() {
5699        synchronized (this) {
5700            return mProcessLimitOverride;
5701        }
5702    }
5703
5704    void foregroundTokenDied(ForegroundToken token) {
5705        synchronized (ActivityManagerService.this) {
5706            synchronized (mPidsSelfLocked) {
5707                ForegroundToken cur
5708                    = mForegroundProcesses.get(token.pid);
5709                if (cur != token) {
5710                    return;
5711                }
5712                mForegroundProcesses.remove(token.pid);
5713                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5714                if (pr == null) {
5715                    return;
5716                }
5717                pr.forcingToForeground = null;
5718                updateProcessForegroundLocked(pr, false, false);
5719            }
5720            updateOomAdjLocked();
5721        }
5722    }
5723
5724    @Override
5725    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5726        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5727                "setProcessForeground()");
5728        synchronized(this) {
5729            boolean changed = false;
5730
5731            synchronized (mPidsSelfLocked) {
5732                ProcessRecord pr = mPidsSelfLocked.get(pid);
5733                if (pr == null && isForeground) {
5734                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5735                    return;
5736                }
5737                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5738                if (oldToken != null) {
5739                    oldToken.token.unlinkToDeath(oldToken, 0);
5740                    mForegroundProcesses.remove(pid);
5741                    if (pr != null) {
5742                        pr.forcingToForeground = null;
5743                    }
5744                    changed = true;
5745                }
5746                if (isForeground && token != null) {
5747                    ForegroundToken newToken = new ForegroundToken() {
5748                        @Override
5749                        public void binderDied() {
5750                            foregroundTokenDied(this);
5751                        }
5752                    };
5753                    newToken.pid = pid;
5754                    newToken.token = token;
5755                    try {
5756                        token.linkToDeath(newToken, 0);
5757                        mForegroundProcesses.put(pid, newToken);
5758                        pr.forcingToForeground = token;
5759                        changed = true;
5760                    } catch (RemoteException e) {
5761                        // If the process died while doing this, we will later
5762                        // do the cleanup with the process death link.
5763                    }
5764                }
5765            }
5766
5767            if (changed) {
5768                updateOomAdjLocked();
5769            }
5770        }
5771    }
5772
5773    // =========================================================
5774    // PERMISSIONS
5775    // =========================================================
5776
5777    static class PermissionController extends IPermissionController.Stub {
5778        ActivityManagerService mActivityManagerService;
5779        PermissionController(ActivityManagerService activityManagerService) {
5780            mActivityManagerService = activityManagerService;
5781        }
5782
5783        @Override
5784        public boolean checkPermission(String permission, int pid, int uid) {
5785            return mActivityManagerService.checkPermission(permission, pid,
5786                    uid) == PackageManager.PERMISSION_GRANTED;
5787        }
5788    }
5789
5790    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5791        @Override
5792        public int checkComponentPermission(String permission, int pid, int uid,
5793                int owningUid, boolean exported) {
5794            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5795                    owningUid, exported);
5796        }
5797
5798        @Override
5799        public Object getAMSLock() {
5800            return ActivityManagerService.this;
5801        }
5802    }
5803
5804    /**
5805     * This can be called with or without the global lock held.
5806     */
5807    int checkComponentPermission(String permission, int pid, int uid,
5808            int owningUid, boolean exported) {
5809        // We might be performing an operation on behalf of an indirect binder
5810        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5811        // client identity accordingly before proceeding.
5812        Identity tlsIdentity = sCallerIdentity.get();
5813        if (tlsIdentity != null) {
5814            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5815                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5816            uid = tlsIdentity.uid;
5817            pid = tlsIdentity.pid;
5818        }
5819
5820        if (pid == MY_PID) {
5821            return PackageManager.PERMISSION_GRANTED;
5822        }
5823
5824        return ActivityManager.checkComponentPermission(permission, uid,
5825                owningUid, exported);
5826    }
5827
5828    /**
5829     * As the only public entry point for permissions checking, this method
5830     * can enforce the semantic that requesting a check on a null global
5831     * permission is automatically denied.  (Internally a null permission
5832     * string is used when calling {@link #checkComponentPermission} in cases
5833     * when only uid-based security is needed.)
5834     *
5835     * This can be called with or without the global lock held.
5836     */
5837    @Override
5838    public int checkPermission(String permission, int pid, int uid) {
5839        if (permission == null) {
5840            return PackageManager.PERMISSION_DENIED;
5841        }
5842        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5843    }
5844
5845    /**
5846     * Binder IPC calls go through the public entry point.
5847     * This can be called with or without the global lock held.
5848     */
5849    int checkCallingPermission(String permission) {
5850        return checkPermission(permission,
5851                Binder.getCallingPid(),
5852                UserHandle.getAppId(Binder.getCallingUid()));
5853    }
5854
5855    /**
5856     * This can be called with or without the global lock held.
5857     */
5858    void enforceCallingPermission(String permission, String func) {
5859        if (checkCallingPermission(permission)
5860                == PackageManager.PERMISSION_GRANTED) {
5861            return;
5862        }
5863
5864        String msg = "Permission Denial: " + func + " from pid="
5865                + Binder.getCallingPid()
5866                + ", uid=" + Binder.getCallingUid()
5867                + " requires " + permission;
5868        Slog.w(TAG, msg);
5869        throw new SecurityException(msg);
5870    }
5871
5872    /**
5873     * Determine if UID is holding permissions required to access {@link Uri} in
5874     * the given {@link ProviderInfo}. Final permission checking is always done
5875     * in {@link ContentProvider}.
5876     */
5877    private final boolean checkHoldingPermissionsLocked(
5878            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) {
5879        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5880                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5881
5882        if (pi.applicationInfo.uid == uid) {
5883            return true;
5884        } else if (!pi.exported) {
5885            return false;
5886        }
5887
5888        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5889        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5890        try {
5891            // check if target holds top-level <provider> permissions
5892            if (!readMet && pi.readPermission != null
5893                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5894                readMet = true;
5895            }
5896            if (!writeMet && pi.writePermission != null
5897                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5898                writeMet = true;
5899            }
5900
5901            // track if unprotected read/write is allowed; any denied
5902            // <path-permission> below removes this ability
5903            boolean allowDefaultRead = pi.readPermission == null;
5904            boolean allowDefaultWrite = pi.writePermission == null;
5905
5906            // check if target holds any <path-permission> that match uri
5907            final PathPermission[] pps = pi.pathPermissions;
5908            if (pps != null) {
5909                final String path = uri.getPath();
5910                int i = pps.length;
5911                while (i > 0 && (!readMet || !writeMet)) {
5912                    i--;
5913                    PathPermission pp = pps[i];
5914                    if (pp.match(path)) {
5915                        if (!readMet) {
5916                            final String pprperm = pp.getReadPermission();
5917                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5918                                    + pprperm + " for " + pp.getPath()
5919                                    + ": match=" + pp.match(path)
5920                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5921                            if (pprperm != null) {
5922                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5923                                    readMet = true;
5924                                } else {
5925                                    allowDefaultRead = false;
5926                                }
5927                            }
5928                        }
5929                        if (!writeMet) {
5930                            final String ppwperm = pp.getWritePermission();
5931                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5932                                    + ppwperm + " for " + pp.getPath()
5933                                    + ": match=" + pp.match(path)
5934                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5935                            if (ppwperm != null) {
5936                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5937                                    writeMet = true;
5938                                } else {
5939                                    allowDefaultWrite = false;
5940                                }
5941                            }
5942                        }
5943                    }
5944                }
5945            }
5946
5947            // grant unprotected <provider> read/write, if not blocked by
5948            // <path-permission> above
5949            if (allowDefaultRead) readMet = true;
5950            if (allowDefaultWrite) writeMet = true;
5951
5952        } catch (RemoteException e) {
5953            return false;
5954        }
5955
5956        return readMet && writeMet;
5957    }
5958
5959    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5960        ProviderInfo pi = null;
5961        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5962        if (cpr != null) {
5963            pi = cpr.info;
5964        } else {
5965            try {
5966                pi = AppGlobals.getPackageManager().resolveContentProvider(
5967                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5968            } catch (RemoteException ex) {
5969            }
5970        }
5971        return pi;
5972    }
5973
5974    private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) {
5975        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5976        if (targetUris != null) {
5977            return targetUris.get(uri);
5978        }
5979        return null;
5980    }
5981
5982    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
5983            String targetPkg, int targetUid, GrantUri uri) {
5984        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5985        if (targetUris == null) {
5986            targetUris = Maps.newArrayMap();
5987            mGrantedUriPermissions.put(targetUid, targetUris);
5988        }
5989
5990        UriPermission perm = targetUris.get(uri);
5991        if (perm == null) {
5992            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5993            targetUris.put(uri, perm);
5994        }
5995
5996        return perm;
5997    }
5998
5999    private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) {
6000        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6001        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6002                : UriPermission.STRENGTH_OWNED;
6003
6004        // Root gets to do everything.
6005        if (uid == 0) {
6006            return true;
6007        }
6008
6009        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6010        if (perms == null) return false;
6011
6012        // First look for exact match
6013        final UriPermission exactPerm = perms.get(new GrantUri(uri, false));
6014        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6015            return true;
6016        }
6017
6018        // No exact match, look for prefixes
6019        final int N = perms.size();
6020        for (int i = 0; i < N; i++) {
6021            final UriPermission perm = perms.valueAt(i);
6022            if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri)
6023                    && perm.getStrength(modeFlags) >= minStrength) {
6024                return true;
6025            }
6026        }
6027
6028        return false;
6029    }
6030
6031    @Override
6032    public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) {
6033        enforceNotIsolatedCaller("checkUriPermission");
6034
6035        // Another redirected-binder-call permissions check as in
6036        // {@link checkComponentPermission}.
6037        Identity tlsIdentity = sCallerIdentity.get();
6038        if (tlsIdentity != null) {
6039            uid = tlsIdentity.uid;
6040            pid = tlsIdentity.pid;
6041        }
6042
6043        // Our own process gets to do everything.
6044        if (pid == MY_PID) {
6045            return PackageManager.PERMISSION_GRANTED;
6046        }
6047        synchronized (this) {
6048            return checkUriPermissionLocked(uri, uid, modeFlags)
6049                    ? PackageManager.PERMISSION_GRANTED
6050                    : PackageManager.PERMISSION_DENIED;
6051        }
6052    }
6053
6054    /**
6055     * Check if the targetPkg can be granted permission to access uri by
6056     * the callingUid using the given modeFlags.  Throws a security exception
6057     * if callingUid is not allowed to do this.  Returns the uid of the target
6058     * if the URI permission grant should be performed; returns -1 if it is not
6059     * needed (for example targetPkg already has permission to access the URI).
6060     * If you already know the uid of the target, you can supply it in
6061     * lastTargetUid else set that to -1.
6062     */
6063    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
6064            Uri uri, final int modeFlags, int lastTargetUid) {
6065        if (!Intent.isAccessUriMode(modeFlags)) {
6066            return -1;
6067        }
6068
6069        if (targetPkg != null) {
6070            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6071                    "Checking grant " + targetPkg + " permission to " + uri);
6072        }
6073
6074        final IPackageManager pm = AppGlobals.getPackageManager();
6075
6076        // If this is not a content: uri, we can't do anything with it.
6077        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6078            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6079                    "Can't grant URI permission for non-content URI: " + uri);
6080            return -1;
6081        }
6082
6083        final String authority = uri.getAuthority();
6084        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6085        if (pi == null) {
6086            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6087            return -1;
6088        }
6089
6090        int targetUid = lastTargetUid;
6091        if (targetUid < 0 && targetPkg != null) {
6092            try {
6093                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6094                if (targetUid < 0) {
6095                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6096                            "Can't grant URI permission no uid for: " + targetPkg);
6097                    return -1;
6098                }
6099            } catch (RemoteException ex) {
6100                return -1;
6101            }
6102        }
6103
6104        if (targetUid >= 0) {
6105            // First...  does the target actually need this permission?
6106            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6107                // No need to grant the target this permission.
6108                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6109                        "Target " + targetPkg + " already has full permission to " + uri);
6110                return -1;
6111            }
6112        } else {
6113            // First...  there is no target package, so can anyone access it?
6114            boolean allowed = pi.exported;
6115            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6116                if (pi.readPermission != null) {
6117                    allowed = false;
6118                }
6119            }
6120            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6121                if (pi.writePermission != null) {
6122                    allowed = false;
6123                }
6124            }
6125            if (allowed) {
6126                return -1;
6127            }
6128        }
6129
6130        // Second...  is the provider allowing granting of URI permissions?
6131        if (!pi.grantUriPermissions) {
6132            throw new SecurityException("Provider " + pi.packageName
6133                    + "/" + pi.name
6134                    + " does not allow granting of Uri permissions (uri "
6135                    + uri + ")");
6136        }
6137        if (pi.uriPermissionPatterns != null) {
6138            final int N = pi.uriPermissionPatterns.length;
6139            boolean allowed = false;
6140            for (int i=0; i<N; i++) {
6141                if (pi.uriPermissionPatterns[i] != null
6142                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6143                    allowed = true;
6144                    break;
6145                }
6146            }
6147            if (!allowed) {
6148                throw new SecurityException("Provider " + pi.packageName
6149                        + "/" + pi.name
6150                        + " does not allow granting of permission to path of Uri "
6151                        + uri);
6152            }
6153        }
6154
6155        // Third...  does the caller itself have permission to access
6156        // this uri?
6157        if (callingUid != Process.myUid()) {
6158            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6159                // Require they hold a strong enough Uri permission
6160                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6161                    throw new SecurityException("Uid " + callingUid
6162                            + " does not have permission to uri " + uri);
6163                }
6164            }
6165        }
6166
6167        return targetUid;
6168    }
6169
6170    @Override
6171    public int checkGrantUriPermission(int callingUid, String targetPkg,
6172            Uri uri, final int modeFlags) {
6173        enforceNotIsolatedCaller("checkGrantUriPermission");
6174        synchronized(this) {
6175            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6176        }
6177    }
6178
6179    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri,
6180            final int modeFlags, UriPermissionOwner owner) {
6181        if (!Intent.isAccessUriMode(modeFlags)) {
6182            return;
6183        }
6184
6185        // So here we are: the caller has the assumed permission
6186        // to the uri, and the target doesn't.  Let's now give this to
6187        // the target.
6188
6189        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6190                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6191
6192        final String authority = uri.getAuthority();
6193        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6194        if (pi == null) {
6195            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6196            return;
6197        }
6198
6199        final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
6200        final UriPermission perm = findOrCreateUriPermissionLocked(
6201                pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix));
6202        perm.grantModes(modeFlags, owner);
6203    }
6204
6205    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6206            final int modeFlags, UriPermissionOwner owner) {
6207        if (targetPkg == null) {
6208            throw new NullPointerException("targetPkg");
6209        }
6210
6211        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6212        if (targetUid < 0) {
6213            return;
6214        }
6215
6216        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6217    }
6218
6219    static class NeededUriGrants extends ArrayList<Uri> {
6220        final String targetPkg;
6221        final int targetUid;
6222        final int flags;
6223
6224        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6225            this.targetPkg = targetPkg;
6226            this.targetUid = targetUid;
6227            this.flags = flags;
6228        }
6229    }
6230
6231    /**
6232     * Like checkGrantUriPermissionLocked, but takes an Intent.
6233     */
6234    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6235            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6236        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6237                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6238                + " clip=" + (intent != null ? intent.getClipData() : null)
6239                + " from " + intent + "; flags=0x"
6240                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6241
6242        if (targetPkg == null) {
6243            throw new NullPointerException("targetPkg");
6244        }
6245
6246        if (intent == null) {
6247            return null;
6248        }
6249        Uri data = intent.getData();
6250        ClipData clip = intent.getClipData();
6251        if (data == null && clip == null) {
6252            return null;
6253        }
6254
6255        if (data != null) {
6256            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6257                mode, needed != null ? needed.targetUid : -1);
6258            if (targetUid > 0) {
6259                if (needed == null) {
6260                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6261                }
6262                needed.add(data);
6263            }
6264        }
6265        if (clip != null) {
6266            for (int i=0; i<clip.getItemCount(); i++) {
6267                Uri uri = clip.getItemAt(i).getUri();
6268                if (uri != null) {
6269                    int targetUid = -1;
6270                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6271                            mode, needed != null ? needed.targetUid : -1);
6272                    if (targetUid > 0) {
6273                        if (needed == null) {
6274                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6275                        }
6276                        needed.add(uri);
6277                    }
6278                } else {
6279                    Intent clipIntent = clip.getItemAt(i).getIntent();
6280                    if (clipIntent != null) {
6281                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6282                                callingUid, targetPkg, clipIntent, mode, needed);
6283                        if (newNeeded != null) {
6284                            needed = newNeeded;
6285                        }
6286                    }
6287                }
6288            }
6289        }
6290
6291        return needed;
6292    }
6293
6294    /**
6295     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6296     */
6297    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6298            UriPermissionOwner owner) {
6299        if (needed != null) {
6300            for (int i=0; i<needed.size(); i++) {
6301                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6302                        needed.get(i), needed.flags, owner);
6303            }
6304        }
6305    }
6306
6307    void grantUriPermissionFromIntentLocked(int callingUid,
6308            String targetPkg, Intent intent, UriPermissionOwner owner) {
6309        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6310                intent, intent != null ? intent.getFlags() : 0, null);
6311        if (needed == null) {
6312            return;
6313        }
6314
6315        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6316    }
6317
6318    @Override
6319    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6320            Uri uri, final int modeFlags) {
6321        enforceNotIsolatedCaller("grantUriPermission");
6322        synchronized(this) {
6323            final ProcessRecord r = getRecordForAppLocked(caller);
6324            if (r == null) {
6325                throw new SecurityException("Unable to find app for caller "
6326                        + caller
6327                        + " when granting permission to uri " + uri);
6328            }
6329            if (targetPkg == null) {
6330                throw new IllegalArgumentException("null target");
6331            }
6332            if (uri == null) {
6333                throw new IllegalArgumentException("null uri");
6334            }
6335
6336            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6337                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6338                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6339                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6340
6341            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null);
6342        }
6343    }
6344
6345    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6346        if (perm.modeFlags == 0) {
6347            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6348                    perm.targetUid);
6349            if (perms != null) {
6350                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6351                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6352
6353                perms.remove(perm.uri);
6354                if (perms.isEmpty()) {
6355                    mGrantedUriPermissions.remove(perm.targetUid);
6356                }
6357            }
6358        }
6359    }
6360
6361    private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) {
6362        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6363
6364        final IPackageManager pm = AppGlobals.getPackageManager();
6365        final String authority = uri.getAuthority();
6366        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6367        if (pi == null) {
6368            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6369            return;
6370        }
6371
6372        // Does the caller have this permission on the URI?
6373        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6374            // Right now, if you are not the original owner of the permission,
6375            // you are not allowed to revoke it.
6376            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6377                throw new SecurityException("Uid " + callingUid
6378                        + " does not have permission to uri " + uri);
6379            //}
6380        }
6381
6382        boolean persistChanged = false;
6383
6384        // Go through all of the permissions and remove any that match.
6385        int N = mGrantedUriPermissions.size();
6386        for (int i = 0; i < N; i++) {
6387            final int targetUid = mGrantedUriPermissions.keyAt(i);
6388            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6389
6390            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6391                final UriPermission perm = it.next();
6392                if (perm.uri.uri.isPathPrefixMatch(uri)) {
6393                    if (DEBUG_URI_PERMISSION)
6394                        Slog.v(TAG,
6395                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6396                    persistChanged |= perm.revokeModes(
6397                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6398                    if (perm.modeFlags == 0) {
6399                        it.remove();
6400                    }
6401                }
6402            }
6403
6404            if (perms.isEmpty()) {
6405                mGrantedUriPermissions.remove(targetUid);
6406                N--;
6407                i--;
6408            }
6409        }
6410
6411        if (persistChanged) {
6412            schedulePersistUriGrants();
6413        }
6414    }
6415
6416    @Override
6417    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6418            final int modeFlags) {
6419        enforceNotIsolatedCaller("revokeUriPermission");
6420        synchronized(this) {
6421            final ProcessRecord r = getRecordForAppLocked(caller);
6422            if (r == null) {
6423                throw new SecurityException("Unable to find app for caller "
6424                        + caller
6425                        + " when revoking permission to uri " + uri);
6426            }
6427            if (uri == null) {
6428                Slog.w(TAG, "revokeUriPermission: null uri");
6429                return;
6430            }
6431
6432            if (!Intent.isAccessUriMode(modeFlags)) {
6433                return;
6434            }
6435
6436            final IPackageManager pm = AppGlobals.getPackageManager();
6437            final String authority = uri.getAuthority();
6438            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6439            if (pi == null) {
6440                Slog.w(TAG, "No content provider found for permission revoke: "
6441                        + uri.toSafeString());
6442                return;
6443            }
6444
6445            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6446        }
6447    }
6448
6449    /**
6450     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6451     * given package.
6452     *
6453     * @param packageName Package name to match, or {@code null} to apply to all
6454     *            packages.
6455     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6456     *            to all users.
6457     * @param persistable If persistable grants should be removed.
6458     */
6459    private void removeUriPermissionsForPackageLocked(
6460            String packageName, int userHandle, boolean persistable) {
6461        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6462            throw new IllegalArgumentException("Must narrow by either package or user");
6463        }
6464
6465        boolean persistChanged = false;
6466
6467        int N = mGrantedUriPermissions.size();
6468        for (int i = 0; i < N; i++) {
6469            final int targetUid = mGrantedUriPermissions.keyAt(i);
6470            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6471
6472            // Only inspect grants matching user
6473            if (userHandle == UserHandle.USER_ALL
6474                    || userHandle == UserHandle.getUserId(targetUid)) {
6475                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6476                    final UriPermission perm = it.next();
6477
6478                    // Only inspect grants matching package
6479                    if (packageName == null || perm.sourcePkg.equals(packageName)
6480                            || perm.targetPkg.equals(packageName)) {
6481                        persistChanged |= perm.revokeModes(
6482                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6483
6484                        // Only remove when no modes remain; any persisted grants
6485                        // will keep this alive.
6486                        if (perm.modeFlags == 0) {
6487                            it.remove();
6488                        }
6489                    }
6490                }
6491
6492                if (perms.isEmpty()) {
6493                    mGrantedUriPermissions.remove(targetUid);
6494                    N--;
6495                    i--;
6496                }
6497            }
6498        }
6499
6500        if (persistChanged) {
6501            schedulePersistUriGrants();
6502        }
6503    }
6504
6505    @Override
6506    public IBinder newUriPermissionOwner(String name) {
6507        enforceNotIsolatedCaller("newUriPermissionOwner");
6508        synchronized(this) {
6509            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6510            return owner.getExternalTokenLocked();
6511        }
6512    }
6513
6514    @Override
6515    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6516            Uri uri, final int modeFlags) {
6517        synchronized(this) {
6518            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6519            if (owner == null) {
6520                throw new IllegalArgumentException("Unknown owner: " + token);
6521            }
6522            if (fromUid != Binder.getCallingUid()) {
6523                if (Binder.getCallingUid() != Process.myUid()) {
6524                    // Only system code can grant URI permissions on behalf
6525                    // of other users.
6526                    throw new SecurityException("nice try");
6527                }
6528            }
6529            if (targetPkg == null) {
6530                throw new IllegalArgumentException("null target");
6531            }
6532            if (uri == null) {
6533                throw new IllegalArgumentException("null uri");
6534            }
6535
6536            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6537        }
6538    }
6539
6540    @Override
6541    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6542        synchronized(this) {
6543            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6544            if (owner == null) {
6545                throw new IllegalArgumentException("Unknown owner: " + token);
6546            }
6547
6548            if (uri == null) {
6549                owner.removeUriPermissionsLocked(mode);
6550            } else {
6551                owner.removeUriPermissionLocked(uri, mode);
6552            }
6553        }
6554    }
6555
6556    private void schedulePersistUriGrants() {
6557        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6558            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6559                    10 * DateUtils.SECOND_IN_MILLIS);
6560        }
6561    }
6562
6563    private void writeGrantedUriPermissions() {
6564        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6565
6566        // Snapshot permissions so we can persist without lock
6567        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6568        synchronized (this) {
6569            final int size = mGrantedUriPermissions.size();
6570            for (int i = 0; i < size; i++) {
6571                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6572                for (UriPermission perm : perms.values()) {
6573                    if (perm.persistedModeFlags != 0) {
6574                        persist.add(perm.snapshot());
6575                    }
6576                }
6577            }
6578        }
6579
6580        FileOutputStream fos = null;
6581        try {
6582            fos = mGrantFile.startWrite();
6583
6584            XmlSerializer out = new FastXmlSerializer();
6585            out.setOutput(fos, "utf-8");
6586            out.startDocument(null, true);
6587            out.startTag(null, TAG_URI_GRANTS);
6588            for (UriPermission.Snapshot perm : persist) {
6589                out.startTag(null, TAG_URI_GRANT);
6590                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6591                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6592                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6593                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6594                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6595                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6596                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6597                out.endTag(null, TAG_URI_GRANT);
6598            }
6599            out.endTag(null, TAG_URI_GRANTS);
6600            out.endDocument();
6601
6602            mGrantFile.finishWrite(fos);
6603        } catch (IOException e) {
6604            if (fos != null) {
6605                mGrantFile.failWrite(fos);
6606            }
6607        }
6608    }
6609
6610    private void readGrantedUriPermissionsLocked() {
6611        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6612
6613        final long now = System.currentTimeMillis();
6614
6615        FileInputStream fis = null;
6616        try {
6617            fis = mGrantFile.openRead();
6618            final XmlPullParser in = Xml.newPullParser();
6619            in.setInput(fis, null);
6620
6621            int type;
6622            while ((type = in.next()) != END_DOCUMENT) {
6623                final String tag = in.getName();
6624                if (type == START_TAG) {
6625                    if (TAG_URI_GRANT.equals(tag)) {
6626                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6627                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6628                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6629                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6630                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6631                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6632                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6633
6634                        // Sanity check that provider still belongs to source package
6635                        final ProviderInfo pi = getProviderInfoLocked(
6636                                uri.getAuthority(), userHandle);
6637                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6638                            int targetUid = -1;
6639                            try {
6640                                targetUid = AppGlobals.getPackageManager()
6641                                        .getPackageUid(targetPkg, userHandle);
6642                            } catch (RemoteException e) {
6643                            }
6644                            if (targetUid != -1) {
6645                                final UriPermission perm = findOrCreateUriPermissionLocked(
6646                                        sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix));
6647                                perm.initPersistedModes(modeFlags, createdTime);
6648                            }
6649                        } else {
6650                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6651                                    + " but instead found " + pi);
6652                        }
6653                    }
6654                }
6655            }
6656        } catch (FileNotFoundException e) {
6657            // Missing grants is okay
6658        } catch (IOException e) {
6659            Log.wtf(TAG, "Failed reading Uri grants", e);
6660        } catch (XmlPullParserException e) {
6661            Log.wtf(TAG, "Failed reading Uri grants", e);
6662        } finally {
6663            IoUtils.closeQuietly(fis);
6664        }
6665    }
6666
6667    @Override
6668    public void takePersistableUriPermission(Uri uri, final int modeFlags) {
6669        enforceNotIsolatedCaller("takePersistableUriPermission");
6670
6671        Preconditions.checkFlagsArgument(modeFlags,
6672                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6673
6674        synchronized (this) {
6675            final int callingUid = Binder.getCallingUid();
6676            boolean persistChanged = false;
6677
6678            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6679            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6680
6681            final boolean exactValid = (exactPerm != null)
6682                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6683            final boolean prefixValid = (prefixPerm != null)
6684                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6685
6686            if (!(exactValid || prefixValid)) {
6687                throw new SecurityException("No persistable permission grants found for UID "
6688                        + callingUid + " and Uri " + uri.toSafeString());
6689            }
6690
6691            if (exactValid) {
6692                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6693            }
6694            if (prefixValid) {
6695                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6696            }
6697
6698            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6699
6700            if (persistChanged) {
6701                schedulePersistUriGrants();
6702            }
6703        }
6704    }
6705
6706    @Override
6707    public void releasePersistableUriPermission(Uri uri, final int modeFlags) {
6708        enforceNotIsolatedCaller("releasePersistableUriPermission");
6709
6710        Preconditions.checkFlagsArgument(modeFlags,
6711                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6712
6713        synchronized (this) {
6714            final int callingUid = Binder.getCallingUid();
6715            boolean persistChanged = false;
6716
6717            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6718            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6719            if (exactPerm == null && prefixPerm == null) {
6720                throw new SecurityException("No permission grants found for UID " + callingUid
6721                        + " and Uri " + uri.toSafeString());
6722            }
6723
6724            if (exactPerm != null) {
6725                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6726                removeUriPermissionIfNeededLocked(exactPerm);
6727            }
6728            if (prefixPerm != null) {
6729                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6730                removeUriPermissionIfNeededLocked(prefixPerm);
6731            }
6732
6733            if (persistChanged) {
6734                schedulePersistUriGrants();
6735            }
6736        }
6737    }
6738
6739    /**
6740     * Prune any older {@link UriPermission} for the given UID until outstanding
6741     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6742     *
6743     * @return if any mutations occured that require persisting.
6744     */
6745    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6746        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6747        if (perms == null) return false;
6748        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6749
6750        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6751        for (UriPermission perm : perms.values()) {
6752            if (perm.persistedModeFlags != 0) {
6753                persisted.add(perm);
6754            }
6755        }
6756
6757        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6758        if (trimCount <= 0) return false;
6759
6760        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6761        for (int i = 0; i < trimCount; i++) {
6762            final UriPermission perm = persisted.get(i);
6763
6764            if (DEBUG_URI_PERMISSION) {
6765                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6766            }
6767
6768            perm.releasePersistableModes(~0);
6769            removeUriPermissionIfNeededLocked(perm);
6770        }
6771
6772        return true;
6773    }
6774
6775    @Override
6776    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6777            String packageName, boolean incoming) {
6778        enforceNotIsolatedCaller("getPersistedUriPermissions");
6779        Preconditions.checkNotNull(packageName, "packageName");
6780
6781        final int callingUid = Binder.getCallingUid();
6782        final IPackageManager pm = AppGlobals.getPackageManager();
6783        try {
6784            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6785            if (packageUid != callingUid) {
6786                throw new SecurityException(
6787                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6788            }
6789        } catch (RemoteException e) {
6790            throw new SecurityException("Failed to verify package name ownership");
6791        }
6792
6793        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6794        synchronized (this) {
6795            if (incoming) {
6796                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6797                        callingUid);
6798                if (perms == null) {
6799                    Slog.w(TAG, "No permission grants found for " + packageName);
6800                } else {
6801                    for (UriPermission perm : perms.values()) {
6802                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6803                            result.add(perm.buildPersistedPublicApiObject());
6804                        }
6805                    }
6806                }
6807            } else {
6808                final int size = mGrantedUriPermissions.size();
6809                for (int i = 0; i < size; i++) {
6810                    final ArrayMap<GrantUri, UriPermission> perms =
6811                            mGrantedUriPermissions.valueAt(i);
6812                    for (UriPermission perm : perms.values()) {
6813                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6814                            result.add(perm.buildPersistedPublicApiObject());
6815                        }
6816                    }
6817                }
6818            }
6819        }
6820        return new ParceledListSlice<android.content.UriPermission>(result);
6821    }
6822
6823    @Override
6824    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6825        synchronized (this) {
6826            ProcessRecord app =
6827                who != null ? getRecordForAppLocked(who) : null;
6828            if (app == null) return;
6829
6830            Message msg = Message.obtain();
6831            msg.what = WAIT_FOR_DEBUGGER_MSG;
6832            msg.obj = app;
6833            msg.arg1 = waiting ? 1 : 0;
6834            mHandler.sendMessage(msg);
6835        }
6836    }
6837
6838    @Override
6839    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6840        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6841        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6842        outInfo.availMem = Process.getFreeMemory();
6843        outInfo.totalMem = Process.getTotalMemory();
6844        outInfo.threshold = homeAppMem;
6845        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6846        outInfo.hiddenAppThreshold = cachedAppMem;
6847        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6848                ProcessList.SERVICE_ADJ);
6849        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6850                ProcessList.VISIBLE_APP_ADJ);
6851        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6852                ProcessList.FOREGROUND_APP_ADJ);
6853    }
6854
6855    // =========================================================
6856    // TASK MANAGEMENT
6857    // =========================================================
6858
6859    @Override
6860    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6861                         IThumbnailReceiver receiver) {
6862        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6863
6864        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6865        ActivityRecord topRecord = null;
6866
6867        synchronized(this) {
6868            if (localLOGV) Slog.v(
6869                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6870                + ", receiver=" + receiver);
6871
6872            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6873                    != PackageManager.PERMISSION_GRANTED) {
6874                if (receiver != null) {
6875                    // If the caller wants to wait for pending thumbnails,
6876                    // it ain't gonna get them.
6877                    try {
6878                        receiver.finished();
6879                    } catch (RemoteException ex) {
6880                    }
6881                }
6882                String msg = "Permission Denial: getTasks() from pid="
6883                        + Binder.getCallingPid()
6884                        + ", uid=" + Binder.getCallingUid()
6885                        + " requires " + android.Manifest.permission.GET_TASKS;
6886                Slog.w(TAG, msg);
6887                throw new SecurityException(msg);
6888            }
6889
6890            // TODO: Improve with MRU list from all ActivityStacks.
6891            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6892
6893            if (!pending.pendingRecords.isEmpty()) {
6894                mPendingThumbnails.add(pending);
6895            }
6896        }
6897
6898        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6899
6900        if (topRecord != null) {
6901            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6902            try {
6903                IApplicationThread topThumbnail = topRecord.app.thread;
6904                topThumbnail.requestThumbnail(topRecord.appToken);
6905            } catch (Exception e) {
6906                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6907                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6908            }
6909        }
6910
6911        if (pending.pendingRecords.isEmpty() && receiver != null) {
6912            // In this case all thumbnails were available and the client
6913            // is being asked to be told when the remaining ones come in...
6914            // which is unusually, since the top-most currently running
6915            // activity should never have a canned thumbnail!  Oh well.
6916            try {
6917                receiver.finished();
6918            } catch (RemoteException ex) {
6919            }
6920        }
6921
6922        return list;
6923    }
6924
6925    TaskRecord getMostRecentTask() {
6926        return mRecentTasks.get(0);
6927    }
6928
6929    @Override
6930    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6931            int flags, int userId) {
6932        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6933                false, true, "getRecentTasks", null);
6934
6935        synchronized (this) {
6936            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6937                    "getRecentTasks()");
6938            final boolean detailed = checkCallingPermission(
6939                    android.Manifest.permission.GET_DETAILED_TASKS)
6940                    == PackageManager.PERMISSION_GRANTED;
6941
6942            IPackageManager pm = AppGlobals.getPackageManager();
6943
6944            final int N = mRecentTasks.size();
6945            ArrayList<ActivityManager.RecentTaskInfo> res
6946                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6947                            maxNum < N ? maxNum : N);
6948
6949            final Set<Integer> includedUsers;
6950            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
6951                includedUsers = getProfileIdsLocked(userId);
6952            } else {
6953                includedUsers = new HashSet<Integer>();
6954            }
6955            includedUsers.add(Integer.valueOf(userId));
6956            for (int i=0; i<N && maxNum > 0; i++) {
6957                TaskRecord tr = mRecentTasks.get(i);
6958                // Only add calling user or related users recent tasks
6959                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
6960
6961                // Return the entry if desired by the caller.  We always return
6962                // the first entry, because callers always expect this to be the
6963                // foreground app.  We may filter others if the caller has
6964                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6965                // we should exclude the entry.
6966
6967                if (i == 0
6968                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6969                        || (tr.intent == null)
6970                        || ((tr.intent.getFlags()
6971                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6972                    ActivityManager.RecentTaskInfo rti
6973                            = new ActivityManager.RecentTaskInfo();
6974                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6975                    rti.persistentId = tr.taskId;
6976                    rti.baseIntent = new Intent(
6977                            tr.intent != null ? tr.intent : tr.affinityIntent);
6978                    if (!detailed) {
6979                        rti.baseIntent.replaceExtras((Bundle)null);
6980                    }
6981                    rti.origActivity = tr.origActivity;
6982                    rti.description = tr.lastDescription;
6983                    rti.stackId = tr.stack.mStackId;
6984                    rti.userId = tr.userId;
6985
6986                    // Traverse upwards looking for any break between main task activities and
6987                    // utility activities.
6988                    final ArrayList<ActivityRecord> activities = tr.mActivities;
6989                    int activityNdx;
6990                    final int numActivities = activities.size();
6991                    for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
6992                            ++activityNdx) {
6993                        final ActivityRecord r = activities.get(activityNdx);
6994                        if (r.intent != null &&
6995                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
6996                                        != 0) {
6997                            break;
6998                        }
6999                    }
7000                    // Traverse downwards starting below break looking for set label and icon.
7001                    for (--activityNdx; activityNdx >= 0; --activityNdx) {
7002                        final ActivityRecord r = activities.get(activityNdx);
7003                        if (r.activityLabel != null || r.activityIcon != null) {
7004                            rti.activityLabel = r.activityLabel;
7005                            rti.activityIcon = r.activityIcon;
7006                            break;
7007                        }
7008                    }
7009
7010                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7011                        // Check whether this activity is currently available.
7012                        try {
7013                            if (rti.origActivity != null) {
7014                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7015                                        == null) {
7016                                    continue;
7017                                }
7018                            } else if (rti.baseIntent != null) {
7019                                if (pm.queryIntentActivities(rti.baseIntent,
7020                                        null, 0, userId) == null) {
7021                                    continue;
7022                                }
7023                            }
7024                        } catch (RemoteException e) {
7025                            // Will never happen.
7026                        }
7027                    }
7028
7029                    res.add(rti);
7030                    maxNum--;
7031                }
7032            }
7033            return res;
7034        }
7035    }
7036
7037    private TaskRecord recentTaskForIdLocked(int id) {
7038        final int N = mRecentTasks.size();
7039            for (int i=0; i<N; i++) {
7040                TaskRecord tr = mRecentTasks.get(i);
7041                if (tr.taskId == id) {
7042                    return tr;
7043                }
7044            }
7045            return null;
7046    }
7047
7048    @Override
7049    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7050        synchronized (this) {
7051            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7052                    "getTaskThumbnails()");
7053            TaskRecord tr = recentTaskForIdLocked(id);
7054            if (tr != null) {
7055                return tr.getTaskThumbnailsLocked();
7056            }
7057        }
7058        return null;
7059    }
7060
7061    @Override
7062    public Bitmap getTaskTopThumbnail(int id) {
7063        synchronized (this) {
7064            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7065                    "getTaskTopThumbnail()");
7066            TaskRecord tr = recentTaskForIdLocked(id);
7067            if (tr != null) {
7068                return tr.getTaskTopThumbnailLocked();
7069            }
7070        }
7071        return null;
7072    }
7073
7074    @Override
7075    public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel,
7076            Bitmap activityIcon) {
7077        synchronized (this) {
7078            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7079            if (r != null) {
7080                r.activityLabel = activityLabel.toString();
7081                r.activityIcon = activityIcon;
7082            }
7083        }
7084    }
7085
7086    @Override
7087    public boolean removeSubTask(int taskId, int subTaskIndex) {
7088        synchronized (this) {
7089            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7090                    "removeSubTask()");
7091            long ident = Binder.clearCallingIdentity();
7092            try {
7093                TaskRecord tr = recentTaskForIdLocked(taskId);
7094                if (tr != null) {
7095                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7096                }
7097                return false;
7098            } finally {
7099                Binder.restoreCallingIdentity(ident);
7100            }
7101        }
7102    }
7103
7104    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7105        if (!pr.killedByAm) {
7106            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7107            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7108                    pr.processName, pr.setAdj, reason);
7109            pr.killedByAm = true;
7110            Process.killProcessQuiet(pr.pid);
7111        }
7112    }
7113
7114    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7115        tr.disposeThumbnail();
7116        mRecentTasks.remove(tr);
7117        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7118        Intent baseIntent = new Intent(
7119                tr.intent != null ? tr.intent : tr.affinityIntent);
7120        ComponentName component = baseIntent.getComponent();
7121        if (component == null) {
7122            Slog.w(TAG, "Now component for base intent of task: " + tr);
7123            return;
7124        }
7125
7126        // Find any running services associated with this app.
7127        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7128
7129        if (killProcesses) {
7130            // Find any running processes associated with this app.
7131            final String pkg = component.getPackageName();
7132            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7133            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7134            for (int i=0; i<pmap.size(); i++) {
7135                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7136                for (int j=0; j<uids.size(); j++) {
7137                    ProcessRecord proc = uids.valueAt(j);
7138                    if (proc.userId != tr.userId) {
7139                        continue;
7140                    }
7141                    if (!proc.pkgList.containsKey(pkg)) {
7142                        continue;
7143                    }
7144                    procs.add(proc);
7145                }
7146            }
7147
7148            // Kill the running processes.
7149            for (int i=0; i<procs.size(); i++) {
7150                ProcessRecord pr = procs.get(i);
7151                if (pr == mHomeProcess) {
7152                    // Don't kill the home process along with tasks from the same package.
7153                    continue;
7154                }
7155                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7156                    killUnneededProcessLocked(pr, "remove task");
7157                } else {
7158                    pr.waitingToKill = "remove task";
7159                }
7160            }
7161        }
7162    }
7163
7164    /**
7165     * Removes the task with the specified task id.
7166     *
7167     * @param taskId Identifier of the task to be removed.
7168     * @param flags Additional operational flags.  May be 0 or
7169     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7170     * @return Returns true if the given task was found and removed.
7171     */
7172    private boolean removeTaskByIdLocked(int taskId, int flags) {
7173        TaskRecord tr = recentTaskForIdLocked(taskId);
7174        if (tr != null) {
7175            tr.removeTaskActivitiesLocked(-1, false);
7176            cleanUpRemovedTaskLocked(tr, flags);
7177            return true;
7178        }
7179        return false;
7180    }
7181
7182    @Override
7183    public boolean removeTask(int taskId, int flags) {
7184        synchronized (this) {
7185            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7186                    "removeTask()");
7187            long ident = Binder.clearCallingIdentity();
7188            try {
7189                return removeTaskByIdLocked(taskId, flags);
7190            } finally {
7191                Binder.restoreCallingIdentity(ident);
7192            }
7193        }
7194    }
7195
7196    /**
7197     * TODO: Add mController hook
7198     */
7199    @Override
7200    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7201        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7202                "moveTaskToFront()");
7203
7204        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7205        synchronized(this) {
7206            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7207                    Binder.getCallingUid(), "Task to front")) {
7208                ActivityOptions.abort(options);
7209                return;
7210            }
7211            final long origId = Binder.clearCallingIdentity();
7212            try {
7213                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7214                if (task == null) {
7215                    return;
7216                }
7217                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7218                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7219                    return;
7220                }
7221                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7222            } finally {
7223                Binder.restoreCallingIdentity(origId);
7224            }
7225            ActivityOptions.abort(options);
7226        }
7227    }
7228
7229    @Override
7230    public void moveTaskToBack(int taskId) {
7231        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7232                "moveTaskToBack()");
7233
7234        synchronized(this) {
7235            TaskRecord tr = recentTaskForIdLocked(taskId);
7236            if (tr != null) {
7237                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7238                ActivityStack stack = tr.stack;
7239                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7240                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7241                            Binder.getCallingUid(), "Task to back")) {
7242                        return;
7243                    }
7244                }
7245                final long origId = Binder.clearCallingIdentity();
7246                try {
7247                    stack.moveTaskToBackLocked(taskId, null);
7248                } finally {
7249                    Binder.restoreCallingIdentity(origId);
7250                }
7251            }
7252        }
7253    }
7254
7255    /**
7256     * Moves an activity, and all of the other activities within the same task, to the bottom
7257     * of the history stack.  The activity's order within the task is unchanged.
7258     *
7259     * @param token A reference to the activity we wish to move
7260     * @param nonRoot If false then this only works if the activity is the root
7261     *                of a task; if true it will work for any activity in a task.
7262     * @return Returns true if the move completed, false if not.
7263     */
7264    @Override
7265    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7266        enforceNotIsolatedCaller("moveActivityTaskToBack");
7267        synchronized(this) {
7268            final long origId = Binder.clearCallingIdentity();
7269            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7270            if (taskId >= 0) {
7271                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7272            }
7273            Binder.restoreCallingIdentity(origId);
7274        }
7275        return false;
7276    }
7277
7278    @Override
7279    public void moveTaskBackwards(int task) {
7280        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7281                "moveTaskBackwards()");
7282
7283        synchronized(this) {
7284            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7285                    Binder.getCallingUid(), "Task backwards")) {
7286                return;
7287            }
7288            final long origId = Binder.clearCallingIdentity();
7289            moveTaskBackwardsLocked(task);
7290            Binder.restoreCallingIdentity(origId);
7291        }
7292    }
7293
7294    private final void moveTaskBackwardsLocked(int task) {
7295        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7296    }
7297
7298    @Override
7299    public IBinder getHomeActivityToken() throws RemoteException {
7300        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7301                "getHomeActivityToken()");
7302        synchronized (this) {
7303            return mStackSupervisor.getHomeActivityToken();
7304        }
7305    }
7306
7307    @Override
7308    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7309            IActivityContainerCallback callback) throws RemoteException {
7310        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7311                "createActivityContainer()");
7312        synchronized (this) {
7313            if (parentActivityToken == null) {
7314                throw new IllegalArgumentException("parent token must not be null");
7315            }
7316            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7317            if (r == null) {
7318                return null;
7319            }
7320            if (callback == null) {
7321                throw new IllegalArgumentException("callback must not be null");
7322            }
7323            return mStackSupervisor.createActivityContainer(r, callback);
7324        }
7325    }
7326
7327    @Override
7328    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7329        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7330                "deleteActivityContainer()");
7331        synchronized (this) {
7332            mStackSupervisor.deleteActivityContainer(container);
7333        }
7334    }
7335
7336    @Override
7337    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7338            throws RemoteException {
7339        synchronized (this) {
7340            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7341            if (stack != null) {
7342                return stack.mActivityContainer;
7343            }
7344            return null;
7345        }
7346    }
7347
7348    @Override
7349    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7350        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7351                "moveTaskToStack()");
7352        if (stackId == HOME_STACK_ID) {
7353            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7354                    new RuntimeException("here").fillInStackTrace());
7355        }
7356        synchronized (this) {
7357            long ident = Binder.clearCallingIdentity();
7358            try {
7359                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7360                        + stackId + " toTop=" + toTop);
7361                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7362            } finally {
7363                Binder.restoreCallingIdentity(ident);
7364            }
7365        }
7366    }
7367
7368    @Override
7369    public void resizeStack(int stackBoxId, Rect bounds) {
7370        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7371                "resizeStackBox()");
7372        long ident = Binder.clearCallingIdentity();
7373        try {
7374            mWindowManager.resizeStack(stackBoxId, bounds);
7375        } finally {
7376            Binder.restoreCallingIdentity(ident);
7377        }
7378    }
7379
7380    @Override
7381    public List<StackInfo> getAllStackInfos() {
7382        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7383                "getAllStackInfos()");
7384        long ident = Binder.clearCallingIdentity();
7385        try {
7386            synchronized (this) {
7387                return mStackSupervisor.getAllStackInfosLocked();
7388            }
7389        } finally {
7390            Binder.restoreCallingIdentity(ident);
7391        }
7392    }
7393
7394    @Override
7395    public StackInfo getStackInfo(int stackId) {
7396        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7397                "getStackInfo()");
7398        long ident = Binder.clearCallingIdentity();
7399        try {
7400            synchronized (this) {
7401                return mStackSupervisor.getStackInfoLocked(stackId);
7402            }
7403        } finally {
7404            Binder.restoreCallingIdentity(ident);
7405        }
7406    }
7407
7408    @Override
7409    public boolean isInHomeStack(int taskId) {
7410        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7411                "getStackInfo()");
7412        long ident = Binder.clearCallingIdentity();
7413        try {
7414            synchronized (this) {
7415                TaskRecord tr = recentTaskForIdLocked(taskId);
7416                if (tr != null) {
7417                    return tr.stack.isHomeStack();
7418                }
7419            }
7420        } finally {
7421            Binder.restoreCallingIdentity(ident);
7422        }
7423        return false;
7424    }
7425
7426    @Override
7427    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7428        synchronized(this) {
7429            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7430        }
7431    }
7432
7433    private boolean isLockTaskAuthorized(ComponentName name) {
7434//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7435//                "startLockTaskMode()");
7436//        DevicePolicyManager dpm = (DevicePolicyManager)
7437//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7438//        return dpm != null && dpm.isLockTaskPermitted(name);
7439        return true;
7440    }
7441
7442    private void startLockTaskMode(TaskRecord task) {
7443        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7444            return;
7445        }
7446        long ident = Binder.clearCallingIdentity();
7447        try {
7448            synchronized (this) {
7449                // Since we lost lock on task, make sure it is still there.
7450                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7451                if (task != null) {
7452                    mStackSupervisor.setLockTaskModeLocked(task);
7453                }
7454            }
7455        } finally {
7456            Binder.restoreCallingIdentity(ident);
7457        }
7458    }
7459
7460    @Override
7461    public void startLockTaskMode(int taskId) {
7462        long ident = Binder.clearCallingIdentity();
7463        try {
7464            final TaskRecord task;
7465            synchronized (this) {
7466                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7467            }
7468            if (task != null) {
7469                startLockTaskMode(task);
7470            }
7471        } finally {
7472            Binder.restoreCallingIdentity(ident);
7473        }
7474    }
7475
7476    @Override
7477    public void startLockTaskMode(IBinder token) {
7478        long ident = Binder.clearCallingIdentity();
7479        try {
7480            final TaskRecord task;
7481            synchronized (this) {
7482                final ActivityRecord r = ActivityRecord.forToken(token);
7483                if (r == null) {
7484                    return;
7485                }
7486                task = r.task;
7487            }
7488            if (task != null) {
7489                startLockTaskMode(task);
7490            }
7491        } finally {
7492            Binder.restoreCallingIdentity(ident);
7493        }
7494    }
7495
7496    @Override
7497    public void stopLockTaskMode() {
7498//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7499//                "stopLockTaskMode()");
7500        synchronized (this) {
7501            mStackSupervisor.setLockTaskModeLocked(null);
7502        }
7503    }
7504
7505    @Override
7506    public boolean isInLockTaskMode() {
7507        synchronized (this) {
7508            return mStackSupervisor.isInLockTaskMode();
7509        }
7510    }
7511
7512    // =========================================================
7513    // THUMBNAILS
7514    // =========================================================
7515
7516    public void reportThumbnail(IBinder token,
7517            Bitmap thumbnail, CharSequence description) {
7518        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7519        final long origId = Binder.clearCallingIdentity();
7520        sendPendingThumbnail(null, token, thumbnail, description, true);
7521        Binder.restoreCallingIdentity(origId);
7522    }
7523
7524    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7525            Bitmap thumbnail, CharSequence description, boolean always) {
7526        TaskRecord task;
7527        ArrayList<PendingThumbnailsRecord> receivers = null;
7528
7529        //System.out.println("Send pending thumbnail: " + r);
7530
7531        synchronized(this) {
7532            if (r == null) {
7533                r = ActivityRecord.isInStackLocked(token);
7534                if (r == null) {
7535                    return;
7536                }
7537            }
7538            if (thumbnail == null && r.thumbHolder != null) {
7539                thumbnail = r.thumbHolder.lastThumbnail;
7540                description = r.thumbHolder.lastDescription;
7541            }
7542            if (thumbnail == null && !always) {
7543                // If there is no thumbnail, and this entry is not actually
7544                // going away, then abort for now and pick up the next
7545                // thumbnail we get.
7546                return;
7547            }
7548            task = r.task;
7549
7550            int N = mPendingThumbnails.size();
7551            int i=0;
7552            while (i<N) {
7553                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7554                //System.out.println("Looking in " + pr.pendingRecords);
7555                if (pr.pendingRecords.remove(r)) {
7556                    if (receivers == null) {
7557                        receivers = new ArrayList<PendingThumbnailsRecord>();
7558                    }
7559                    receivers.add(pr);
7560                    if (pr.pendingRecords.size() == 0) {
7561                        pr.finished = true;
7562                        mPendingThumbnails.remove(i);
7563                        N--;
7564                        continue;
7565                    }
7566                }
7567                i++;
7568            }
7569        }
7570
7571        if (receivers != null) {
7572            final int N = receivers.size();
7573            for (int i=0; i<N; i++) {
7574                try {
7575                    PendingThumbnailsRecord pr = receivers.get(i);
7576                    pr.receiver.newThumbnail(
7577                        task != null ? task.taskId : -1, thumbnail, description);
7578                    if (pr.finished) {
7579                        pr.receiver.finished();
7580                    }
7581                } catch (Exception e) {
7582                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7583                }
7584            }
7585        }
7586    }
7587
7588    // =========================================================
7589    // CONTENT PROVIDERS
7590    // =========================================================
7591
7592    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7593        List<ProviderInfo> providers = null;
7594        try {
7595            providers = AppGlobals.getPackageManager().
7596                queryContentProviders(app.processName, app.uid,
7597                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7598        } catch (RemoteException ex) {
7599        }
7600        if (DEBUG_MU)
7601            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7602        int userId = app.userId;
7603        if (providers != null) {
7604            int N = providers.size();
7605            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7606            for (int i=0; i<N; i++) {
7607                ProviderInfo cpi =
7608                    (ProviderInfo)providers.get(i);
7609                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7610                        cpi.name, cpi.flags);
7611                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7612                    // This is a singleton provider, but a user besides the
7613                    // default user is asking to initialize a process it runs
7614                    // in...  well, no, it doesn't actually run in this process,
7615                    // it runs in the process of the default user.  Get rid of it.
7616                    providers.remove(i);
7617                    N--;
7618                    i--;
7619                    continue;
7620                }
7621
7622                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7623                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7624                if (cpr == null) {
7625                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7626                    mProviderMap.putProviderByClass(comp, cpr);
7627                }
7628                if (DEBUG_MU)
7629                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7630                app.pubProviders.put(cpi.name, cpr);
7631                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7632                    // Don't add this if it is a platform component that is marked
7633                    // to run in multiple processes, because this is actually
7634                    // part of the framework so doesn't make sense to track as a
7635                    // separate apk in the process.
7636                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7637                }
7638                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7639            }
7640        }
7641        return providers;
7642    }
7643
7644    /**
7645     * Check if {@link ProcessRecord} has a possible chance at accessing the
7646     * given {@link ProviderInfo}. Final permission checking is always done
7647     * in {@link ContentProvider}.
7648     */
7649    private final String checkContentProviderPermissionLocked(
7650            ProviderInfo cpi, ProcessRecord r) {
7651        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7652        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7653        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7654                cpi.applicationInfo.uid, cpi.exported)
7655                == PackageManager.PERMISSION_GRANTED) {
7656            return null;
7657        }
7658        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7659                cpi.applicationInfo.uid, cpi.exported)
7660                == PackageManager.PERMISSION_GRANTED) {
7661            return null;
7662        }
7663
7664        PathPermission[] pps = cpi.pathPermissions;
7665        if (pps != null) {
7666            int i = pps.length;
7667            while (i > 0) {
7668                i--;
7669                PathPermission pp = pps[i];
7670                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7671                        cpi.applicationInfo.uid, cpi.exported)
7672                        == PackageManager.PERMISSION_GRANTED) {
7673                    return null;
7674                }
7675                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7676                        cpi.applicationInfo.uid, cpi.exported)
7677                        == PackageManager.PERMISSION_GRANTED) {
7678                    return null;
7679                }
7680            }
7681        }
7682
7683        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7684        if (perms != null) {
7685            for (GrantUri uri : perms.keySet()) {
7686                if (uri.uri.getAuthority().equals(cpi.authority)) {
7687                    return null;
7688                }
7689            }
7690        }
7691
7692        String msg;
7693        if (!cpi.exported) {
7694            msg = "Permission Denial: opening provider " + cpi.name
7695                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7696                    + ", uid=" + callingUid + ") that is not exported from uid "
7697                    + cpi.applicationInfo.uid;
7698        } else {
7699            msg = "Permission Denial: opening provider " + cpi.name
7700                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7701                    + ", uid=" + callingUid + ") requires "
7702                    + cpi.readPermission + " or " + cpi.writePermission;
7703        }
7704        Slog.w(TAG, msg);
7705        return msg;
7706    }
7707
7708    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7709            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7710        if (r != null) {
7711            for (int i=0; i<r.conProviders.size(); i++) {
7712                ContentProviderConnection conn = r.conProviders.get(i);
7713                if (conn.provider == cpr) {
7714                    if (DEBUG_PROVIDER) Slog.v(TAG,
7715                            "Adding provider requested by "
7716                            + r.processName + " from process "
7717                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7718                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7719                    if (stable) {
7720                        conn.stableCount++;
7721                        conn.numStableIncs++;
7722                    } else {
7723                        conn.unstableCount++;
7724                        conn.numUnstableIncs++;
7725                    }
7726                    return conn;
7727                }
7728            }
7729            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7730            if (stable) {
7731                conn.stableCount = 1;
7732                conn.numStableIncs = 1;
7733            } else {
7734                conn.unstableCount = 1;
7735                conn.numUnstableIncs = 1;
7736            }
7737            cpr.connections.add(conn);
7738            r.conProviders.add(conn);
7739            return conn;
7740        }
7741        cpr.addExternalProcessHandleLocked(externalProcessToken);
7742        return null;
7743    }
7744
7745    boolean decProviderCountLocked(ContentProviderConnection conn,
7746            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7747        if (conn != null) {
7748            cpr = conn.provider;
7749            if (DEBUG_PROVIDER) Slog.v(TAG,
7750                    "Removing provider requested by "
7751                    + conn.client.processName + " from process "
7752                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7753                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7754            if (stable) {
7755                conn.stableCount--;
7756            } else {
7757                conn.unstableCount--;
7758            }
7759            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7760                cpr.connections.remove(conn);
7761                conn.client.conProviders.remove(conn);
7762                return true;
7763            }
7764            return false;
7765        }
7766        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7767        return false;
7768    }
7769
7770    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7771            String name, IBinder token, boolean stable, int userId) {
7772        ContentProviderRecord cpr;
7773        ContentProviderConnection conn = null;
7774        ProviderInfo cpi = null;
7775
7776        synchronized(this) {
7777            ProcessRecord r = null;
7778            if (caller != null) {
7779                r = getRecordForAppLocked(caller);
7780                if (r == null) {
7781                    throw new SecurityException(
7782                            "Unable to find app for caller " + caller
7783                          + " (pid=" + Binder.getCallingPid()
7784                          + ") when getting content provider " + name);
7785                }
7786            }
7787
7788            // First check if this content provider has been published...
7789            cpr = mProviderMap.getProviderByName(name, userId);
7790            boolean providerRunning = cpr != null;
7791            if (providerRunning) {
7792                cpi = cpr.info;
7793                String msg;
7794                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7795                    throw new SecurityException(msg);
7796                }
7797
7798                if (r != null && cpr.canRunHere(r)) {
7799                    // This provider has been published or is in the process
7800                    // of being published...  but it is also allowed to run
7801                    // in the caller's process, so don't make a connection
7802                    // and just let the caller instantiate its own instance.
7803                    ContentProviderHolder holder = cpr.newHolder(null);
7804                    // don't give caller the provider object, it needs
7805                    // to make its own.
7806                    holder.provider = null;
7807                    return holder;
7808                }
7809
7810                final long origId = Binder.clearCallingIdentity();
7811
7812                // In this case the provider instance already exists, so we can
7813                // return it right away.
7814                conn = incProviderCountLocked(r, cpr, token, stable);
7815                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7816                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7817                        // If this is a perceptible app accessing the provider,
7818                        // make sure to count it as being accessed and thus
7819                        // back up on the LRU list.  This is good because
7820                        // content providers are often expensive to start.
7821                        updateLruProcessLocked(cpr.proc, false, null);
7822                    }
7823                }
7824
7825                if (cpr.proc != null) {
7826                    if (false) {
7827                        if (cpr.name.flattenToShortString().equals(
7828                                "com.android.providers.calendar/.CalendarProvider2")) {
7829                            Slog.v(TAG, "****************** KILLING "
7830                                + cpr.name.flattenToShortString());
7831                            Process.killProcess(cpr.proc.pid);
7832                        }
7833                    }
7834                    boolean success = updateOomAdjLocked(cpr.proc);
7835                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7836                    // NOTE: there is still a race here where a signal could be
7837                    // pending on the process even though we managed to update its
7838                    // adj level.  Not sure what to do about this, but at least
7839                    // the race is now smaller.
7840                    if (!success) {
7841                        // Uh oh...  it looks like the provider's process
7842                        // has been killed on us.  We need to wait for a new
7843                        // process to be started, and make sure its death
7844                        // doesn't kill our process.
7845                        Slog.i(TAG,
7846                                "Existing provider " + cpr.name.flattenToShortString()
7847                                + " is crashing; detaching " + r);
7848                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7849                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7850                        if (!lastRef) {
7851                            // This wasn't the last ref our process had on
7852                            // the provider...  we have now been killed, bail.
7853                            return null;
7854                        }
7855                        providerRunning = false;
7856                        conn = null;
7857                    }
7858                }
7859
7860                Binder.restoreCallingIdentity(origId);
7861            }
7862
7863            boolean singleton;
7864            if (!providerRunning) {
7865                try {
7866                    cpi = AppGlobals.getPackageManager().
7867                        resolveContentProvider(name,
7868                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7869                } catch (RemoteException ex) {
7870                }
7871                if (cpi == null) {
7872                    return null;
7873                }
7874                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7875                        cpi.name, cpi.flags);
7876                if (singleton) {
7877                    userId = 0;
7878                }
7879                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7880
7881                String msg;
7882                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7883                    throw new SecurityException(msg);
7884                }
7885
7886                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7887                        && !cpi.processName.equals("system")) {
7888                    // If this content provider does not run in the system
7889                    // process, and the system is not yet ready to run other
7890                    // processes, then fail fast instead of hanging.
7891                    throw new IllegalArgumentException(
7892                            "Attempt to launch content provider before system ready");
7893                }
7894
7895                // Make sure that the user who owns this provider is started.  If not,
7896                // we don't want to allow it to run.
7897                if (mStartedUsers.get(userId) == null) {
7898                    Slog.w(TAG, "Unable to launch app "
7899                            + cpi.applicationInfo.packageName + "/"
7900                            + cpi.applicationInfo.uid + " for provider "
7901                            + name + ": user " + userId + " is stopped");
7902                    return null;
7903                }
7904
7905                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7906                cpr = mProviderMap.getProviderByClass(comp, userId);
7907                final boolean firstClass = cpr == null;
7908                if (firstClass) {
7909                    try {
7910                        ApplicationInfo ai =
7911                            AppGlobals.getPackageManager().
7912                                getApplicationInfo(
7913                                        cpi.applicationInfo.packageName,
7914                                        STOCK_PM_FLAGS, userId);
7915                        if (ai == null) {
7916                            Slog.w(TAG, "No package info for content provider "
7917                                    + cpi.name);
7918                            return null;
7919                        }
7920                        ai = getAppInfoForUser(ai, userId);
7921                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7922                    } catch (RemoteException ex) {
7923                        // pm is in same process, this will never happen.
7924                    }
7925                }
7926
7927                if (r != null && cpr.canRunHere(r)) {
7928                    // If this is a multiprocess provider, then just return its
7929                    // info and allow the caller to instantiate it.  Only do
7930                    // this if the provider is the same user as the caller's
7931                    // process, or can run as root (so can be in any process).
7932                    return cpr.newHolder(null);
7933                }
7934
7935                if (DEBUG_PROVIDER) {
7936                    RuntimeException e = new RuntimeException("here");
7937                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7938                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7939                }
7940
7941                // This is single process, and our app is now connecting to it.
7942                // See if we are already in the process of launching this
7943                // provider.
7944                final int N = mLaunchingProviders.size();
7945                int i;
7946                for (i=0; i<N; i++) {
7947                    if (mLaunchingProviders.get(i) == cpr) {
7948                        break;
7949                    }
7950                }
7951
7952                // If the provider is not already being launched, then get it
7953                // started.
7954                if (i >= N) {
7955                    final long origId = Binder.clearCallingIdentity();
7956
7957                    try {
7958                        // Content provider is now in use, its package can't be stopped.
7959                        try {
7960                            AppGlobals.getPackageManager().setPackageStoppedState(
7961                                    cpr.appInfo.packageName, false, userId);
7962                        } catch (RemoteException e) {
7963                        } catch (IllegalArgumentException e) {
7964                            Slog.w(TAG, "Failed trying to unstop package "
7965                                    + cpr.appInfo.packageName + ": " + e);
7966                        }
7967
7968                        // Use existing process if already started
7969                        ProcessRecord proc = getProcessRecordLocked(
7970                                cpi.processName, cpr.appInfo.uid, false);
7971                        if (proc != null && proc.thread != null) {
7972                            if (DEBUG_PROVIDER) {
7973                                Slog.d(TAG, "Installing in existing process " + proc);
7974                            }
7975                            proc.pubProviders.put(cpi.name, cpr);
7976                            try {
7977                                proc.thread.scheduleInstallProvider(cpi);
7978                            } catch (RemoteException e) {
7979                            }
7980                        } else {
7981                            proc = startProcessLocked(cpi.processName,
7982                                    cpr.appInfo, false, 0, "content provider",
7983                                    new ComponentName(cpi.applicationInfo.packageName,
7984                                            cpi.name), false, false, false);
7985                            if (proc == null) {
7986                                Slog.w(TAG, "Unable to launch app "
7987                                        + cpi.applicationInfo.packageName + "/"
7988                                        + cpi.applicationInfo.uid + " for provider "
7989                                        + name + ": process is bad");
7990                                return null;
7991                            }
7992                        }
7993                        cpr.launchingApp = proc;
7994                        mLaunchingProviders.add(cpr);
7995                    } finally {
7996                        Binder.restoreCallingIdentity(origId);
7997                    }
7998                }
7999
8000                // Make sure the provider is published (the same provider class
8001                // may be published under multiple names).
8002                if (firstClass) {
8003                    mProviderMap.putProviderByClass(comp, cpr);
8004                }
8005
8006                mProviderMap.putProviderByName(name, cpr);
8007                conn = incProviderCountLocked(r, cpr, token, stable);
8008                if (conn != null) {
8009                    conn.waiting = true;
8010                }
8011            }
8012        }
8013
8014        // Wait for the provider to be published...
8015        synchronized (cpr) {
8016            while (cpr.provider == null) {
8017                if (cpr.launchingApp == null) {
8018                    Slog.w(TAG, "Unable to launch app "
8019                            + cpi.applicationInfo.packageName + "/"
8020                            + cpi.applicationInfo.uid + " for provider "
8021                            + name + ": launching app became null");
8022                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8023                            UserHandle.getUserId(cpi.applicationInfo.uid),
8024                            cpi.applicationInfo.packageName,
8025                            cpi.applicationInfo.uid, name);
8026                    return null;
8027                }
8028                try {
8029                    if (DEBUG_MU) {
8030                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8031                                + cpr.launchingApp);
8032                    }
8033                    if (conn != null) {
8034                        conn.waiting = true;
8035                    }
8036                    cpr.wait();
8037                } catch (InterruptedException ex) {
8038                } finally {
8039                    if (conn != null) {
8040                        conn.waiting = false;
8041                    }
8042                }
8043            }
8044        }
8045        return cpr != null ? cpr.newHolder(conn) : null;
8046    }
8047
8048    public final ContentProviderHolder getContentProvider(
8049            IApplicationThread caller, String name, int userId, boolean stable) {
8050        enforceNotIsolatedCaller("getContentProvider");
8051        if (caller == null) {
8052            String msg = "null IApplicationThread when getting content provider "
8053                    + name;
8054            Slog.w(TAG, msg);
8055            throw new SecurityException(msg);
8056        }
8057
8058        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8059                false, true, "getContentProvider", null);
8060        return getContentProviderImpl(caller, name, null, stable, userId);
8061    }
8062
8063    public ContentProviderHolder getContentProviderExternal(
8064            String name, int userId, IBinder token) {
8065        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8066            "Do not have permission in call getContentProviderExternal()");
8067        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8068                false, true, "getContentProvider", null);
8069        return getContentProviderExternalUnchecked(name, token, userId);
8070    }
8071
8072    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8073            IBinder token, int userId) {
8074        return getContentProviderImpl(null, name, token, true, userId);
8075    }
8076
8077    /**
8078     * Drop a content provider from a ProcessRecord's bookkeeping
8079     */
8080    public void removeContentProvider(IBinder connection, boolean stable) {
8081        enforceNotIsolatedCaller("removeContentProvider");
8082        long ident = Binder.clearCallingIdentity();
8083        try {
8084            synchronized (this) {
8085                ContentProviderConnection conn;
8086                try {
8087                    conn = (ContentProviderConnection)connection;
8088                } catch (ClassCastException e) {
8089                    String msg ="removeContentProvider: " + connection
8090                            + " not a ContentProviderConnection";
8091                    Slog.w(TAG, msg);
8092                    throw new IllegalArgumentException(msg);
8093                }
8094                if (conn == null) {
8095                    throw new NullPointerException("connection is null");
8096                }
8097                if (decProviderCountLocked(conn, null, null, stable)) {
8098                    updateOomAdjLocked();
8099                }
8100            }
8101        } finally {
8102            Binder.restoreCallingIdentity(ident);
8103        }
8104    }
8105
8106    public void removeContentProviderExternal(String name, IBinder token) {
8107        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8108            "Do not have permission in call removeContentProviderExternal()");
8109        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8110    }
8111
8112    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8113        synchronized (this) {
8114            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8115            if(cpr == null) {
8116                //remove from mProvidersByClass
8117                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8118                return;
8119            }
8120
8121            //update content provider record entry info
8122            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8123            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8124            if (localCpr.hasExternalProcessHandles()) {
8125                if (localCpr.removeExternalProcessHandleLocked(token)) {
8126                    updateOomAdjLocked();
8127                } else {
8128                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8129                            + " with no external reference for token: "
8130                            + token + ".");
8131                }
8132            } else {
8133                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8134                        + " with no external references.");
8135            }
8136        }
8137    }
8138
8139    public final void publishContentProviders(IApplicationThread caller,
8140            List<ContentProviderHolder> providers) {
8141        if (providers == null) {
8142            return;
8143        }
8144
8145        enforceNotIsolatedCaller("publishContentProviders");
8146        synchronized (this) {
8147            final ProcessRecord r = getRecordForAppLocked(caller);
8148            if (DEBUG_MU)
8149                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8150            if (r == null) {
8151                throw new SecurityException(
8152                        "Unable to find app for caller " + caller
8153                      + " (pid=" + Binder.getCallingPid()
8154                      + ") when publishing content providers");
8155            }
8156
8157            final long origId = Binder.clearCallingIdentity();
8158
8159            final int N = providers.size();
8160            for (int i=0; i<N; i++) {
8161                ContentProviderHolder src = providers.get(i);
8162                if (src == null || src.info == null || src.provider == null) {
8163                    continue;
8164                }
8165                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8166                if (DEBUG_MU)
8167                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8168                if (dst != null) {
8169                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8170                    mProviderMap.putProviderByClass(comp, dst);
8171                    String names[] = dst.info.authority.split(";");
8172                    for (int j = 0; j < names.length; j++) {
8173                        mProviderMap.putProviderByName(names[j], dst);
8174                    }
8175
8176                    int NL = mLaunchingProviders.size();
8177                    int j;
8178                    for (j=0; j<NL; j++) {
8179                        if (mLaunchingProviders.get(j) == dst) {
8180                            mLaunchingProviders.remove(j);
8181                            j--;
8182                            NL--;
8183                        }
8184                    }
8185                    synchronized (dst) {
8186                        dst.provider = src.provider;
8187                        dst.proc = r;
8188                        dst.notifyAll();
8189                    }
8190                    updateOomAdjLocked(r);
8191                }
8192            }
8193
8194            Binder.restoreCallingIdentity(origId);
8195        }
8196    }
8197
8198    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8199        ContentProviderConnection conn;
8200        try {
8201            conn = (ContentProviderConnection)connection;
8202        } catch (ClassCastException e) {
8203            String msg ="refContentProvider: " + connection
8204                    + " not a ContentProviderConnection";
8205            Slog.w(TAG, msg);
8206            throw new IllegalArgumentException(msg);
8207        }
8208        if (conn == null) {
8209            throw new NullPointerException("connection is null");
8210        }
8211
8212        synchronized (this) {
8213            if (stable > 0) {
8214                conn.numStableIncs += stable;
8215            }
8216            stable = conn.stableCount + stable;
8217            if (stable < 0) {
8218                throw new IllegalStateException("stableCount < 0: " + stable);
8219            }
8220
8221            if (unstable > 0) {
8222                conn.numUnstableIncs += unstable;
8223            }
8224            unstable = conn.unstableCount + unstable;
8225            if (unstable < 0) {
8226                throw new IllegalStateException("unstableCount < 0: " + unstable);
8227            }
8228
8229            if ((stable+unstable) <= 0) {
8230                throw new IllegalStateException("ref counts can't go to zero here: stable="
8231                        + stable + " unstable=" + unstable);
8232            }
8233            conn.stableCount = stable;
8234            conn.unstableCount = unstable;
8235            return !conn.dead;
8236        }
8237    }
8238
8239    public void unstableProviderDied(IBinder connection) {
8240        ContentProviderConnection conn;
8241        try {
8242            conn = (ContentProviderConnection)connection;
8243        } catch (ClassCastException e) {
8244            String msg ="refContentProvider: " + connection
8245                    + " not a ContentProviderConnection";
8246            Slog.w(TAG, msg);
8247            throw new IllegalArgumentException(msg);
8248        }
8249        if (conn == null) {
8250            throw new NullPointerException("connection is null");
8251        }
8252
8253        // Safely retrieve the content provider associated with the connection.
8254        IContentProvider provider;
8255        synchronized (this) {
8256            provider = conn.provider.provider;
8257        }
8258
8259        if (provider == null) {
8260            // Um, yeah, we're way ahead of you.
8261            return;
8262        }
8263
8264        // Make sure the caller is being honest with us.
8265        if (provider.asBinder().pingBinder()) {
8266            // Er, no, still looks good to us.
8267            synchronized (this) {
8268                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8269                        + " says " + conn + " died, but we don't agree");
8270                return;
8271            }
8272        }
8273
8274        // Well look at that!  It's dead!
8275        synchronized (this) {
8276            if (conn.provider.provider != provider) {
8277                // But something changed...  good enough.
8278                return;
8279            }
8280
8281            ProcessRecord proc = conn.provider.proc;
8282            if (proc == null || proc.thread == null) {
8283                // Seems like the process is already cleaned up.
8284                return;
8285            }
8286
8287            // As far as we're concerned, this is just like receiving a
8288            // death notification...  just a bit prematurely.
8289            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8290                    + ") early provider death");
8291            final long ident = Binder.clearCallingIdentity();
8292            try {
8293                appDiedLocked(proc, proc.pid, proc.thread);
8294            } finally {
8295                Binder.restoreCallingIdentity(ident);
8296            }
8297        }
8298    }
8299
8300    @Override
8301    public void appNotRespondingViaProvider(IBinder connection) {
8302        enforceCallingPermission(
8303                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8304
8305        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8306        if (conn == null) {
8307            Slog.w(TAG, "ContentProviderConnection is null");
8308            return;
8309        }
8310
8311        final ProcessRecord host = conn.provider.proc;
8312        if (host == null) {
8313            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8314            return;
8315        }
8316
8317        final long token = Binder.clearCallingIdentity();
8318        try {
8319            appNotResponding(host, null, null, false, "ContentProvider not responding");
8320        } finally {
8321            Binder.restoreCallingIdentity(token);
8322        }
8323    }
8324
8325    public final void installSystemProviders() {
8326        List<ProviderInfo> providers;
8327        synchronized (this) {
8328            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8329            providers = generateApplicationProvidersLocked(app);
8330            if (providers != null) {
8331                for (int i=providers.size()-1; i>=0; i--) {
8332                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8333                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8334                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8335                                + ": not system .apk");
8336                        providers.remove(i);
8337                    }
8338                }
8339            }
8340        }
8341        if (providers != null) {
8342            mSystemThread.installSystemProviders(providers);
8343        }
8344
8345        mCoreSettingsObserver = new CoreSettingsObserver(this);
8346
8347        mUsageStatsService.monitorPackages();
8348    }
8349
8350    /**
8351     * Allows app to retrieve the MIME type of a URI without having permission
8352     * to access its content provider.
8353     *
8354     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8355     *
8356     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8357     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8358     */
8359    public String getProviderMimeType(Uri uri, int userId) {
8360        enforceNotIsolatedCaller("getProviderMimeType");
8361        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8362                userId, false, true, "getProviderMimeType", null);
8363        final String name = uri.getAuthority();
8364        final long ident = Binder.clearCallingIdentity();
8365        ContentProviderHolder holder = null;
8366
8367        try {
8368            holder = getContentProviderExternalUnchecked(name, null, userId);
8369            if (holder != null) {
8370                return holder.provider.getType(uri);
8371            }
8372        } catch (RemoteException e) {
8373            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8374            return null;
8375        } finally {
8376            if (holder != null) {
8377                removeContentProviderExternalUnchecked(name, null, userId);
8378            }
8379            Binder.restoreCallingIdentity(ident);
8380        }
8381
8382        return null;
8383    }
8384
8385    // =========================================================
8386    // GLOBAL MANAGEMENT
8387    // =========================================================
8388
8389    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8390            boolean isolated) {
8391        String proc = customProcess != null ? customProcess : info.processName;
8392        BatteryStatsImpl.Uid.Proc ps = null;
8393        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8394        int uid = info.uid;
8395        if (isolated) {
8396            int userId = UserHandle.getUserId(uid);
8397            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8398            while (true) {
8399                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8400                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8401                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8402                }
8403                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8404                mNextIsolatedProcessUid++;
8405                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8406                    // No process for this uid, use it.
8407                    break;
8408                }
8409                stepsLeft--;
8410                if (stepsLeft <= 0) {
8411                    return null;
8412                }
8413            }
8414        }
8415        return new ProcessRecord(stats, info, proc, uid);
8416    }
8417
8418    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8419        ProcessRecord app;
8420        if (!isolated) {
8421            app = getProcessRecordLocked(info.processName, info.uid, true);
8422        } else {
8423            app = null;
8424        }
8425
8426        if (app == null) {
8427            app = newProcessRecordLocked(info, null, isolated);
8428            mProcessNames.put(info.processName, app.uid, app);
8429            if (isolated) {
8430                mIsolatedProcesses.put(app.uid, app);
8431            }
8432            updateLruProcessLocked(app, false, null);
8433            updateOomAdjLocked();
8434        }
8435
8436        // This package really, really can not be stopped.
8437        try {
8438            AppGlobals.getPackageManager().setPackageStoppedState(
8439                    info.packageName, false, UserHandle.getUserId(app.uid));
8440        } catch (RemoteException e) {
8441        } catch (IllegalArgumentException e) {
8442            Slog.w(TAG, "Failed trying to unstop package "
8443                    + info.packageName + ": " + e);
8444        }
8445
8446        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8447                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8448            app.persistent = true;
8449            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8450        }
8451        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8452            mPersistentStartingProcesses.add(app);
8453            startProcessLocked(app, "added application", app.processName);
8454        }
8455
8456        return app;
8457    }
8458
8459    public void unhandledBack() {
8460        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8461                "unhandledBack()");
8462
8463        synchronized(this) {
8464            final long origId = Binder.clearCallingIdentity();
8465            try {
8466                getFocusedStack().unhandledBackLocked();
8467            } finally {
8468                Binder.restoreCallingIdentity(origId);
8469            }
8470        }
8471    }
8472
8473    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8474        enforceNotIsolatedCaller("openContentUri");
8475        final int userId = UserHandle.getCallingUserId();
8476        String name = uri.getAuthority();
8477        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8478        ParcelFileDescriptor pfd = null;
8479        if (cph != null) {
8480            // We record the binder invoker's uid in thread-local storage before
8481            // going to the content provider to open the file.  Later, in the code
8482            // that handles all permissions checks, we look for this uid and use
8483            // that rather than the Activity Manager's own uid.  The effect is that
8484            // we do the check against the caller's permissions even though it looks
8485            // to the content provider like the Activity Manager itself is making
8486            // the request.
8487            sCallerIdentity.set(new Identity(
8488                    Binder.getCallingPid(), Binder.getCallingUid()));
8489            try {
8490                pfd = cph.provider.openFile(null, uri, "r", null);
8491            } catch (FileNotFoundException e) {
8492                // do nothing; pfd will be returned null
8493            } finally {
8494                // Ensure that whatever happens, we clean up the identity state
8495                sCallerIdentity.remove();
8496            }
8497
8498            // We've got the fd now, so we're done with the provider.
8499            removeContentProviderExternalUnchecked(name, null, userId);
8500        } else {
8501            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8502        }
8503        return pfd;
8504    }
8505
8506    // Actually is sleeping or shutting down or whatever else in the future
8507    // is an inactive state.
8508    public boolean isSleepingOrShuttingDown() {
8509        return mSleeping || mShuttingDown;
8510    }
8511
8512    void goingToSleep() {
8513        synchronized(this) {
8514            mWentToSleep = true;
8515            updateEventDispatchingLocked();
8516
8517            if (!mSleeping) {
8518                mSleeping = true;
8519                mStackSupervisor.goingToSleepLocked();
8520
8521                // Initialize the wake times of all processes.
8522                checkExcessivePowerUsageLocked(false);
8523                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8524                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8525                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8526            }
8527        }
8528    }
8529
8530    @Override
8531    public boolean shutdown(int timeout) {
8532        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8533                != PackageManager.PERMISSION_GRANTED) {
8534            throw new SecurityException("Requires permission "
8535                    + android.Manifest.permission.SHUTDOWN);
8536        }
8537
8538        boolean timedout = false;
8539
8540        synchronized(this) {
8541            mShuttingDown = true;
8542            updateEventDispatchingLocked();
8543            timedout = mStackSupervisor.shutdownLocked(timeout);
8544        }
8545
8546        mAppOpsService.shutdown();
8547        mUsageStatsService.shutdown();
8548        mBatteryStatsService.shutdown();
8549        synchronized (this) {
8550            mProcessStats.shutdownLocked();
8551        }
8552
8553        return timedout;
8554    }
8555
8556    public final void activitySlept(IBinder token) {
8557        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8558
8559        final long origId = Binder.clearCallingIdentity();
8560
8561        synchronized (this) {
8562            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8563            if (r != null) {
8564                mStackSupervisor.activitySleptLocked(r);
8565            }
8566        }
8567
8568        Binder.restoreCallingIdentity(origId);
8569    }
8570
8571    void logLockScreen(String msg) {
8572        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8573                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8574                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8575                mStackSupervisor.mDismissKeyguardOnNextActivity);
8576    }
8577
8578    private void comeOutOfSleepIfNeededLocked() {
8579        if (!mWentToSleep && !mLockScreenShown) {
8580            if (mSleeping) {
8581                mSleeping = false;
8582                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8583            }
8584        }
8585    }
8586
8587    void wakingUp() {
8588        synchronized(this) {
8589            mWentToSleep = false;
8590            updateEventDispatchingLocked();
8591            comeOutOfSleepIfNeededLocked();
8592        }
8593    }
8594
8595    private void updateEventDispatchingLocked() {
8596        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8597    }
8598
8599    public void setLockScreenShown(boolean shown) {
8600        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8601                != PackageManager.PERMISSION_GRANTED) {
8602            throw new SecurityException("Requires permission "
8603                    + android.Manifest.permission.DEVICE_POWER);
8604        }
8605
8606        synchronized(this) {
8607            long ident = Binder.clearCallingIdentity();
8608            try {
8609                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8610                mLockScreenShown = shown;
8611                comeOutOfSleepIfNeededLocked();
8612            } finally {
8613                Binder.restoreCallingIdentity(ident);
8614            }
8615        }
8616    }
8617
8618    public void stopAppSwitches() {
8619        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8620                != PackageManager.PERMISSION_GRANTED) {
8621            throw new SecurityException("Requires permission "
8622                    + android.Manifest.permission.STOP_APP_SWITCHES);
8623        }
8624
8625        synchronized(this) {
8626            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8627                    + APP_SWITCH_DELAY_TIME;
8628            mDidAppSwitch = false;
8629            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8630            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8631            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8632        }
8633    }
8634
8635    public void resumeAppSwitches() {
8636        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8637                != PackageManager.PERMISSION_GRANTED) {
8638            throw new SecurityException("Requires permission "
8639                    + android.Manifest.permission.STOP_APP_SWITCHES);
8640        }
8641
8642        synchronized(this) {
8643            // Note that we don't execute any pending app switches... we will
8644            // let those wait until either the timeout, or the next start
8645            // activity request.
8646            mAppSwitchesAllowedTime = 0;
8647        }
8648    }
8649
8650    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8651            String name) {
8652        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8653            return true;
8654        }
8655
8656        final int perm = checkComponentPermission(
8657                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8658                callingUid, -1, true);
8659        if (perm == PackageManager.PERMISSION_GRANTED) {
8660            return true;
8661        }
8662
8663        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8664        return false;
8665    }
8666
8667    public void setDebugApp(String packageName, boolean waitForDebugger,
8668            boolean persistent) {
8669        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8670                "setDebugApp()");
8671
8672        long ident = Binder.clearCallingIdentity();
8673        try {
8674            // Note that this is not really thread safe if there are multiple
8675            // callers into it at the same time, but that's not a situation we
8676            // care about.
8677            if (persistent) {
8678                final ContentResolver resolver = mContext.getContentResolver();
8679                Settings.Global.putString(
8680                    resolver, Settings.Global.DEBUG_APP,
8681                    packageName);
8682                Settings.Global.putInt(
8683                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8684                    waitForDebugger ? 1 : 0);
8685            }
8686
8687            synchronized (this) {
8688                if (!persistent) {
8689                    mOrigDebugApp = mDebugApp;
8690                    mOrigWaitForDebugger = mWaitForDebugger;
8691                }
8692                mDebugApp = packageName;
8693                mWaitForDebugger = waitForDebugger;
8694                mDebugTransient = !persistent;
8695                if (packageName != null) {
8696                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8697                            false, UserHandle.USER_ALL, "set debug app");
8698                }
8699            }
8700        } finally {
8701            Binder.restoreCallingIdentity(ident);
8702        }
8703    }
8704
8705    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8706        synchronized (this) {
8707            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8708            if (!isDebuggable) {
8709                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8710                    throw new SecurityException("Process not debuggable: " + app.packageName);
8711                }
8712            }
8713
8714            mOpenGlTraceApp = processName;
8715        }
8716    }
8717
8718    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8719            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8720        synchronized (this) {
8721            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8722            if (!isDebuggable) {
8723                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8724                    throw new SecurityException("Process not debuggable: " + app.packageName);
8725                }
8726            }
8727            mProfileApp = processName;
8728            mProfileFile = profileFile;
8729            if (mProfileFd != null) {
8730                try {
8731                    mProfileFd.close();
8732                } catch (IOException e) {
8733                }
8734                mProfileFd = null;
8735            }
8736            mProfileFd = profileFd;
8737            mProfileType = 0;
8738            mAutoStopProfiler = autoStopProfiler;
8739        }
8740    }
8741
8742    @Override
8743    public void setAlwaysFinish(boolean enabled) {
8744        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8745                "setAlwaysFinish()");
8746
8747        Settings.Global.putInt(
8748                mContext.getContentResolver(),
8749                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8750
8751        synchronized (this) {
8752            mAlwaysFinishActivities = enabled;
8753        }
8754    }
8755
8756    @Override
8757    public void setActivityController(IActivityController controller) {
8758        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8759                "setActivityController()");
8760        synchronized (this) {
8761            mController = controller;
8762            Watchdog.getInstance().setActivityController(controller);
8763        }
8764    }
8765
8766    @Override
8767    public void setUserIsMonkey(boolean userIsMonkey) {
8768        synchronized (this) {
8769            synchronized (mPidsSelfLocked) {
8770                final int callingPid = Binder.getCallingPid();
8771                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8772                if (precessRecord == null) {
8773                    throw new SecurityException("Unknown process: " + callingPid);
8774                }
8775                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8776                    throw new SecurityException("Only an instrumentation process "
8777                            + "with a UiAutomation can call setUserIsMonkey");
8778                }
8779            }
8780            mUserIsMonkey = userIsMonkey;
8781        }
8782    }
8783
8784    @Override
8785    public boolean isUserAMonkey() {
8786        synchronized (this) {
8787            // If there is a controller also implies the user is a monkey.
8788            return (mUserIsMonkey || mController != null);
8789        }
8790    }
8791
8792    public void requestBugReport() {
8793        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8794        SystemProperties.set("ctl.start", "bugreport");
8795    }
8796
8797    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8798        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8799    }
8800
8801    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8802        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8803            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8804        }
8805        return KEY_DISPATCHING_TIMEOUT;
8806    }
8807
8808    @Override
8809    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8810        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8811                != PackageManager.PERMISSION_GRANTED) {
8812            throw new SecurityException("Requires permission "
8813                    + android.Manifest.permission.FILTER_EVENTS);
8814        }
8815        ProcessRecord proc;
8816        long timeout;
8817        synchronized (this) {
8818            synchronized (mPidsSelfLocked) {
8819                proc = mPidsSelfLocked.get(pid);
8820            }
8821            timeout = getInputDispatchingTimeoutLocked(proc);
8822        }
8823
8824        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8825            return -1;
8826        }
8827
8828        return timeout;
8829    }
8830
8831    /**
8832     * Handle input dispatching timeouts.
8833     * Returns whether input dispatching should be aborted or not.
8834     */
8835    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8836            final ActivityRecord activity, final ActivityRecord parent,
8837            final boolean aboveSystem, String reason) {
8838        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8839                != PackageManager.PERMISSION_GRANTED) {
8840            throw new SecurityException("Requires permission "
8841                    + android.Manifest.permission.FILTER_EVENTS);
8842        }
8843
8844        final String annotation;
8845        if (reason == null) {
8846            annotation = "Input dispatching timed out";
8847        } else {
8848            annotation = "Input dispatching timed out (" + reason + ")";
8849        }
8850
8851        if (proc != null) {
8852            synchronized (this) {
8853                if (proc.debugging) {
8854                    return false;
8855                }
8856
8857                if (mDidDexOpt) {
8858                    // Give more time since we were dexopting.
8859                    mDidDexOpt = false;
8860                    return false;
8861                }
8862
8863                if (proc.instrumentationClass != null) {
8864                    Bundle info = new Bundle();
8865                    info.putString("shortMsg", "keyDispatchingTimedOut");
8866                    info.putString("longMsg", annotation);
8867                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8868                    return true;
8869                }
8870            }
8871            mHandler.post(new Runnable() {
8872                @Override
8873                public void run() {
8874                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8875                }
8876            });
8877        }
8878
8879        return true;
8880    }
8881
8882    public Bundle getAssistContextExtras(int requestType) {
8883        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8884                "getAssistContextExtras()");
8885        PendingAssistExtras pae;
8886        Bundle extras = new Bundle();
8887        synchronized (this) {
8888            ActivityRecord activity = getFocusedStack().mResumedActivity;
8889            if (activity == null) {
8890                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8891                return null;
8892            }
8893            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8894            if (activity.app == null || activity.app.thread == null) {
8895                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8896                return extras;
8897            }
8898            if (activity.app.pid == Binder.getCallingPid()) {
8899                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8900                return extras;
8901            }
8902            pae = new PendingAssistExtras(activity);
8903            try {
8904                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8905                        requestType);
8906                mPendingAssistExtras.add(pae);
8907                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8908            } catch (RemoteException e) {
8909                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8910                return extras;
8911            }
8912        }
8913        synchronized (pae) {
8914            while (!pae.haveResult) {
8915                try {
8916                    pae.wait();
8917                } catch (InterruptedException e) {
8918                }
8919            }
8920            if (pae.result != null) {
8921                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8922            }
8923        }
8924        synchronized (this) {
8925            mPendingAssistExtras.remove(pae);
8926            mHandler.removeCallbacks(pae);
8927        }
8928        return extras;
8929    }
8930
8931    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8932        PendingAssistExtras pae = (PendingAssistExtras)token;
8933        synchronized (pae) {
8934            pae.result = extras;
8935            pae.haveResult = true;
8936            pae.notifyAll();
8937        }
8938    }
8939
8940    public void registerProcessObserver(IProcessObserver observer) {
8941        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8942                "registerProcessObserver()");
8943        synchronized (this) {
8944            mProcessObservers.register(observer);
8945        }
8946    }
8947
8948    @Override
8949    public void unregisterProcessObserver(IProcessObserver observer) {
8950        synchronized (this) {
8951            mProcessObservers.unregister(observer);
8952        }
8953    }
8954
8955    @Override
8956    public boolean convertFromTranslucent(IBinder token) {
8957        final long origId = Binder.clearCallingIdentity();
8958        try {
8959            synchronized (this) {
8960                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8961                if (r == null) {
8962                    return false;
8963                }
8964                if (r.changeWindowTranslucency(true)) {
8965                    mWindowManager.setAppFullscreen(token, true);
8966                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8967                    return true;
8968                }
8969                return false;
8970            }
8971        } finally {
8972            Binder.restoreCallingIdentity(origId);
8973        }
8974    }
8975
8976    @Override
8977    public boolean convertToTranslucent(IBinder token) {
8978        final long origId = Binder.clearCallingIdentity();
8979        try {
8980            synchronized (this) {
8981                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8982                if (r == null) {
8983                    return false;
8984                }
8985                if (r.changeWindowTranslucency(false)) {
8986                    r.task.stack.convertToTranslucent(r);
8987                    mWindowManager.setAppFullscreen(token, false);
8988                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8989                    return true;
8990                }
8991                return false;
8992            }
8993        } finally {
8994            Binder.restoreCallingIdentity(origId);
8995        }
8996    }
8997
8998    @Override
8999    public void setImmersive(IBinder token, boolean immersive) {
9000        synchronized(this) {
9001            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9002            if (r == null) {
9003                throw new IllegalArgumentException();
9004            }
9005            r.immersive = immersive;
9006
9007            // update associated state if we're frontmost
9008            if (r == mFocusedActivity) {
9009                if (DEBUG_IMMERSIVE) {
9010                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9011                }
9012                applyUpdateLockStateLocked(r);
9013            }
9014        }
9015    }
9016
9017    @Override
9018    public boolean isImmersive(IBinder token) {
9019        synchronized (this) {
9020            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9021            if (r == null) {
9022                throw new IllegalArgumentException();
9023            }
9024            return r.immersive;
9025        }
9026    }
9027
9028    public boolean isTopActivityImmersive() {
9029        enforceNotIsolatedCaller("startActivity");
9030        synchronized (this) {
9031            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9032            return (r != null) ? r.immersive : false;
9033        }
9034    }
9035
9036    public final void enterSafeMode() {
9037        synchronized(this) {
9038            // It only makes sense to do this before the system is ready
9039            // and started launching other packages.
9040            if (!mSystemReady) {
9041                try {
9042                    AppGlobals.getPackageManager().enterSafeMode();
9043                } catch (RemoteException e) {
9044                }
9045            }
9046
9047            mSafeMode = true;
9048        }
9049    }
9050
9051    public final void showSafeModeOverlay() {
9052        View v = LayoutInflater.from(mContext).inflate(
9053                com.android.internal.R.layout.safe_mode, null);
9054        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9055        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9056        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9057        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9058        lp.gravity = Gravity.BOTTOM | Gravity.START;
9059        lp.format = v.getBackground().getOpacity();
9060        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9061                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9062        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9063        ((WindowManager)mContext.getSystemService(
9064                Context.WINDOW_SERVICE)).addView(v, lp);
9065    }
9066
9067    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9068        if (!(sender instanceof PendingIntentRecord)) {
9069            return;
9070        }
9071        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9072        synchronized (stats) {
9073            if (mBatteryStatsService.isOnBattery()) {
9074                mBatteryStatsService.enforceCallingPermission();
9075                PendingIntentRecord rec = (PendingIntentRecord)sender;
9076                int MY_UID = Binder.getCallingUid();
9077                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9078                BatteryStatsImpl.Uid.Pkg pkg =
9079                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9080                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9081                pkg.incWakeupsLocked();
9082            }
9083        }
9084    }
9085
9086    public boolean killPids(int[] pids, String pReason, boolean secure) {
9087        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9088            throw new SecurityException("killPids only available to the system");
9089        }
9090        String reason = (pReason == null) ? "Unknown" : pReason;
9091        // XXX Note: don't acquire main activity lock here, because the window
9092        // manager calls in with its locks held.
9093
9094        boolean killed = false;
9095        synchronized (mPidsSelfLocked) {
9096            int[] types = new int[pids.length];
9097            int worstType = 0;
9098            for (int i=0; i<pids.length; i++) {
9099                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9100                if (proc != null) {
9101                    int type = proc.setAdj;
9102                    types[i] = type;
9103                    if (type > worstType) {
9104                        worstType = type;
9105                    }
9106                }
9107            }
9108
9109            // If the worst oom_adj is somewhere in the cached proc LRU range,
9110            // then constrain it so we will kill all cached procs.
9111            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9112                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9113                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9114            }
9115
9116            // If this is not a secure call, don't let it kill processes that
9117            // are important.
9118            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9119                worstType = ProcessList.SERVICE_ADJ;
9120            }
9121
9122            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9123            for (int i=0; i<pids.length; i++) {
9124                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9125                if (proc == null) {
9126                    continue;
9127                }
9128                int adj = proc.setAdj;
9129                if (adj >= worstType && !proc.killedByAm) {
9130                    killUnneededProcessLocked(proc, reason);
9131                    killed = true;
9132                }
9133            }
9134        }
9135        return killed;
9136    }
9137
9138    @Override
9139    public void killUid(int uid, String reason) {
9140        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9141            throw new SecurityException("killUid only available to the system");
9142        }
9143        synchronized (this) {
9144            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9145                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9146                    reason != null ? reason : "kill uid");
9147        }
9148    }
9149
9150    @Override
9151    public boolean killProcessesBelowForeground(String reason) {
9152        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9153            throw new SecurityException("killProcessesBelowForeground() only available to system");
9154        }
9155
9156        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9157    }
9158
9159    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9160        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9161            throw new SecurityException("killProcessesBelowAdj() only available to system");
9162        }
9163
9164        boolean killed = false;
9165        synchronized (mPidsSelfLocked) {
9166            final int size = mPidsSelfLocked.size();
9167            for (int i = 0; i < size; i++) {
9168                final int pid = mPidsSelfLocked.keyAt(i);
9169                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9170                if (proc == null) continue;
9171
9172                final int adj = proc.setAdj;
9173                if (adj > belowAdj && !proc.killedByAm) {
9174                    killUnneededProcessLocked(proc, reason);
9175                    killed = true;
9176                }
9177            }
9178        }
9179        return killed;
9180    }
9181
9182    @Override
9183    public void hang(final IBinder who, boolean allowRestart) {
9184        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9185                != PackageManager.PERMISSION_GRANTED) {
9186            throw new SecurityException("Requires permission "
9187                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9188        }
9189
9190        final IBinder.DeathRecipient death = new DeathRecipient() {
9191            @Override
9192            public void binderDied() {
9193                synchronized (this) {
9194                    notifyAll();
9195                }
9196            }
9197        };
9198
9199        try {
9200            who.linkToDeath(death, 0);
9201        } catch (RemoteException e) {
9202            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9203            return;
9204        }
9205
9206        synchronized (this) {
9207            Watchdog.getInstance().setAllowRestart(allowRestart);
9208            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9209            synchronized (death) {
9210                while (who.isBinderAlive()) {
9211                    try {
9212                        death.wait();
9213                    } catch (InterruptedException e) {
9214                    }
9215                }
9216            }
9217            Watchdog.getInstance().setAllowRestart(true);
9218        }
9219    }
9220
9221    @Override
9222    public void restart() {
9223        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9224                != PackageManager.PERMISSION_GRANTED) {
9225            throw new SecurityException("Requires permission "
9226                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9227        }
9228
9229        Log.i(TAG, "Sending shutdown broadcast...");
9230
9231        BroadcastReceiver br = new BroadcastReceiver() {
9232            @Override public void onReceive(Context context, Intent intent) {
9233                // Now the broadcast is done, finish up the low-level shutdown.
9234                Log.i(TAG, "Shutting down activity manager...");
9235                shutdown(10000);
9236                Log.i(TAG, "Shutdown complete, restarting!");
9237                Process.killProcess(Process.myPid());
9238                System.exit(10);
9239            }
9240        };
9241
9242        // First send the high-level shut down broadcast.
9243        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9244        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9245        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9246        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9247        mContext.sendOrderedBroadcastAsUser(intent,
9248                UserHandle.ALL, null, br, mHandler, 0, null, null);
9249        */
9250        br.onReceive(mContext, intent);
9251    }
9252
9253    private long getLowRamTimeSinceIdle(long now) {
9254        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9255    }
9256
9257    @Override
9258    public void performIdleMaintenance() {
9259        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9260                != PackageManager.PERMISSION_GRANTED) {
9261            throw new SecurityException("Requires permission "
9262                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9263        }
9264
9265        synchronized (this) {
9266            final long now = SystemClock.uptimeMillis();
9267            final long timeSinceLastIdle = now - mLastIdleTime;
9268            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9269            mLastIdleTime = now;
9270            mLowRamTimeSinceLastIdle = 0;
9271            if (mLowRamStartTime != 0) {
9272                mLowRamStartTime = now;
9273            }
9274
9275            StringBuilder sb = new StringBuilder(128);
9276            sb.append("Idle maintenance over ");
9277            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9278            sb.append(" low RAM for ");
9279            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9280            Slog.i(TAG, sb.toString());
9281
9282            // If at least 1/3 of our time since the last idle period has been spent
9283            // with RAM low, then we want to kill processes.
9284            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9285
9286            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9287                ProcessRecord proc = mLruProcesses.get(i);
9288                if (proc.notCachedSinceIdle) {
9289                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9290                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9291                        if (doKilling && proc.initialIdlePss != 0
9292                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9293                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9294                                    + " from " + proc.initialIdlePss + ")");
9295                        }
9296                    }
9297                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9298                    proc.notCachedSinceIdle = true;
9299                    proc.initialIdlePss = 0;
9300                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9301                            mSleeping, now);
9302                }
9303            }
9304
9305            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9306            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9307        }
9308    }
9309
9310    private void retrieveSettings() {
9311        final ContentResolver resolver = mContext.getContentResolver();
9312        String debugApp = Settings.Global.getString(
9313            resolver, Settings.Global.DEBUG_APP);
9314        boolean waitForDebugger = Settings.Global.getInt(
9315            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9316        boolean alwaysFinishActivities = Settings.Global.getInt(
9317            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9318        boolean forceRtl = Settings.Global.getInt(
9319                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9320        // Transfer any global setting for forcing RTL layout, into a System Property
9321        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9322
9323        Configuration configuration = new Configuration();
9324        Settings.System.getConfiguration(resolver, configuration);
9325        if (forceRtl) {
9326            // This will take care of setting the correct layout direction flags
9327            configuration.setLayoutDirection(configuration.locale);
9328        }
9329
9330        synchronized (this) {
9331            mDebugApp = mOrigDebugApp = debugApp;
9332            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9333            mAlwaysFinishActivities = alwaysFinishActivities;
9334            // This happens before any activities are started, so we can
9335            // change mConfiguration in-place.
9336            updateConfigurationLocked(configuration, null, false, true);
9337            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9338        }
9339    }
9340
9341    public boolean testIsSystemReady() {
9342        // no need to synchronize(this) just to read & return the value
9343        return mSystemReady;
9344    }
9345
9346    private static File getCalledPreBootReceiversFile() {
9347        File dataDir = Environment.getDataDirectory();
9348        File systemDir = new File(dataDir, "system");
9349        File fname = new File(systemDir, "called_pre_boots.dat");
9350        return fname;
9351    }
9352
9353    static final int LAST_DONE_VERSION = 10000;
9354
9355    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9356        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9357        File file = getCalledPreBootReceiversFile();
9358        FileInputStream fis = null;
9359        try {
9360            fis = new FileInputStream(file);
9361            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9362            int fvers = dis.readInt();
9363            if (fvers == LAST_DONE_VERSION) {
9364                String vers = dis.readUTF();
9365                String codename = dis.readUTF();
9366                String build = dis.readUTF();
9367                if (android.os.Build.VERSION.RELEASE.equals(vers)
9368                        && android.os.Build.VERSION.CODENAME.equals(codename)
9369                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9370                    int num = dis.readInt();
9371                    while (num > 0) {
9372                        num--;
9373                        String pkg = dis.readUTF();
9374                        String cls = dis.readUTF();
9375                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9376                    }
9377                }
9378            }
9379        } catch (FileNotFoundException e) {
9380        } catch (IOException e) {
9381            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9382        } finally {
9383            if (fis != null) {
9384                try {
9385                    fis.close();
9386                } catch (IOException e) {
9387                }
9388            }
9389        }
9390        return lastDoneReceivers;
9391    }
9392
9393    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9394        File file = getCalledPreBootReceiversFile();
9395        FileOutputStream fos = null;
9396        DataOutputStream dos = null;
9397        try {
9398            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9399            fos = new FileOutputStream(file);
9400            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9401            dos.writeInt(LAST_DONE_VERSION);
9402            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9403            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9404            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9405            dos.writeInt(list.size());
9406            for (int i=0; i<list.size(); i++) {
9407                dos.writeUTF(list.get(i).getPackageName());
9408                dos.writeUTF(list.get(i).getClassName());
9409            }
9410        } catch (IOException e) {
9411            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9412            file.delete();
9413        } finally {
9414            FileUtils.sync(fos);
9415            if (dos != null) {
9416                try {
9417                    dos.close();
9418                } catch (IOException e) {
9419                    // TODO Auto-generated catch block
9420                    e.printStackTrace();
9421                }
9422            }
9423        }
9424    }
9425
9426    public void systemReady(final Runnable goingCallback) {
9427        synchronized(this) {
9428            if (mSystemReady) {
9429                if (goingCallback != null) goingCallback.run();
9430                return;
9431            }
9432
9433            // Check to see if there are any update receivers to run.
9434            if (!mDidUpdate) {
9435                if (mWaitingUpdate) {
9436                    return;
9437                }
9438                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9439                List<ResolveInfo> ris = null;
9440                try {
9441                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9442                            intent, null, 0, 0);
9443                } catch (RemoteException e) {
9444                }
9445                if (ris != null) {
9446                    for (int i=ris.size()-1; i>=0; i--) {
9447                        if ((ris.get(i).activityInfo.applicationInfo.flags
9448                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9449                            ris.remove(i);
9450                        }
9451                    }
9452                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9453
9454                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9455
9456                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9457                    for (int i=0; i<ris.size(); i++) {
9458                        ActivityInfo ai = ris.get(i).activityInfo;
9459                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9460                        if (lastDoneReceivers.contains(comp)) {
9461                            // We already did the pre boot receiver for this app with the current
9462                            // platform version, so don't do it again...
9463                            ris.remove(i);
9464                            i--;
9465                            // ...however, do keep it as one that has been done, so we don't
9466                            // forget about it when rewriting the file of last done receivers.
9467                            doneReceivers.add(comp);
9468                        }
9469                    }
9470
9471                    final int[] users = getUsersLocked();
9472                    for (int i=0; i<ris.size(); i++) {
9473                        ActivityInfo ai = ris.get(i).activityInfo;
9474                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9475                        doneReceivers.add(comp);
9476                        intent.setComponent(comp);
9477                        for (int j=0; j<users.length; j++) {
9478                            IIntentReceiver finisher = null;
9479                            if (i == ris.size()-1 && j == users.length-1) {
9480                                finisher = new IIntentReceiver.Stub() {
9481                                    public void performReceive(Intent intent, int resultCode,
9482                                            String data, Bundle extras, boolean ordered,
9483                                            boolean sticky, int sendingUser) {
9484                                        // The raw IIntentReceiver interface is called
9485                                        // with the AM lock held, so redispatch to
9486                                        // execute our code without the lock.
9487                                        mHandler.post(new Runnable() {
9488                                            public void run() {
9489                                                synchronized (ActivityManagerService.this) {
9490                                                    mDidUpdate = true;
9491                                                }
9492                                                writeLastDonePreBootReceivers(doneReceivers);
9493                                                showBootMessage(mContext.getText(
9494                                                        R.string.android_upgrading_complete),
9495                                                        false);
9496                                                systemReady(goingCallback);
9497                                            }
9498                                        });
9499                                    }
9500                                };
9501                            }
9502                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9503                                    + " for user " + users[j]);
9504                            broadcastIntentLocked(null, null, intent, null, finisher,
9505                                    0, null, null, null, AppOpsManager.OP_NONE,
9506                                    true, false, MY_PID, Process.SYSTEM_UID,
9507                                    users[j]);
9508                            if (finisher != null) {
9509                                mWaitingUpdate = true;
9510                            }
9511                        }
9512                    }
9513                }
9514                if (mWaitingUpdate) {
9515                    return;
9516                }
9517                mDidUpdate = true;
9518            }
9519
9520            mAppOpsService.systemReady();
9521            mSystemReady = true;
9522        }
9523
9524        ArrayList<ProcessRecord> procsToKill = null;
9525        synchronized(mPidsSelfLocked) {
9526            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9527                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9528                if (!isAllowedWhileBooting(proc.info)){
9529                    if (procsToKill == null) {
9530                        procsToKill = new ArrayList<ProcessRecord>();
9531                    }
9532                    procsToKill.add(proc);
9533                }
9534            }
9535        }
9536
9537        synchronized(this) {
9538            if (procsToKill != null) {
9539                for (int i=procsToKill.size()-1; i>=0; i--) {
9540                    ProcessRecord proc = procsToKill.get(i);
9541                    Slog.i(TAG, "Removing system update proc: " + proc);
9542                    removeProcessLocked(proc, true, false, "system update done");
9543                }
9544            }
9545
9546            // Now that we have cleaned up any update processes, we
9547            // are ready to start launching real processes and know that
9548            // we won't trample on them any more.
9549            mProcessesReady = true;
9550        }
9551
9552        Slog.i(TAG, "System now ready");
9553        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9554            SystemClock.uptimeMillis());
9555
9556        synchronized(this) {
9557            // Make sure we have no pre-ready processes sitting around.
9558
9559            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9560                ResolveInfo ri = mContext.getPackageManager()
9561                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9562                                STOCK_PM_FLAGS);
9563                CharSequence errorMsg = null;
9564                if (ri != null) {
9565                    ActivityInfo ai = ri.activityInfo;
9566                    ApplicationInfo app = ai.applicationInfo;
9567                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9568                        mTopAction = Intent.ACTION_FACTORY_TEST;
9569                        mTopData = null;
9570                        mTopComponent = new ComponentName(app.packageName,
9571                                ai.name);
9572                    } else {
9573                        errorMsg = mContext.getResources().getText(
9574                                com.android.internal.R.string.factorytest_not_system);
9575                    }
9576                } else {
9577                    errorMsg = mContext.getResources().getText(
9578                            com.android.internal.R.string.factorytest_no_action);
9579                }
9580                if (errorMsg != null) {
9581                    mTopAction = null;
9582                    mTopData = null;
9583                    mTopComponent = null;
9584                    Message msg = Message.obtain();
9585                    msg.what = SHOW_FACTORY_ERROR_MSG;
9586                    msg.getData().putCharSequence("msg", errorMsg);
9587                    mHandler.sendMessage(msg);
9588                }
9589            }
9590        }
9591
9592        retrieveSettings();
9593
9594        synchronized (this) {
9595            readGrantedUriPermissionsLocked();
9596        }
9597
9598        if (goingCallback != null) goingCallback.run();
9599
9600        synchronized (this) {
9601            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9602                try {
9603                    List apps = AppGlobals.getPackageManager().
9604                        getPersistentApplications(STOCK_PM_FLAGS);
9605                    if (apps != null) {
9606                        int N = apps.size();
9607                        int i;
9608                        for (i=0; i<N; i++) {
9609                            ApplicationInfo info
9610                                = (ApplicationInfo)apps.get(i);
9611                            if (info != null &&
9612                                    !info.packageName.equals("android")) {
9613                                addAppLocked(info, false);
9614                            }
9615                        }
9616                    }
9617                } catch (RemoteException ex) {
9618                    // pm is in same process, this will never happen.
9619                }
9620            }
9621
9622            // Start up initial activity.
9623            mBooting = true;
9624
9625            try {
9626                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9627                    Message msg = Message.obtain();
9628                    msg.what = SHOW_UID_ERROR_MSG;
9629                    mHandler.sendMessage(msg);
9630                }
9631            } catch (RemoteException e) {
9632            }
9633
9634            long ident = Binder.clearCallingIdentity();
9635            try {
9636                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9637                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9638                        | Intent.FLAG_RECEIVER_FOREGROUND);
9639                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9640                broadcastIntentLocked(null, null, intent,
9641                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9642                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9643                intent = new Intent(Intent.ACTION_USER_STARTING);
9644                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9645                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9646                broadcastIntentLocked(null, null, intent,
9647                        null, new IIntentReceiver.Stub() {
9648                            @Override
9649                            public void performReceive(Intent intent, int resultCode, String data,
9650                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9651                                    throws RemoteException {
9652                            }
9653                        }, 0, null, null,
9654                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9655                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9656            } finally {
9657                Binder.restoreCallingIdentity(ident);
9658            }
9659            mStackSupervisor.resumeTopActivitiesLocked();
9660            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9661        }
9662    }
9663
9664    private boolean makeAppCrashingLocked(ProcessRecord app,
9665            String shortMsg, String longMsg, String stackTrace) {
9666        app.crashing = true;
9667        app.crashingReport = generateProcessError(app,
9668                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9669        startAppProblemLocked(app);
9670        app.stopFreezingAllLocked();
9671        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9672    }
9673
9674    private void makeAppNotRespondingLocked(ProcessRecord app,
9675            String activity, String shortMsg, String longMsg) {
9676        app.notResponding = true;
9677        app.notRespondingReport = generateProcessError(app,
9678                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9679                activity, shortMsg, longMsg, null);
9680        startAppProblemLocked(app);
9681        app.stopFreezingAllLocked();
9682    }
9683
9684    /**
9685     * Generate a process error record, suitable for attachment to a ProcessRecord.
9686     *
9687     * @param app The ProcessRecord in which the error occurred.
9688     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9689     *                      ActivityManager.AppErrorStateInfo
9690     * @param activity The activity associated with the crash, if known.
9691     * @param shortMsg Short message describing the crash.
9692     * @param longMsg Long message describing the crash.
9693     * @param stackTrace Full crash stack trace, may be null.
9694     *
9695     * @return Returns a fully-formed AppErrorStateInfo record.
9696     */
9697    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9698            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9699        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9700
9701        report.condition = condition;
9702        report.processName = app.processName;
9703        report.pid = app.pid;
9704        report.uid = app.info.uid;
9705        report.tag = activity;
9706        report.shortMsg = shortMsg;
9707        report.longMsg = longMsg;
9708        report.stackTrace = stackTrace;
9709
9710        return report;
9711    }
9712
9713    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9714        synchronized (this) {
9715            app.crashing = false;
9716            app.crashingReport = null;
9717            app.notResponding = false;
9718            app.notRespondingReport = null;
9719            if (app.anrDialog == fromDialog) {
9720                app.anrDialog = null;
9721            }
9722            if (app.waitDialog == fromDialog) {
9723                app.waitDialog = null;
9724            }
9725            if (app.pid > 0 && app.pid != MY_PID) {
9726                handleAppCrashLocked(app, null, null, null);
9727                killUnneededProcessLocked(app, "user request after error");
9728            }
9729        }
9730    }
9731
9732    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9733            String stackTrace) {
9734        long now = SystemClock.uptimeMillis();
9735
9736        Long crashTime;
9737        if (!app.isolated) {
9738            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9739        } else {
9740            crashTime = null;
9741        }
9742        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9743            // This process loses!
9744            Slog.w(TAG, "Process " + app.info.processName
9745                    + " has crashed too many times: killing!");
9746            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9747                    app.userId, app.info.processName, app.uid);
9748            mStackSupervisor.handleAppCrashLocked(app);
9749            if (!app.persistent) {
9750                // We don't want to start this process again until the user
9751                // explicitly does so...  but for persistent process, we really
9752                // need to keep it running.  If a persistent process is actually
9753                // repeatedly crashing, then badness for everyone.
9754                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9755                        app.info.processName);
9756                if (!app.isolated) {
9757                    // XXX We don't have a way to mark isolated processes
9758                    // as bad, since they don't have a peristent identity.
9759                    mBadProcesses.put(app.info.processName, app.uid,
9760                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9761                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9762                }
9763                app.bad = true;
9764                app.removed = true;
9765                // Don't let services in this process be restarted and potentially
9766                // annoy the user repeatedly.  Unless it is persistent, since those
9767                // processes run critical code.
9768                removeProcessLocked(app, false, false, "crash");
9769                mStackSupervisor.resumeTopActivitiesLocked();
9770                return false;
9771            }
9772            mStackSupervisor.resumeTopActivitiesLocked();
9773        } else {
9774            mStackSupervisor.finishTopRunningActivityLocked(app);
9775        }
9776
9777        // Bump up the crash count of any services currently running in the proc.
9778        for (int i=app.services.size()-1; i>=0; i--) {
9779            // Any services running in the application need to be placed
9780            // back in the pending list.
9781            ServiceRecord sr = app.services.valueAt(i);
9782            sr.crashCount++;
9783        }
9784
9785        // If the crashing process is what we consider to be the "home process" and it has been
9786        // replaced by a third-party app, clear the package preferred activities from packages
9787        // with a home activity running in the process to prevent a repeatedly crashing app
9788        // from blocking the user to manually clear the list.
9789        final ArrayList<ActivityRecord> activities = app.activities;
9790        if (app == mHomeProcess && activities.size() > 0
9791                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9792            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9793                final ActivityRecord r = activities.get(activityNdx);
9794                if (r.isHomeActivity()) {
9795                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9796                    try {
9797                        ActivityThread.getPackageManager()
9798                                .clearPackagePreferredActivities(r.packageName);
9799                    } catch (RemoteException c) {
9800                        // pm is in same process, this will never happen.
9801                    }
9802                }
9803            }
9804        }
9805
9806        if (!app.isolated) {
9807            // XXX Can't keep track of crash times for isolated processes,
9808            // because they don't have a perisistent identity.
9809            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9810        }
9811
9812        return true;
9813    }
9814
9815    void startAppProblemLocked(ProcessRecord app) {
9816        if (app.userId == mCurrentUserId) {
9817            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9818                    mContext, app.info.packageName, app.info.flags);
9819        } else {
9820            // If this app is not running under the current user, then we
9821            // can't give it a report button because that would require
9822            // launching the report UI under a different user.
9823            app.errorReportReceiver = null;
9824        }
9825        skipCurrentReceiverLocked(app);
9826    }
9827
9828    void skipCurrentReceiverLocked(ProcessRecord app) {
9829        for (BroadcastQueue queue : mBroadcastQueues) {
9830            queue.skipCurrentReceiverLocked(app);
9831        }
9832    }
9833
9834    /**
9835     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9836     * The application process will exit immediately after this call returns.
9837     * @param app object of the crashing app, null for the system server
9838     * @param crashInfo describing the exception
9839     */
9840    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9841        ProcessRecord r = findAppProcess(app, "Crash");
9842        final String processName = app == null ? "system_server"
9843                : (r == null ? "unknown" : r.processName);
9844
9845        handleApplicationCrashInner("crash", r, processName, crashInfo);
9846    }
9847
9848    /* Native crash reporting uses this inner version because it needs to be somewhat
9849     * decoupled from the AM-managed cleanup lifecycle
9850     */
9851    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9852            ApplicationErrorReport.CrashInfo crashInfo) {
9853        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9854                UserHandle.getUserId(Binder.getCallingUid()), processName,
9855                r == null ? -1 : r.info.flags,
9856                crashInfo.exceptionClassName,
9857                crashInfo.exceptionMessage,
9858                crashInfo.throwFileName,
9859                crashInfo.throwLineNumber);
9860
9861        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9862
9863        crashApplication(r, crashInfo);
9864    }
9865
9866    public void handleApplicationStrictModeViolation(
9867            IBinder app,
9868            int violationMask,
9869            StrictMode.ViolationInfo info) {
9870        ProcessRecord r = findAppProcess(app, "StrictMode");
9871        if (r == null) {
9872            return;
9873        }
9874
9875        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9876            Integer stackFingerprint = info.hashCode();
9877            boolean logIt = true;
9878            synchronized (mAlreadyLoggedViolatedStacks) {
9879                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9880                    logIt = false;
9881                    // TODO: sub-sample into EventLog for these, with
9882                    // the info.durationMillis?  Then we'd get
9883                    // the relative pain numbers, without logging all
9884                    // the stack traces repeatedly.  We'd want to do
9885                    // likewise in the client code, which also does
9886                    // dup suppression, before the Binder call.
9887                } else {
9888                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9889                        mAlreadyLoggedViolatedStacks.clear();
9890                    }
9891                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9892                }
9893            }
9894            if (logIt) {
9895                logStrictModeViolationToDropBox(r, info);
9896            }
9897        }
9898
9899        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9900            AppErrorResult result = new AppErrorResult();
9901            synchronized (this) {
9902                final long origId = Binder.clearCallingIdentity();
9903
9904                Message msg = Message.obtain();
9905                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9906                HashMap<String, Object> data = new HashMap<String, Object>();
9907                data.put("result", result);
9908                data.put("app", r);
9909                data.put("violationMask", violationMask);
9910                data.put("info", info);
9911                msg.obj = data;
9912                mHandler.sendMessage(msg);
9913
9914                Binder.restoreCallingIdentity(origId);
9915            }
9916            int res = result.get();
9917            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9918        }
9919    }
9920
9921    // Depending on the policy in effect, there could be a bunch of
9922    // these in quick succession so we try to batch these together to
9923    // minimize disk writes, number of dropbox entries, and maximize
9924    // compression, by having more fewer, larger records.
9925    private void logStrictModeViolationToDropBox(
9926            ProcessRecord process,
9927            StrictMode.ViolationInfo info) {
9928        if (info == null) {
9929            return;
9930        }
9931        final boolean isSystemApp = process == null ||
9932                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9933                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9934        final String processName = process == null ? "unknown" : process.processName;
9935        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9936        final DropBoxManager dbox = (DropBoxManager)
9937                mContext.getSystemService(Context.DROPBOX_SERVICE);
9938
9939        // Exit early if the dropbox isn't configured to accept this report type.
9940        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9941
9942        boolean bufferWasEmpty;
9943        boolean needsFlush;
9944        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9945        synchronized (sb) {
9946            bufferWasEmpty = sb.length() == 0;
9947            appendDropBoxProcessHeaders(process, processName, sb);
9948            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9949            sb.append("System-App: ").append(isSystemApp).append("\n");
9950            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9951            if (info.violationNumThisLoop != 0) {
9952                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9953            }
9954            if (info.numAnimationsRunning != 0) {
9955                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9956            }
9957            if (info.broadcastIntentAction != null) {
9958                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9959            }
9960            if (info.durationMillis != -1) {
9961                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9962            }
9963            if (info.numInstances != -1) {
9964                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9965            }
9966            if (info.tags != null) {
9967                for (String tag : info.tags) {
9968                    sb.append("Span-Tag: ").append(tag).append("\n");
9969                }
9970            }
9971            sb.append("\n");
9972            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9973                sb.append(info.crashInfo.stackTrace);
9974            }
9975            sb.append("\n");
9976
9977            // Only buffer up to ~64k.  Various logging bits truncate
9978            // things at 128k.
9979            needsFlush = (sb.length() > 64 * 1024);
9980        }
9981
9982        // Flush immediately if the buffer's grown too large, or this
9983        // is a non-system app.  Non-system apps are isolated with a
9984        // different tag & policy and not batched.
9985        //
9986        // Batching is useful during internal testing with
9987        // StrictMode settings turned up high.  Without batching,
9988        // thousands of separate files could be created on boot.
9989        if (!isSystemApp || needsFlush) {
9990            new Thread("Error dump: " + dropboxTag) {
9991                @Override
9992                public void run() {
9993                    String report;
9994                    synchronized (sb) {
9995                        report = sb.toString();
9996                        sb.delete(0, sb.length());
9997                        sb.trimToSize();
9998                    }
9999                    if (report.length() != 0) {
10000                        dbox.addText(dropboxTag, report);
10001                    }
10002                }
10003            }.start();
10004            return;
10005        }
10006
10007        // System app batching:
10008        if (!bufferWasEmpty) {
10009            // An existing dropbox-writing thread is outstanding, so
10010            // we don't need to start it up.  The existing thread will
10011            // catch the buffer appends we just did.
10012            return;
10013        }
10014
10015        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10016        // (After this point, we shouldn't access AMS internal data structures.)
10017        new Thread("Error dump: " + dropboxTag) {
10018            @Override
10019            public void run() {
10020                // 5 second sleep to let stacks arrive and be batched together
10021                try {
10022                    Thread.sleep(5000);  // 5 seconds
10023                } catch (InterruptedException e) {}
10024
10025                String errorReport;
10026                synchronized (mStrictModeBuffer) {
10027                    errorReport = mStrictModeBuffer.toString();
10028                    if (errorReport.length() == 0) {
10029                        return;
10030                    }
10031                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10032                    mStrictModeBuffer.trimToSize();
10033                }
10034                dbox.addText(dropboxTag, errorReport);
10035            }
10036        }.start();
10037    }
10038
10039    /**
10040     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10041     * @param app object of the crashing app, null for the system server
10042     * @param tag reported by the caller
10043     * @param crashInfo describing the context of the error
10044     * @return true if the process should exit immediately (WTF is fatal)
10045     */
10046    public boolean handleApplicationWtf(IBinder app, String tag,
10047            ApplicationErrorReport.CrashInfo crashInfo) {
10048        ProcessRecord r = findAppProcess(app, "WTF");
10049        final String processName = app == null ? "system_server"
10050                : (r == null ? "unknown" : r.processName);
10051
10052        EventLog.writeEvent(EventLogTags.AM_WTF,
10053                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10054                processName,
10055                r == null ? -1 : r.info.flags,
10056                tag, crashInfo.exceptionMessage);
10057
10058        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10059
10060        if (r != null && r.pid != Process.myPid() &&
10061                Settings.Global.getInt(mContext.getContentResolver(),
10062                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10063            crashApplication(r, crashInfo);
10064            return true;
10065        } else {
10066            return false;
10067        }
10068    }
10069
10070    /**
10071     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10072     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10073     */
10074    private ProcessRecord findAppProcess(IBinder app, String reason) {
10075        if (app == null) {
10076            return null;
10077        }
10078
10079        synchronized (this) {
10080            final int NP = mProcessNames.getMap().size();
10081            for (int ip=0; ip<NP; ip++) {
10082                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10083                final int NA = apps.size();
10084                for (int ia=0; ia<NA; ia++) {
10085                    ProcessRecord p = apps.valueAt(ia);
10086                    if (p.thread != null && p.thread.asBinder() == app) {
10087                        return p;
10088                    }
10089                }
10090            }
10091
10092            Slog.w(TAG, "Can't find mystery application for " + reason
10093                    + " from pid=" + Binder.getCallingPid()
10094                    + " uid=" + Binder.getCallingUid() + ": " + app);
10095            return null;
10096        }
10097    }
10098
10099    /**
10100     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10101     * to append various headers to the dropbox log text.
10102     */
10103    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10104            StringBuilder sb) {
10105        // Watchdog thread ends up invoking this function (with
10106        // a null ProcessRecord) to add the stack file to dropbox.
10107        // Do not acquire a lock on this (am) in such cases, as it
10108        // could cause a potential deadlock, if and when watchdog
10109        // is invoked due to unavailability of lock on am and it
10110        // would prevent watchdog from killing system_server.
10111        if (process == null) {
10112            sb.append("Process: ").append(processName).append("\n");
10113            return;
10114        }
10115        // Note: ProcessRecord 'process' is guarded by the service
10116        // instance.  (notably process.pkgList, which could otherwise change
10117        // concurrently during execution of this method)
10118        synchronized (this) {
10119            sb.append("Process: ").append(processName).append("\n");
10120            int flags = process.info.flags;
10121            IPackageManager pm = AppGlobals.getPackageManager();
10122            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10123            for (int ip=0; ip<process.pkgList.size(); ip++) {
10124                String pkg = process.pkgList.keyAt(ip);
10125                sb.append("Package: ").append(pkg);
10126                try {
10127                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10128                    if (pi != null) {
10129                        sb.append(" v").append(pi.versionCode);
10130                        if (pi.versionName != null) {
10131                            sb.append(" (").append(pi.versionName).append(")");
10132                        }
10133                    }
10134                } catch (RemoteException e) {
10135                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10136                }
10137                sb.append("\n");
10138            }
10139        }
10140    }
10141
10142    private static String processClass(ProcessRecord process) {
10143        if (process == null || process.pid == MY_PID) {
10144            return "system_server";
10145        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10146            return "system_app";
10147        } else {
10148            return "data_app";
10149        }
10150    }
10151
10152    /**
10153     * Write a description of an error (crash, WTF, ANR) to the drop box.
10154     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10155     * @param process which caused the error, null means the system server
10156     * @param activity which triggered the error, null if unknown
10157     * @param parent activity related to the error, null if unknown
10158     * @param subject line related to the error, null if absent
10159     * @param report in long form describing the error, null if absent
10160     * @param logFile to include in the report, null if none
10161     * @param crashInfo giving an application stack trace, null if absent
10162     */
10163    public void addErrorToDropBox(String eventType,
10164            ProcessRecord process, String processName, ActivityRecord activity,
10165            ActivityRecord parent, String subject,
10166            final String report, final File logFile,
10167            final ApplicationErrorReport.CrashInfo crashInfo) {
10168        // NOTE -- this must never acquire the ActivityManagerService lock,
10169        // otherwise the watchdog may be prevented from resetting the system.
10170
10171        final String dropboxTag = processClass(process) + "_" + eventType;
10172        final DropBoxManager dbox = (DropBoxManager)
10173                mContext.getSystemService(Context.DROPBOX_SERVICE);
10174
10175        // Exit early if the dropbox isn't configured to accept this report type.
10176        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10177
10178        final StringBuilder sb = new StringBuilder(1024);
10179        appendDropBoxProcessHeaders(process, processName, sb);
10180        if (activity != null) {
10181            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10182        }
10183        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10184            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10185        }
10186        if (parent != null && parent != activity) {
10187            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10188        }
10189        if (subject != null) {
10190            sb.append("Subject: ").append(subject).append("\n");
10191        }
10192        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10193        if (Debug.isDebuggerConnected()) {
10194            sb.append("Debugger: Connected\n");
10195        }
10196        sb.append("\n");
10197
10198        // Do the rest in a worker thread to avoid blocking the caller on I/O
10199        // (After this point, we shouldn't access AMS internal data structures.)
10200        Thread worker = new Thread("Error dump: " + dropboxTag) {
10201            @Override
10202            public void run() {
10203                if (report != null) {
10204                    sb.append(report);
10205                }
10206                if (logFile != null) {
10207                    try {
10208                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10209                                    "\n\n[[TRUNCATED]]"));
10210                    } catch (IOException e) {
10211                        Slog.e(TAG, "Error reading " + logFile, e);
10212                    }
10213                }
10214                if (crashInfo != null && crashInfo.stackTrace != null) {
10215                    sb.append(crashInfo.stackTrace);
10216                }
10217
10218                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10219                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10220                if (lines > 0) {
10221                    sb.append("\n");
10222
10223                    // Merge several logcat streams, and take the last N lines
10224                    InputStreamReader input = null;
10225                    try {
10226                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10227                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10228                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10229
10230                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10231                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10232                        input = new InputStreamReader(logcat.getInputStream());
10233
10234                        int num;
10235                        char[] buf = new char[8192];
10236                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10237                    } catch (IOException e) {
10238                        Slog.e(TAG, "Error running logcat", e);
10239                    } finally {
10240                        if (input != null) try { input.close(); } catch (IOException e) {}
10241                    }
10242                }
10243
10244                dbox.addText(dropboxTag, sb.toString());
10245            }
10246        };
10247
10248        if (process == null) {
10249            // If process is null, we are being called from some internal code
10250            // and may be about to die -- run this synchronously.
10251            worker.run();
10252        } else {
10253            worker.start();
10254        }
10255    }
10256
10257    /**
10258     * Bring up the "unexpected error" dialog box for a crashing app.
10259     * Deal with edge cases (intercepts from instrumented applications,
10260     * ActivityController, error intent receivers, that sort of thing).
10261     * @param r the application crashing
10262     * @param crashInfo describing the failure
10263     */
10264    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10265        long timeMillis = System.currentTimeMillis();
10266        String shortMsg = crashInfo.exceptionClassName;
10267        String longMsg = crashInfo.exceptionMessage;
10268        String stackTrace = crashInfo.stackTrace;
10269        if (shortMsg != null && longMsg != null) {
10270            longMsg = shortMsg + ": " + longMsg;
10271        } else if (shortMsg != null) {
10272            longMsg = shortMsg;
10273        }
10274
10275        AppErrorResult result = new AppErrorResult();
10276        synchronized (this) {
10277            if (mController != null) {
10278                try {
10279                    String name = r != null ? r.processName : null;
10280                    int pid = r != null ? r.pid : Binder.getCallingPid();
10281                    if (!mController.appCrashed(name, pid,
10282                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10283                        Slog.w(TAG, "Force-killing crashed app " + name
10284                                + " at watcher's request");
10285                        Process.killProcess(pid);
10286                        return;
10287                    }
10288                } catch (RemoteException e) {
10289                    mController = null;
10290                    Watchdog.getInstance().setActivityController(null);
10291                }
10292            }
10293
10294            final long origId = Binder.clearCallingIdentity();
10295
10296            // If this process is running instrumentation, finish it.
10297            if (r != null && r.instrumentationClass != null) {
10298                Slog.w(TAG, "Error in app " + r.processName
10299                      + " running instrumentation " + r.instrumentationClass + ":");
10300                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10301                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10302                Bundle info = new Bundle();
10303                info.putString("shortMsg", shortMsg);
10304                info.putString("longMsg", longMsg);
10305                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10306                Binder.restoreCallingIdentity(origId);
10307                return;
10308            }
10309
10310            // If we can't identify the process or it's already exceeded its crash quota,
10311            // quit right away without showing a crash dialog.
10312            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10313                Binder.restoreCallingIdentity(origId);
10314                return;
10315            }
10316
10317            Message msg = Message.obtain();
10318            msg.what = SHOW_ERROR_MSG;
10319            HashMap data = new HashMap();
10320            data.put("result", result);
10321            data.put("app", r);
10322            msg.obj = data;
10323            mHandler.sendMessage(msg);
10324
10325            Binder.restoreCallingIdentity(origId);
10326        }
10327
10328        int res = result.get();
10329
10330        Intent appErrorIntent = null;
10331        synchronized (this) {
10332            if (r != null && !r.isolated) {
10333                // XXX Can't keep track of crash time for isolated processes,
10334                // since they don't have a persistent identity.
10335                mProcessCrashTimes.put(r.info.processName, r.uid,
10336                        SystemClock.uptimeMillis());
10337            }
10338            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10339                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10340            }
10341        }
10342
10343        if (appErrorIntent != null) {
10344            try {
10345                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10346            } catch (ActivityNotFoundException e) {
10347                Slog.w(TAG, "bug report receiver dissappeared", e);
10348            }
10349        }
10350    }
10351
10352    Intent createAppErrorIntentLocked(ProcessRecord r,
10353            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10354        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10355        if (report == null) {
10356            return null;
10357        }
10358        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10359        result.setComponent(r.errorReportReceiver);
10360        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10361        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10362        return result;
10363    }
10364
10365    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10366            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10367        if (r.errorReportReceiver == null) {
10368            return null;
10369        }
10370
10371        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10372            return null;
10373        }
10374
10375        ApplicationErrorReport report = new ApplicationErrorReport();
10376        report.packageName = r.info.packageName;
10377        report.installerPackageName = r.errorReportReceiver.getPackageName();
10378        report.processName = r.processName;
10379        report.time = timeMillis;
10380        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10381
10382        if (r.crashing || r.forceCrashReport) {
10383            report.type = ApplicationErrorReport.TYPE_CRASH;
10384            report.crashInfo = crashInfo;
10385        } else if (r.notResponding) {
10386            report.type = ApplicationErrorReport.TYPE_ANR;
10387            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10388
10389            report.anrInfo.activity = r.notRespondingReport.tag;
10390            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10391            report.anrInfo.info = r.notRespondingReport.longMsg;
10392        }
10393
10394        return report;
10395    }
10396
10397    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10398        enforceNotIsolatedCaller("getProcessesInErrorState");
10399        // assume our apps are happy - lazy create the list
10400        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10401
10402        final boolean allUsers = ActivityManager.checkUidPermission(
10403                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10404                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10405        int userId = UserHandle.getUserId(Binder.getCallingUid());
10406
10407        synchronized (this) {
10408
10409            // iterate across all processes
10410            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10411                ProcessRecord app = mLruProcesses.get(i);
10412                if (!allUsers && app.userId != userId) {
10413                    continue;
10414                }
10415                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10416                    // This one's in trouble, so we'll generate a report for it
10417                    // crashes are higher priority (in case there's a crash *and* an anr)
10418                    ActivityManager.ProcessErrorStateInfo report = null;
10419                    if (app.crashing) {
10420                        report = app.crashingReport;
10421                    } else if (app.notResponding) {
10422                        report = app.notRespondingReport;
10423                    }
10424
10425                    if (report != null) {
10426                        if (errList == null) {
10427                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10428                        }
10429                        errList.add(report);
10430                    } else {
10431                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10432                                " crashing = " + app.crashing +
10433                                " notResponding = " + app.notResponding);
10434                    }
10435                }
10436            }
10437        }
10438
10439        return errList;
10440    }
10441
10442    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10443        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10444            if (currApp != null) {
10445                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10446            }
10447            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10448        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10449            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10450        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10451            if (currApp != null) {
10452                currApp.lru = 0;
10453            }
10454            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10455        } else if (adj >= ProcessList.SERVICE_ADJ) {
10456            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10457        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10458            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10459        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10460            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10461        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10462            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10463        } else {
10464            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10465        }
10466    }
10467
10468    private void fillInProcMemInfo(ProcessRecord app,
10469            ActivityManager.RunningAppProcessInfo outInfo) {
10470        outInfo.pid = app.pid;
10471        outInfo.uid = app.info.uid;
10472        if (mHeavyWeightProcess == app) {
10473            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10474        }
10475        if (app.persistent) {
10476            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10477        }
10478        if (app.activities.size() > 0) {
10479            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10480        }
10481        outInfo.lastTrimLevel = app.trimMemoryLevel;
10482        int adj = app.curAdj;
10483        outInfo.importance = oomAdjToImportance(adj, outInfo);
10484        outInfo.importanceReasonCode = app.adjTypeCode;
10485    }
10486
10487    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10488        enforceNotIsolatedCaller("getRunningAppProcesses");
10489        // Lazy instantiation of list
10490        List<ActivityManager.RunningAppProcessInfo> runList = null;
10491        final boolean allUsers = ActivityManager.checkUidPermission(
10492                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10493                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10494        int userId = UserHandle.getUserId(Binder.getCallingUid());
10495        synchronized (this) {
10496            // Iterate across all processes
10497            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10498                ProcessRecord app = mLruProcesses.get(i);
10499                if (!allUsers && app.userId != userId) {
10500                    continue;
10501                }
10502                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10503                    // Generate process state info for running application
10504                    ActivityManager.RunningAppProcessInfo currApp =
10505                        new ActivityManager.RunningAppProcessInfo(app.processName,
10506                                app.pid, app.getPackageList());
10507                    fillInProcMemInfo(app, currApp);
10508                    if (app.adjSource instanceof ProcessRecord) {
10509                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10510                        currApp.importanceReasonImportance = oomAdjToImportance(
10511                                app.adjSourceOom, null);
10512                    } else if (app.adjSource instanceof ActivityRecord) {
10513                        ActivityRecord r = (ActivityRecord)app.adjSource;
10514                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10515                    }
10516                    if (app.adjTarget instanceof ComponentName) {
10517                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10518                    }
10519                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10520                    //        + " lru=" + currApp.lru);
10521                    if (runList == null) {
10522                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10523                    }
10524                    runList.add(currApp);
10525                }
10526            }
10527        }
10528        return runList;
10529    }
10530
10531    public List<ApplicationInfo> getRunningExternalApplications() {
10532        enforceNotIsolatedCaller("getRunningExternalApplications");
10533        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10534        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10535        if (runningApps != null && runningApps.size() > 0) {
10536            Set<String> extList = new HashSet<String>();
10537            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10538                if (app.pkgList != null) {
10539                    for (String pkg : app.pkgList) {
10540                        extList.add(pkg);
10541                    }
10542                }
10543            }
10544            IPackageManager pm = AppGlobals.getPackageManager();
10545            for (String pkg : extList) {
10546                try {
10547                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10548                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10549                        retList.add(info);
10550                    }
10551                } catch (RemoteException e) {
10552                }
10553            }
10554        }
10555        return retList;
10556    }
10557
10558    @Override
10559    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10560        enforceNotIsolatedCaller("getMyMemoryState");
10561        synchronized (this) {
10562            ProcessRecord proc;
10563            synchronized (mPidsSelfLocked) {
10564                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10565            }
10566            fillInProcMemInfo(proc, outInfo);
10567        }
10568    }
10569
10570    @Override
10571    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10572        if (checkCallingPermission(android.Manifest.permission.DUMP)
10573                != PackageManager.PERMISSION_GRANTED) {
10574            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10575                    + Binder.getCallingPid()
10576                    + ", uid=" + Binder.getCallingUid()
10577                    + " without permission "
10578                    + android.Manifest.permission.DUMP);
10579            return;
10580        }
10581
10582        boolean dumpAll = false;
10583        boolean dumpClient = false;
10584        String dumpPackage = null;
10585
10586        int opti = 0;
10587        while (opti < args.length) {
10588            String opt = args[opti];
10589            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10590                break;
10591            }
10592            opti++;
10593            if ("-a".equals(opt)) {
10594                dumpAll = true;
10595            } else if ("-c".equals(opt)) {
10596                dumpClient = true;
10597            } else if ("-h".equals(opt)) {
10598                pw.println("Activity manager dump options:");
10599                pw.println("  [-a] [-c] [-h] [cmd] ...");
10600                pw.println("  cmd may be one of:");
10601                pw.println("    a[ctivities]: activity stack state");
10602                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10603                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10604                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10605                pw.println("    o[om]: out of memory management");
10606                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10607                pw.println("    provider [COMP_SPEC]: provider client-side state");
10608                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10609                pw.println("    service [COMP_SPEC]: service client-side state");
10610                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10611                pw.println("    all: dump all activities");
10612                pw.println("    top: dump the top activity");
10613                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10614                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10615                pw.println("    a partial substring in a component name, a");
10616                pw.println("    hex object identifier.");
10617                pw.println("  -a: include all available server state.");
10618                pw.println("  -c: include client state.");
10619                return;
10620            } else {
10621                pw.println("Unknown argument: " + opt + "; use -h for help");
10622            }
10623        }
10624
10625        long origId = Binder.clearCallingIdentity();
10626        boolean more = false;
10627        // Is the caller requesting to dump a particular piece of data?
10628        if (opti < args.length) {
10629            String cmd = args[opti];
10630            opti++;
10631            if ("activities".equals(cmd) || "a".equals(cmd)) {
10632                synchronized (this) {
10633                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10634                }
10635            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10636                String[] newArgs;
10637                String name;
10638                if (opti >= args.length) {
10639                    name = null;
10640                    newArgs = EMPTY_STRING_ARRAY;
10641                } else {
10642                    name = args[opti];
10643                    opti++;
10644                    newArgs = new String[args.length - opti];
10645                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10646                            args.length - opti);
10647                }
10648                synchronized (this) {
10649                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10650                }
10651            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10652                String[] newArgs;
10653                String name;
10654                if (opti >= args.length) {
10655                    name = null;
10656                    newArgs = EMPTY_STRING_ARRAY;
10657                } else {
10658                    name = args[opti];
10659                    opti++;
10660                    newArgs = new String[args.length - opti];
10661                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10662                            args.length - opti);
10663                }
10664                synchronized (this) {
10665                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10666                }
10667            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10668                String[] newArgs;
10669                String name;
10670                if (opti >= args.length) {
10671                    name = null;
10672                    newArgs = EMPTY_STRING_ARRAY;
10673                } else {
10674                    name = args[opti];
10675                    opti++;
10676                    newArgs = new String[args.length - opti];
10677                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10678                            args.length - opti);
10679                }
10680                synchronized (this) {
10681                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10682                }
10683            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10684                synchronized (this) {
10685                    dumpOomLocked(fd, pw, args, opti, true);
10686                }
10687            } else if ("provider".equals(cmd)) {
10688                String[] newArgs;
10689                String name;
10690                if (opti >= args.length) {
10691                    name = null;
10692                    newArgs = EMPTY_STRING_ARRAY;
10693                } else {
10694                    name = args[opti];
10695                    opti++;
10696                    newArgs = new String[args.length - opti];
10697                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10698                }
10699                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10700                    pw.println("No providers match: " + name);
10701                    pw.println("Use -h for help.");
10702                }
10703            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10704                synchronized (this) {
10705                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10706                }
10707            } else if ("service".equals(cmd)) {
10708                String[] newArgs;
10709                String name;
10710                if (opti >= args.length) {
10711                    name = null;
10712                    newArgs = EMPTY_STRING_ARRAY;
10713                } else {
10714                    name = args[opti];
10715                    opti++;
10716                    newArgs = new String[args.length - opti];
10717                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10718                            args.length - opti);
10719                }
10720                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10721                    pw.println("No services match: " + name);
10722                    pw.println("Use -h for help.");
10723                }
10724            } else if ("package".equals(cmd)) {
10725                String[] newArgs;
10726                if (opti >= args.length) {
10727                    pw.println("package: no package name specified");
10728                    pw.println("Use -h for help.");
10729                } else {
10730                    dumpPackage = args[opti];
10731                    opti++;
10732                    newArgs = new String[args.length - opti];
10733                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10734                            args.length - opti);
10735                    args = newArgs;
10736                    opti = 0;
10737                    more = true;
10738                }
10739            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10740                synchronized (this) {
10741                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10742                }
10743            } else {
10744                // Dumping a single activity?
10745                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10746                    pw.println("Bad activity command, or no activities match: " + cmd);
10747                    pw.println("Use -h for help.");
10748                }
10749            }
10750            if (!more) {
10751                Binder.restoreCallingIdentity(origId);
10752                return;
10753            }
10754        }
10755
10756        // No piece of data specified, dump everything.
10757        synchronized (this) {
10758            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10759            pw.println();
10760            if (dumpAll) {
10761                pw.println("-------------------------------------------------------------------------------");
10762            }
10763            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10764            pw.println();
10765            if (dumpAll) {
10766                pw.println("-------------------------------------------------------------------------------");
10767            }
10768            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10769            pw.println();
10770            if (dumpAll) {
10771                pw.println("-------------------------------------------------------------------------------");
10772            }
10773            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10774            pw.println();
10775            if (dumpAll) {
10776                pw.println("-------------------------------------------------------------------------------");
10777            }
10778            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10779            pw.println();
10780            if (dumpAll) {
10781                pw.println("-------------------------------------------------------------------------------");
10782            }
10783            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10784        }
10785        Binder.restoreCallingIdentity(origId);
10786    }
10787
10788    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10789            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10790        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10791
10792        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10793                dumpPackage);
10794        boolean needSep = printedAnything;
10795
10796        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10797                dumpPackage, needSep, "  mFocusedActivity: ");
10798        if (printed) {
10799            printedAnything = true;
10800            needSep = false;
10801        }
10802
10803        if (dumpPackage == null) {
10804            if (needSep) {
10805                pw.println();
10806            }
10807            needSep = true;
10808            printedAnything = true;
10809            mStackSupervisor.dump(pw, "  ");
10810        }
10811
10812        if (mRecentTasks.size() > 0) {
10813            boolean printedHeader = false;
10814
10815            final int N = mRecentTasks.size();
10816            for (int i=0; i<N; i++) {
10817                TaskRecord tr = mRecentTasks.get(i);
10818                if (dumpPackage != null) {
10819                    if (tr.realActivity == null ||
10820                            !dumpPackage.equals(tr.realActivity)) {
10821                        continue;
10822                    }
10823                }
10824                if (!printedHeader) {
10825                    if (needSep) {
10826                        pw.println();
10827                    }
10828                    pw.println("  Recent tasks:");
10829                    printedHeader = true;
10830                    printedAnything = true;
10831                }
10832                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10833                        pw.println(tr);
10834                if (dumpAll) {
10835                    mRecentTasks.get(i).dump(pw, "    ");
10836                }
10837            }
10838        }
10839
10840        if (!printedAnything) {
10841            pw.println("  (nothing)");
10842        }
10843    }
10844
10845    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10846            int opti, boolean dumpAll, String dumpPackage) {
10847        boolean needSep = false;
10848        boolean printedAnything = false;
10849        int numPers = 0;
10850
10851        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10852
10853        if (dumpAll) {
10854            final int NP = mProcessNames.getMap().size();
10855            for (int ip=0; ip<NP; ip++) {
10856                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10857                final int NA = procs.size();
10858                for (int ia=0; ia<NA; ia++) {
10859                    ProcessRecord r = procs.valueAt(ia);
10860                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10861                        continue;
10862                    }
10863                    if (!needSep) {
10864                        pw.println("  All known processes:");
10865                        needSep = true;
10866                        printedAnything = true;
10867                    }
10868                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10869                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10870                        pw.print(" "); pw.println(r);
10871                    r.dump(pw, "    ");
10872                    if (r.persistent) {
10873                        numPers++;
10874                    }
10875                }
10876            }
10877        }
10878
10879        if (mIsolatedProcesses.size() > 0) {
10880            boolean printed = false;
10881            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10882                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10883                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10884                    continue;
10885                }
10886                if (!printed) {
10887                    if (needSep) {
10888                        pw.println();
10889                    }
10890                    pw.println("  Isolated process list (sorted by uid):");
10891                    printedAnything = true;
10892                    printed = true;
10893                    needSep = true;
10894                }
10895                pw.println(String.format("%sIsolated #%2d: %s",
10896                        "    ", i, r.toString()));
10897            }
10898        }
10899
10900        if (mLruProcesses.size() > 0) {
10901            if (needSep) {
10902                pw.println();
10903            }
10904            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10905                    pw.print(" total, non-act at ");
10906                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10907                    pw.print(", non-svc at ");
10908                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10909                    pw.println("):");
10910            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10911            needSep = true;
10912            printedAnything = true;
10913        }
10914
10915        if (dumpAll || dumpPackage != null) {
10916            synchronized (mPidsSelfLocked) {
10917                boolean printed = false;
10918                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10919                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10920                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10921                        continue;
10922                    }
10923                    if (!printed) {
10924                        if (needSep) pw.println();
10925                        needSep = true;
10926                        pw.println("  PID mappings:");
10927                        printed = true;
10928                        printedAnything = true;
10929                    }
10930                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10931                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10932                }
10933            }
10934        }
10935
10936        if (mForegroundProcesses.size() > 0) {
10937            synchronized (mPidsSelfLocked) {
10938                boolean printed = false;
10939                for (int i=0; i<mForegroundProcesses.size(); i++) {
10940                    ProcessRecord r = mPidsSelfLocked.get(
10941                            mForegroundProcesses.valueAt(i).pid);
10942                    if (dumpPackage != null && (r == null
10943                            || !r.pkgList.containsKey(dumpPackage))) {
10944                        continue;
10945                    }
10946                    if (!printed) {
10947                        if (needSep) pw.println();
10948                        needSep = true;
10949                        pw.println("  Foreground Processes:");
10950                        printed = true;
10951                        printedAnything = true;
10952                    }
10953                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10954                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10955                }
10956            }
10957        }
10958
10959        if (mPersistentStartingProcesses.size() > 0) {
10960            if (needSep) pw.println();
10961            needSep = true;
10962            printedAnything = true;
10963            pw.println("  Persisent processes that are starting:");
10964            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10965                    "Starting Norm", "Restarting PERS", dumpPackage);
10966        }
10967
10968        if (mRemovedProcesses.size() > 0) {
10969            if (needSep) pw.println();
10970            needSep = true;
10971            printedAnything = true;
10972            pw.println("  Processes that are being removed:");
10973            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10974                    "Removed Norm", "Removed PERS", dumpPackage);
10975        }
10976
10977        if (mProcessesOnHold.size() > 0) {
10978            if (needSep) pw.println();
10979            needSep = true;
10980            printedAnything = true;
10981            pw.println("  Processes that are on old until the system is ready:");
10982            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10983                    "OnHold Norm", "OnHold PERS", dumpPackage);
10984        }
10985
10986        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10987
10988        if (mProcessCrashTimes.getMap().size() > 0) {
10989            boolean printed = false;
10990            long now = SystemClock.uptimeMillis();
10991            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10992            final int NP = pmap.size();
10993            for (int ip=0; ip<NP; ip++) {
10994                String pname = pmap.keyAt(ip);
10995                SparseArray<Long> uids = pmap.valueAt(ip);
10996                final int N = uids.size();
10997                for (int i=0; i<N; i++) {
10998                    int puid = uids.keyAt(i);
10999                    ProcessRecord r = mProcessNames.get(pname, puid);
11000                    if (dumpPackage != null && (r == null
11001                            || !r.pkgList.containsKey(dumpPackage))) {
11002                        continue;
11003                    }
11004                    if (!printed) {
11005                        if (needSep) pw.println();
11006                        needSep = true;
11007                        pw.println("  Time since processes crashed:");
11008                        printed = true;
11009                        printedAnything = true;
11010                    }
11011                    pw.print("    Process "); pw.print(pname);
11012                            pw.print(" uid "); pw.print(puid);
11013                            pw.print(": last crashed ");
11014                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11015                            pw.println(" ago");
11016                }
11017            }
11018        }
11019
11020        if (mBadProcesses.getMap().size() > 0) {
11021            boolean printed = false;
11022            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11023            final int NP = pmap.size();
11024            for (int ip=0; ip<NP; ip++) {
11025                String pname = pmap.keyAt(ip);
11026                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11027                final int N = uids.size();
11028                for (int i=0; i<N; i++) {
11029                    int puid = uids.keyAt(i);
11030                    ProcessRecord r = mProcessNames.get(pname, puid);
11031                    if (dumpPackage != null && (r == null
11032                            || !r.pkgList.containsKey(dumpPackage))) {
11033                        continue;
11034                    }
11035                    if (!printed) {
11036                        if (needSep) pw.println();
11037                        needSep = true;
11038                        pw.println("  Bad processes:");
11039                        printedAnything = true;
11040                    }
11041                    BadProcessInfo info = uids.valueAt(i);
11042                    pw.print("    Bad process "); pw.print(pname);
11043                            pw.print(" uid "); pw.print(puid);
11044                            pw.print(": crashed at time "); pw.println(info.time);
11045                    if (info.shortMsg != null) {
11046                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11047                    }
11048                    if (info.longMsg != null) {
11049                        pw.print("      Long msg: "); pw.println(info.longMsg);
11050                    }
11051                    if (info.stack != null) {
11052                        pw.println("      Stack:");
11053                        int lastPos = 0;
11054                        for (int pos=0; pos<info.stack.length(); pos++) {
11055                            if (info.stack.charAt(pos) == '\n') {
11056                                pw.print("        ");
11057                                pw.write(info.stack, lastPos, pos-lastPos);
11058                                pw.println();
11059                                lastPos = pos+1;
11060                            }
11061                        }
11062                        if (lastPos < info.stack.length()) {
11063                            pw.print("        ");
11064                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11065                            pw.println();
11066                        }
11067                    }
11068                }
11069            }
11070        }
11071
11072        if (dumpPackage == null) {
11073            pw.println();
11074            needSep = false;
11075            pw.println("  mStartedUsers:");
11076            for (int i=0; i<mStartedUsers.size(); i++) {
11077                UserStartedState uss = mStartedUsers.valueAt(i);
11078                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11079                        pw.print(": "); uss.dump("", pw);
11080            }
11081            pw.print("  mStartedUserArray: [");
11082            for (int i=0; i<mStartedUserArray.length; i++) {
11083                if (i > 0) pw.print(", ");
11084                pw.print(mStartedUserArray[i]);
11085            }
11086            pw.println("]");
11087            pw.print("  mUserLru: [");
11088            for (int i=0; i<mUserLru.size(); i++) {
11089                if (i > 0) pw.print(", ");
11090                pw.print(mUserLru.get(i));
11091            }
11092            pw.println("]");
11093            if (dumpAll) {
11094                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11095            }
11096        }
11097        if (mHomeProcess != null && (dumpPackage == null
11098                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11099            if (needSep) {
11100                pw.println();
11101                needSep = false;
11102            }
11103            pw.println("  mHomeProcess: " + mHomeProcess);
11104        }
11105        if (mPreviousProcess != null && (dumpPackage == null
11106                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11107            if (needSep) {
11108                pw.println();
11109                needSep = false;
11110            }
11111            pw.println("  mPreviousProcess: " + mPreviousProcess);
11112        }
11113        if (dumpAll) {
11114            StringBuilder sb = new StringBuilder(128);
11115            sb.append("  mPreviousProcessVisibleTime: ");
11116            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11117            pw.println(sb);
11118        }
11119        if (mHeavyWeightProcess != null && (dumpPackage == null
11120                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11121            if (needSep) {
11122                pw.println();
11123                needSep = false;
11124            }
11125            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11126        }
11127        if (dumpPackage == null) {
11128            pw.println("  mConfiguration: " + mConfiguration);
11129        }
11130        if (dumpAll) {
11131            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11132            if (mCompatModePackages.getPackages().size() > 0) {
11133                boolean printed = false;
11134                for (Map.Entry<String, Integer> entry
11135                        : mCompatModePackages.getPackages().entrySet()) {
11136                    String pkg = entry.getKey();
11137                    int mode = entry.getValue();
11138                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11139                        continue;
11140                    }
11141                    if (!printed) {
11142                        pw.println("  mScreenCompatPackages:");
11143                        printed = true;
11144                    }
11145                    pw.print("    "); pw.print(pkg); pw.print(": ");
11146                            pw.print(mode); pw.println();
11147                }
11148            }
11149        }
11150        if (dumpPackage == null) {
11151            if (mSleeping || mWentToSleep || mLockScreenShown) {
11152                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11153                        + " mLockScreenShown " + mLockScreenShown);
11154            }
11155            if (mShuttingDown) {
11156                pw.println("  mShuttingDown=" + mShuttingDown);
11157            }
11158        }
11159        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11160                || mOrigWaitForDebugger) {
11161            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11162                    || dumpPackage.equals(mOrigDebugApp)) {
11163                if (needSep) {
11164                    pw.println();
11165                    needSep = false;
11166                }
11167                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11168                        + " mDebugTransient=" + mDebugTransient
11169                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11170            }
11171        }
11172        if (mOpenGlTraceApp != null) {
11173            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11174                if (needSep) {
11175                    pw.println();
11176                    needSep = false;
11177                }
11178                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11179            }
11180        }
11181        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11182                || mProfileFd != null) {
11183            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11184                if (needSep) {
11185                    pw.println();
11186                    needSep = false;
11187                }
11188                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11189                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11190                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11191                        + mAutoStopProfiler);
11192            }
11193        }
11194        if (dumpPackage == null) {
11195            if (mAlwaysFinishActivities || mController != null) {
11196                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11197                        + " mController=" + mController);
11198            }
11199            if (dumpAll) {
11200                pw.println("  Total persistent processes: " + numPers);
11201                pw.println("  mProcessesReady=" + mProcessesReady
11202                        + " mSystemReady=" + mSystemReady);
11203                pw.println("  mBooting=" + mBooting
11204                        + " mBooted=" + mBooted
11205                        + " mFactoryTest=" + mFactoryTest);
11206                pw.print("  mLastPowerCheckRealtime=");
11207                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11208                        pw.println("");
11209                pw.print("  mLastPowerCheckUptime=");
11210                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11211                        pw.println("");
11212                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11213                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11214                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11215                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11216                        + " (" + mLruProcesses.size() + " total)"
11217                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11218                        + " mNumServiceProcs=" + mNumServiceProcs
11219                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11220                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11221                        + " mLastMemoryLevel" + mLastMemoryLevel
11222                        + " mLastNumProcesses" + mLastNumProcesses);
11223                long now = SystemClock.uptimeMillis();
11224                pw.print("  mLastIdleTime=");
11225                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11226                        pw.print(" mLowRamSinceLastIdle=");
11227                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11228                        pw.println();
11229            }
11230        }
11231
11232        if (!printedAnything) {
11233            pw.println("  (nothing)");
11234        }
11235    }
11236
11237    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11238            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11239        if (mProcessesToGc.size() > 0) {
11240            boolean printed = false;
11241            long now = SystemClock.uptimeMillis();
11242            for (int i=0; i<mProcessesToGc.size(); i++) {
11243                ProcessRecord proc = mProcessesToGc.get(i);
11244                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11245                    continue;
11246                }
11247                if (!printed) {
11248                    if (needSep) pw.println();
11249                    needSep = true;
11250                    pw.println("  Processes that are waiting to GC:");
11251                    printed = true;
11252                }
11253                pw.print("    Process "); pw.println(proc);
11254                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11255                        pw.print(", last gced=");
11256                        pw.print(now-proc.lastRequestedGc);
11257                        pw.print(" ms ago, last lowMem=");
11258                        pw.print(now-proc.lastLowMemory);
11259                        pw.println(" ms ago");
11260
11261            }
11262        }
11263        return needSep;
11264    }
11265
11266    void printOomLevel(PrintWriter pw, String name, int adj) {
11267        pw.print("    ");
11268        if (adj >= 0) {
11269            pw.print(' ');
11270            if (adj < 10) pw.print(' ');
11271        } else {
11272            if (adj > -10) pw.print(' ');
11273        }
11274        pw.print(adj);
11275        pw.print(": ");
11276        pw.print(name);
11277        pw.print(" (");
11278        pw.print(mProcessList.getMemLevel(adj)/1024);
11279        pw.println(" kB)");
11280    }
11281
11282    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11283            int opti, boolean dumpAll) {
11284        boolean needSep = false;
11285
11286        if (mLruProcesses.size() > 0) {
11287            if (needSep) pw.println();
11288            needSep = true;
11289            pw.println("  OOM levels:");
11290            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11291            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11292            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11293            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11294            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11295            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11296            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11297            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11298            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11299            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11300            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11301            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11302            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11303
11304            if (needSep) pw.println();
11305            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11306                    pw.print(" total, non-act at ");
11307                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11308                    pw.print(", non-svc at ");
11309                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11310                    pw.println("):");
11311            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11312            needSep = true;
11313        }
11314
11315        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11316
11317        pw.println();
11318        pw.println("  mHomeProcess: " + mHomeProcess);
11319        pw.println("  mPreviousProcess: " + mPreviousProcess);
11320        if (mHeavyWeightProcess != null) {
11321            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11322        }
11323
11324        return true;
11325    }
11326
11327    /**
11328     * There are three ways to call this:
11329     *  - no provider specified: dump all the providers
11330     *  - a flattened component name that matched an existing provider was specified as the
11331     *    first arg: dump that one provider
11332     *  - the first arg isn't the flattened component name of an existing provider:
11333     *    dump all providers whose component contains the first arg as a substring
11334     */
11335    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11336            int opti, boolean dumpAll) {
11337        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11338    }
11339
11340    static class ItemMatcher {
11341        ArrayList<ComponentName> components;
11342        ArrayList<String> strings;
11343        ArrayList<Integer> objects;
11344        boolean all;
11345
11346        ItemMatcher() {
11347            all = true;
11348        }
11349
11350        void build(String name) {
11351            ComponentName componentName = ComponentName.unflattenFromString(name);
11352            if (componentName != null) {
11353                if (components == null) {
11354                    components = new ArrayList<ComponentName>();
11355                }
11356                components.add(componentName);
11357                all = false;
11358            } else {
11359                int objectId = 0;
11360                // Not a '/' separated full component name; maybe an object ID?
11361                try {
11362                    objectId = Integer.parseInt(name, 16);
11363                    if (objects == null) {
11364                        objects = new ArrayList<Integer>();
11365                    }
11366                    objects.add(objectId);
11367                    all = false;
11368                } catch (RuntimeException e) {
11369                    // Not an integer; just do string match.
11370                    if (strings == null) {
11371                        strings = new ArrayList<String>();
11372                    }
11373                    strings.add(name);
11374                    all = false;
11375                }
11376            }
11377        }
11378
11379        int build(String[] args, int opti) {
11380            for (; opti<args.length; opti++) {
11381                String name = args[opti];
11382                if ("--".equals(name)) {
11383                    return opti+1;
11384                }
11385                build(name);
11386            }
11387            return opti;
11388        }
11389
11390        boolean match(Object object, ComponentName comp) {
11391            if (all) {
11392                return true;
11393            }
11394            if (components != null) {
11395                for (int i=0; i<components.size(); i++) {
11396                    if (components.get(i).equals(comp)) {
11397                        return true;
11398                    }
11399                }
11400            }
11401            if (objects != null) {
11402                for (int i=0; i<objects.size(); i++) {
11403                    if (System.identityHashCode(object) == objects.get(i)) {
11404                        return true;
11405                    }
11406                }
11407            }
11408            if (strings != null) {
11409                String flat = comp.flattenToString();
11410                for (int i=0; i<strings.size(); i++) {
11411                    if (flat.contains(strings.get(i))) {
11412                        return true;
11413                    }
11414                }
11415            }
11416            return false;
11417        }
11418    }
11419
11420    /**
11421     * There are three things that cmd can be:
11422     *  - a flattened component name that matches an existing activity
11423     *  - the cmd arg isn't the flattened component name of an existing activity:
11424     *    dump all activity whose component contains the cmd as a substring
11425     *  - A hex number of the ActivityRecord object instance.
11426     */
11427    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11428            int opti, boolean dumpAll) {
11429        ArrayList<ActivityRecord> activities;
11430
11431        synchronized (this) {
11432            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11433        }
11434
11435        if (activities.size() <= 0) {
11436            return false;
11437        }
11438
11439        String[] newArgs = new String[args.length - opti];
11440        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11441
11442        TaskRecord lastTask = null;
11443        boolean needSep = false;
11444        for (int i=activities.size()-1; i>=0; i--) {
11445            ActivityRecord r = activities.get(i);
11446            if (needSep) {
11447                pw.println();
11448            }
11449            needSep = true;
11450            synchronized (this) {
11451                if (lastTask != r.task) {
11452                    lastTask = r.task;
11453                    pw.print("TASK "); pw.print(lastTask.affinity);
11454                            pw.print(" id="); pw.println(lastTask.taskId);
11455                    if (dumpAll) {
11456                        lastTask.dump(pw, "  ");
11457                    }
11458                }
11459            }
11460            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11461        }
11462        return true;
11463    }
11464
11465    /**
11466     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11467     * there is a thread associated with the activity.
11468     */
11469    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11470            final ActivityRecord r, String[] args, boolean dumpAll) {
11471        String innerPrefix = prefix + "  ";
11472        synchronized (this) {
11473            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11474                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11475                    pw.print(" pid=");
11476                    if (r.app != null) pw.println(r.app.pid);
11477                    else pw.println("(not running)");
11478            if (dumpAll) {
11479                r.dump(pw, innerPrefix);
11480            }
11481        }
11482        if (r.app != null && r.app.thread != null) {
11483            // flush anything that is already in the PrintWriter since the thread is going
11484            // to write to the file descriptor directly
11485            pw.flush();
11486            try {
11487                TransferPipe tp = new TransferPipe();
11488                try {
11489                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11490                            r.appToken, innerPrefix, args);
11491                    tp.go(fd);
11492                } finally {
11493                    tp.kill();
11494                }
11495            } catch (IOException e) {
11496                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11497            } catch (RemoteException e) {
11498                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11499            }
11500        }
11501    }
11502
11503    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11504            int opti, boolean dumpAll, String dumpPackage) {
11505        boolean needSep = false;
11506        boolean onlyHistory = false;
11507        boolean printedAnything = false;
11508
11509        if ("history".equals(dumpPackage)) {
11510            if (opti < args.length && "-s".equals(args[opti])) {
11511                dumpAll = false;
11512            }
11513            onlyHistory = true;
11514            dumpPackage = null;
11515        }
11516
11517        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11518        if (!onlyHistory && dumpAll) {
11519            if (mRegisteredReceivers.size() > 0) {
11520                boolean printed = false;
11521                Iterator it = mRegisteredReceivers.values().iterator();
11522                while (it.hasNext()) {
11523                    ReceiverList r = (ReceiverList)it.next();
11524                    if (dumpPackage != null && (r.app == null ||
11525                            !dumpPackage.equals(r.app.info.packageName))) {
11526                        continue;
11527                    }
11528                    if (!printed) {
11529                        pw.println("  Registered Receivers:");
11530                        needSep = true;
11531                        printed = true;
11532                        printedAnything = true;
11533                    }
11534                    pw.print("  * "); pw.println(r);
11535                    r.dump(pw, "    ");
11536                }
11537            }
11538
11539            if (mReceiverResolver.dump(pw, needSep ?
11540                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11541                    "    ", dumpPackage, false)) {
11542                needSep = true;
11543                printedAnything = true;
11544            }
11545        }
11546
11547        for (BroadcastQueue q : mBroadcastQueues) {
11548            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11549            printedAnything |= needSep;
11550        }
11551
11552        needSep = true;
11553
11554        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11555            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11556                if (needSep) {
11557                    pw.println();
11558                }
11559                needSep = true;
11560                printedAnything = true;
11561                pw.print("  Sticky broadcasts for user ");
11562                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11563                StringBuilder sb = new StringBuilder(128);
11564                for (Map.Entry<String, ArrayList<Intent>> ent
11565                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11566                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11567                    if (dumpAll) {
11568                        pw.println(":");
11569                        ArrayList<Intent> intents = ent.getValue();
11570                        final int N = intents.size();
11571                        for (int i=0; i<N; i++) {
11572                            sb.setLength(0);
11573                            sb.append("    Intent: ");
11574                            intents.get(i).toShortString(sb, false, true, false, false);
11575                            pw.println(sb.toString());
11576                            Bundle bundle = intents.get(i).getExtras();
11577                            if (bundle != null) {
11578                                pw.print("      ");
11579                                pw.println(bundle.toString());
11580                            }
11581                        }
11582                    } else {
11583                        pw.println("");
11584                    }
11585                }
11586            }
11587        }
11588
11589        if (!onlyHistory && dumpAll) {
11590            pw.println();
11591            for (BroadcastQueue queue : mBroadcastQueues) {
11592                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11593                        + queue.mBroadcastsScheduled);
11594            }
11595            pw.println("  mHandler:");
11596            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11597            needSep = true;
11598            printedAnything = true;
11599        }
11600
11601        if (!printedAnything) {
11602            pw.println("  (nothing)");
11603        }
11604    }
11605
11606    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11607            int opti, boolean dumpAll, String dumpPackage) {
11608        boolean needSep;
11609        boolean printedAnything = false;
11610
11611        ItemMatcher matcher = new ItemMatcher();
11612        matcher.build(args, opti);
11613
11614        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11615
11616        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11617        printedAnything |= needSep;
11618
11619        if (mLaunchingProviders.size() > 0) {
11620            boolean printed = false;
11621            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11622                ContentProviderRecord r = mLaunchingProviders.get(i);
11623                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11624                    continue;
11625                }
11626                if (!printed) {
11627                    if (needSep) pw.println();
11628                    needSep = true;
11629                    pw.println("  Launching content providers:");
11630                    printed = true;
11631                    printedAnything = true;
11632                }
11633                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11634                        pw.println(r);
11635            }
11636        }
11637
11638        if (mGrantedUriPermissions.size() > 0) {
11639            boolean printed = false;
11640            int dumpUid = -2;
11641            if (dumpPackage != null) {
11642                try {
11643                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11644                } catch (NameNotFoundException e) {
11645                    dumpUid = -1;
11646                }
11647            }
11648            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11649                int uid = mGrantedUriPermissions.keyAt(i);
11650                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11651                    continue;
11652                }
11653                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11654                if (!printed) {
11655                    if (needSep) pw.println();
11656                    needSep = true;
11657                    pw.println("  Granted Uri Permissions:");
11658                    printed = true;
11659                    printedAnything = true;
11660                }
11661                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11662                for (UriPermission perm : perms.values()) {
11663                    pw.print("    "); pw.println(perm);
11664                    if (dumpAll) {
11665                        perm.dump(pw, "      ");
11666                    }
11667                }
11668            }
11669        }
11670
11671        if (!printedAnything) {
11672            pw.println("  (nothing)");
11673        }
11674    }
11675
11676    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11677            int opti, boolean dumpAll, String dumpPackage) {
11678        boolean printed = false;
11679
11680        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11681
11682        if (mIntentSenderRecords.size() > 0) {
11683            Iterator<WeakReference<PendingIntentRecord>> it
11684                    = mIntentSenderRecords.values().iterator();
11685            while (it.hasNext()) {
11686                WeakReference<PendingIntentRecord> ref = it.next();
11687                PendingIntentRecord rec = ref != null ? ref.get(): null;
11688                if (dumpPackage != null && (rec == null
11689                        || !dumpPackage.equals(rec.key.packageName))) {
11690                    continue;
11691                }
11692                printed = true;
11693                if (rec != null) {
11694                    pw.print("  * "); pw.println(rec);
11695                    if (dumpAll) {
11696                        rec.dump(pw, "    ");
11697                    }
11698                } else {
11699                    pw.print("  * "); pw.println(ref);
11700                }
11701            }
11702        }
11703
11704        if (!printed) {
11705            pw.println("  (nothing)");
11706        }
11707    }
11708
11709    private static final int dumpProcessList(PrintWriter pw,
11710            ActivityManagerService service, List list,
11711            String prefix, String normalLabel, String persistentLabel,
11712            String dumpPackage) {
11713        int numPers = 0;
11714        final int N = list.size()-1;
11715        for (int i=N; i>=0; i--) {
11716            ProcessRecord r = (ProcessRecord)list.get(i);
11717            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11718                continue;
11719            }
11720            pw.println(String.format("%s%s #%2d: %s",
11721                    prefix, (r.persistent ? persistentLabel : normalLabel),
11722                    i, r.toString()));
11723            if (r.persistent) {
11724                numPers++;
11725            }
11726        }
11727        return numPers;
11728    }
11729
11730    private static final boolean dumpProcessOomList(PrintWriter pw,
11731            ActivityManagerService service, List<ProcessRecord> origList,
11732            String prefix, String normalLabel, String persistentLabel,
11733            boolean inclDetails, String dumpPackage) {
11734
11735        ArrayList<Pair<ProcessRecord, Integer>> list
11736                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11737        for (int i=0; i<origList.size(); i++) {
11738            ProcessRecord r = origList.get(i);
11739            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11740                continue;
11741            }
11742            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11743        }
11744
11745        if (list.size() <= 0) {
11746            return false;
11747        }
11748
11749        Comparator<Pair<ProcessRecord, Integer>> comparator
11750                = new Comparator<Pair<ProcessRecord, Integer>>() {
11751            @Override
11752            public int compare(Pair<ProcessRecord, Integer> object1,
11753                    Pair<ProcessRecord, Integer> object2) {
11754                if (object1.first.setAdj != object2.first.setAdj) {
11755                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11756                }
11757                if (object1.second.intValue() != object2.second.intValue()) {
11758                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11759                }
11760                return 0;
11761            }
11762        };
11763
11764        Collections.sort(list, comparator);
11765
11766        final long curRealtime = SystemClock.elapsedRealtime();
11767        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11768        final long curUptime = SystemClock.uptimeMillis();
11769        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11770
11771        for (int i=list.size()-1; i>=0; i--) {
11772            ProcessRecord r = list.get(i).first;
11773            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11774            char schedGroup;
11775            switch (r.setSchedGroup) {
11776                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11777                    schedGroup = 'B';
11778                    break;
11779                case Process.THREAD_GROUP_DEFAULT:
11780                    schedGroup = 'F';
11781                    break;
11782                default:
11783                    schedGroup = '?';
11784                    break;
11785            }
11786            char foreground;
11787            if (r.foregroundActivities) {
11788                foreground = 'A';
11789            } else if (r.foregroundServices) {
11790                foreground = 'S';
11791            } else {
11792                foreground = ' ';
11793            }
11794            String procState = ProcessList.makeProcStateString(r.curProcState);
11795            pw.print(prefix);
11796            pw.print(r.persistent ? persistentLabel : normalLabel);
11797            pw.print(" #");
11798            int num = (origList.size()-1)-list.get(i).second;
11799            if (num < 10) pw.print(' ');
11800            pw.print(num);
11801            pw.print(": ");
11802            pw.print(oomAdj);
11803            pw.print(' ');
11804            pw.print(schedGroup);
11805            pw.print('/');
11806            pw.print(foreground);
11807            pw.print('/');
11808            pw.print(procState);
11809            pw.print(" trm:");
11810            if (r.trimMemoryLevel < 10) pw.print(' ');
11811            pw.print(r.trimMemoryLevel);
11812            pw.print(' ');
11813            pw.print(r.toShortString());
11814            pw.print(" (");
11815            pw.print(r.adjType);
11816            pw.println(')');
11817            if (r.adjSource != null || r.adjTarget != null) {
11818                pw.print(prefix);
11819                pw.print("    ");
11820                if (r.adjTarget instanceof ComponentName) {
11821                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11822                } else if (r.adjTarget != null) {
11823                    pw.print(r.adjTarget.toString());
11824                } else {
11825                    pw.print("{null}");
11826                }
11827                pw.print("<=");
11828                if (r.adjSource instanceof ProcessRecord) {
11829                    pw.print("Proc{");
11830                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11831                    pw.println("}");
11832                } else if (r.adjSource != null) {
11833                    pw.println(r.adjSource.toString());
11834                } else {
11835                    pw.println("{null}");
11836                }
11837            }
11838            if (inclDetails) {
11839                pw.print(prefix);
11840                pw.print("    ");
11841                pw.print("oom: max="); pw.print(r.maxAdj);
11842                pw.print(" curRaw="); pw.print(r.curRawAdj);
11843                pw.print(" setRaw="); pw.print(r.setRawAdj);
11844                pw.print(" cur="); pw.print(r.curAdj);
11845                pw.print(" set="); pw.println(r.setAdj);
11846                pw.print(prefix);
11847                pw.print("    ");
11848                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11849                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11850                pw.print(" lastPss="); pw.print(r.lastPss);
11851                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11852                pw.print(prefix);
11853                pw.print("    ");
11854                pw.print("keeping="); pw.print(r.keeping);
11855                pw.print(" cached="); pw.print(r.cached);
11856                pw.print(" empty="); pw.print(r.empty);
11857                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11858
11859                if (!r.keeping) {
11860                    if (r.lastWakeTime != 0) {
11861                        long wtime;
11862                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11863                        synchronized (stats) {
11864                            wtime = stats.getProcessWakeTime(r.info.uid,
11865                                    r.pid, curRealtime);
11866                        }
11867                        long timeUsed = wtime - r.lastWakeTime;
11868                        pw.print(prefix);
11869                        pw.print("    ");
11870                        pw.print("keep awake over ");
11871                        TimeUtils.formatDuration(realtimeSince, pw);
11872                        pw.print(" used ");
11873                        TimeUtils.formatDuration(timeUsed, pw);
11874                        pw.print(" (");
11875                        pw.print((timeUsed*100)/realtimeSince);
11876                        pw.println("%)");
11877                    }
11878                    if (r.lastCpuTime != 0) {
11879                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11880                        pw.print(prefix);
11881                        pw.print("    ");
11882                        pw.print("run cpu over ");
11883                        TimeUtils.formatDuration(uptimeSince, pw);
11884                        pw.print(" used ");
11885                        TimeUtils.formatDuration(timeUsed, pw);
11886                        pw.print(" (");
11887                        pw.print((timeUsed*100)/uptimeSince);
11888                        pw.println("%)");
11889                    }
11890                }
11891            }
11892        }
11893        return true;
11894    }
11895
11896    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11897        ArrayList<ProcessRecord> procs;
11898        synchronized (this) {
11899            if (args != null && args.length > start
11900                    && args[start].charAt(0) != '-') {
11901                procs = new ArrayList<ProcessRecord>();
11902                int pid = -1;
11903                try {
11904                    pid = Integer.parseInt(args[start]);
11905                } catch (NumberFormatException e) {
11906                }
11907                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11908                    ProcessRecord proc = mLruProcesses.get(i);
11909                    if (proc.pid == pid) {
11910                        procs.add(proc);
11911                    } else if (proc.processName.equals(args[start])) {
11912                        procs.add(proc);
11913                    }
11914                }
11915                if (procs.size() <= 0) {
11916                    return null;
11917                }
11918            } else {
11919                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11920            }
11921        }
11922        return procs;
11923    }
11924
11925    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11926            PrintWriter pw, String[] args) {
11927        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11928        if (procs == null) {
11929            pw.println("No process found for: " + args[0]);
11930            return;
11931        }
11932
11933        long uptime = SystemClock.uptimeMillis();
11934        long realtime = SystemClock.elapsedRealtime();
11935        pw.println("Applications Graphics Acceleration Info:");
11936        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11937
11938        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11939            ProcessRecord r = procs.get(i);
11940            if (r.thread != null) {
11941                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11942                pw.flush();
11943                try {
11944                    TransferPipe tp = new TransferPipe();
11945                    try {
11946                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11947                        tp.go(fd);
11948                    } finally {
11949                        tp.kill();
11950                    }
11951                } catch (IOException e) {
11952                    pw.println("Failure while dumping the app: " + r);
11953                    pw.flush();
11954                } catch (RemoteException e) {
11955                    pw.println("Got a RemoteException while dumping the app " + r);
11956                    pw.flush();
11957                }
11958            }
11959        }
11960    }
11961
11962    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11963        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11964        if (procs == null) {
11965            pw.println("No process found for: " + args[0]);
11966            return;
11967        }
11968
11969        pw.println("Applications Database Info:");
11970
11971        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11972            ProcessRecord r = procs.get(i);
11973            if (r.thread != null) {
11974                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11975                pw.flush();
11976                try {
11977                    TransferPipe tp = new TransferPipe();
11978                    try {
11979                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11980                        tp.go(fd);
11981                    } finally {
11982                        tp.kill();
11983                    }
11984                } catch (IOException e) {
11985                    pw.println("Failure while dumping the app: " + r);
11986                    pw.flush();
11987                } catch (RemoteException e) {
11988                    pw.println("Got a RemoteException while dumping the app " + r);
11989                    pw.flush();
11990                }
11991            }
11992        }
11993    }
11994
11995    final static class MemItem {
11996        final boolean isProc;
11997        final String label;
11998        final String shortLabel;
11999        final long pss;
12000        final int id;
12001        final boolean hasActivities;
12002        ArrayList<MemItem> subitems;
12003
12004        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12005                boolean _hasActivities) {
12006            isProc = true;
12007            label = _label;
12008            shortLabel = _shortLabel;
12009            pss = _pss;
12010            id = _id;
12011            hasActivities = _hasActivities;
12012        }
12013
12014        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12015            isProc = false;
12016            label = _label;
12017            shortLabel = _shortLabel;
12018            pss = _pss;
12019            id = _id;
12020            hasActivities = false;
12021        }
12022    }
12023
12024    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12025            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12026        if (sort && !isCompact) {
12027            Collections.sort(items, new Comparator<MemItem>() {
12028                @Override
12029                public int compare(MemItem lhs, MemItem rhs) {
12030                    if (lhs.pss < rhs.pss) {
12031                        return 1;
12032                    } else if (lhs.pss > rhs.pss) {
12033                        return -1;
12034                    }
12035                    return 0;
12036                }
12037            });
12038        }
12039
12040        for (int i=0; i<items.size(); i++) {
12041            MemItem mi = items.get(i);
12042            if (!isCompact) {
12043                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12044            } else if (mi.isProc) {
12045                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12046                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12047                pw.println(mi.hasActivities ? ",a" : ",e");
12048            } else {
12049                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12050                pw.println(mi.pss);
12051            }
12052            if (mi.subitems != null) {
12053                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12054                        true, isCompact);
12055            }
12056        }
12057    }
12058
12059    // These are in KB.
12060    static final long[] DUMP_MEM_BUCKETS = new long[] {
12061        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12062        120*1024, 160*1024, 200*1024,
12063        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12064        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12065    };
12066
12067    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12068            boolean stackLike) {
12069        int start = label.lastIndexOf('.');
12070        if (start >= 0) start++;
12071        else start = 0;
12072        int end = label.length();
12073        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12074            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12075                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12076                out.append(bucket);
12077                out.append(stackLike ? "MB." : "MB ");
12078                out.append(label, start, end);
12079                return;
12080            }
12081        }
12082        out.append(memKB/1024);
12083        out.append(stackLike ? "MB." : "MB ");
12084        out.append(label, start, end);
12085    }
12086
12087    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12088            ProcessList.NATIVE_ADJ,
12089            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12090            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12091            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12092            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12093            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12094    };
12095    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12096            "Native",
12097            "System", "Persistent", "Foreground",
12098            "Visible", "Perceptible",
12099            "Heavy Weight", "Backup",
12100            "A Services", "Home",
12101            "Previous", "B Services", "Cached"
12102    };
12103    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12104            "native",
12105            "sys", "pers", "fore",
12106            "vis", "percept",
12107            "heavy", "backup",
12108            "servicea", "home",
12109            "prev", "serviceb", "cached"
12110    };
12111
12112    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12113            long realtime, boolean isCheckinRequest, boolean isCompact) {
12114        if (isCheckinRequest || isCompact) {
12115            // short checkin version
12116            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12117        } else {
12118            pw.println("Applications Memory Usage (kB):");
12119            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12120        }
12121    }
12122
12123    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12124            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12125        boolean dumpDetails = false;
12126        boolean dumpFullDetails = false;
12127        boolean dumpDalvik = false;
12128        boolean oomOnly = false;
12129        boolean isCompact = false;
12130        boolean localOnly = false;
12131
12132        int opti = 0;
12133        while (opti < args.length) {
12134            String opt = args[opti];
12135            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12136                break;
12137            }
12138            opti++;
12139            if ("-a".equals(opt)) {
12140                dumpDetails = true;
12141                dumpFullDetails = true;
12142                dumpDalvik = true;
12143            } else if ("-d".equals(opt)) {
12144                dumpDalvik = true;
12145            } else if ("-c".equals(opt)) {
12146                isCompact = true;
12147            } else if ("--oom".equals(opt)) {
12148                oomOnly = true;
12149            } else if ("--local".equals(opt)) {
12150                localOnly = true;
12151            } else if ("-h".equals(opt)) {
12152                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12153                pw.println("  -a: include all available information for each process.");
12154                pw.println("  -d: include dalvik details when dumping process details.");
12155                pw.println("  -c: dump in a compact machine-parseable representation.");
12156                pw.println("  --oom: only show processes organized by oom adj.");
12157                pw.println("  --local: only collect details locally, don't call process.");
12158                pw.println("If [process] is specified it can be the name or ");
12159                pw.println("pid of a specific process to dump.");
12160                return;
12161            } else {
12162                pw.println("Unknown argument: " + opt + "; use -h for help");
12163            }
12164        }
12165
12166        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12167        long uptime = SystemClock.uptimeMillis();
12168        long realtime = SystemClock.elapsedRealtime();
12169        final long[] tmpLong = new long[1];
12170
12171        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12172        if (procs == null) {
12173            // No Java processes.  Maybe they want to print a native process.
12174            if (args != null && args.length > opti
12175                    && args[opti].charAt(0) != '-') {
12176                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12177                        = new ArrayList<ProcessCpuTracker.Stats>();
12178                updateCpuStatsNow();
12179                int findPid = -1;
12180                try {
12181                    findPid = Integer.parseInt(args[opti]);
12182                } catch (NumberFormatException e) {
12183                }
12184                synchronized (mProcessCpuThread) {
12185                    final int N = mProcessCpuTracker.countStats();
12186                    for (int i=0; i<N; i++) {
12187                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12188                        if (st.pid == findPid || (st.baseName != null
12189                                && st.baseName.equals(args[opti]))) {
12190                            nativeProcs.add(st);
12191                        }
12192                    }
12193                }
12194                if (nativeProcs.size() > 0) {
12195                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12196                            isCompact);
12197                    Debug.MemoryInfo mi = null;
12198                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12199                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12200                        final int pid = r.pid;
12201                        if (!isCheckinRequest && dumpDetails) {
12202                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12203                        }
12204                        if (mi == null) {
12205                            mi = new Debug.MemoryInfo();
12206                        }
12207                        if (dumpDetails || (!brief && !oomOnly)) {
12208                            Debug.getMemoryInfo(pid, mi);
12209                        } else {
12210                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12211                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12212                        }
12213                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12214                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12215                        if (isCheckinRequest) {
12216                            pw.println();
12217                        }
12218                    }
12219                    return;
12220                }
12221            }
12222            pw.println("No process found for: " + args[opti]);
12223            return;
12224        }
12225
12226        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12227            dumpDetails = true;
12228        }
12229
12230        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12231
12232        String[] innerArgs = new String[args.length-opti];
12233        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12234
12235        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12236        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12237        long nativePss=0, dalvikPss=0, otherPss=0;
12238        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12239
12240        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12241        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12242                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12243
12244        long totalPss = 0;
12245        long cachedPss = 0;
12246
12247        Debug.MemoryInfo mi = null;
12248        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12249            final ProcessRecord r = procs.get(i);
12250            final IApplicationThread thread;
12251            final int pid;
12252            final int oomAdj;
12253            final boolean hasActivities;
12254            synchronized (this) {
12255                thread = r.thread;
12256                pid = r.pid;
12257                oomAdj = r.getSetAdjWithServices();
12258                hasActivities = r.activities.size() > 0;
12259            }
12260            if (thread != null) {
12261                if (!isCheckinRequest && dumpDetails) {
12262                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12263                }
12264                if (mi == null) {
12265                    mi = new Debug.MemoryInfo();
12266                }
12267                if (dumpDetails || (!brief && !oomOnly)) {
12268                    Debug.getMemoryInfo(pid, mi);
12269                } else {
12270                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12271                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12272                }
12273                if (dumpDetails) {
12274                    if (localOnly) {
12275                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12276                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12277                        if (isCheckinRequest) {
12278                            pw.println();
12279                        }
12280                    } else {
12281                        try {
12282                            pw.flush();
12283                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12284                                    dumpDalvik, innerArgs);
12285                        } catch (RemoteException e) {
12286                            if (!isCheckinRequest) {
12287                                pw.println("Got RemoteException!");
12288                                pw.flush();
12289                            }
12290                        }
12291                    }
12292                }
12293
12294                final long myTotalPss = mi.getTotalPss();
12295                final long myTotalUss = mi.getTotalUss();
12296
12297                synchronized (this) {
12298                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12299                        // Record this for posterity if the process has been stable.
12300                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12301                    }
12302                }
12303
12304                if (!isCheckinRequest && mi != null) {
12305                    totalPss += myTotalPss;
12306                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12307                            (hasActivities ? " / activities)" : ")"),
12308                            r.processName, myTotalPss, pid, hasActivities);
12309                    procMems.add(pssItem);
12310                    procMemsMap.put(pid, pssItem);
12311
12312                    nativePss += mi.nativePss;
12313                    dalvikPss += mi.dalvikPss;
12314                    otherPss += mi.otherPss;
12315                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12316                        long mem = mi.getOtherPss(j);
12317                        miscPss[j] += mem;
12318                        otherPss -= mem;
12319                    }
12320
12321                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12322                        cachedPss += myTotalPss;
12323                    }
12324
12325                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12326                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12327                                || oomIndex == (oomPss.length-1)) {
12328                            oomPss[oomIndex] += myTotalPss;
12329                            if (oomProcs[oomIndex] == null) {
12330                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12331                            }
12332                            oomProcs[oomIndex].add(pssItem);
12333                            break;
12334                        }
12335                    }
12336                }
12337            }
12338        }
12339
12340        if (!isCheckinRequest && procs.size() > 1) {
12341            // If we are showing aggregations, also look for native processes to
12342            // include so that our aggregations are more accurate.
12343            updateCpuStatsNow();
12344            synchronized (mProcessCpuThread) {
12345                final int N = mProcessCpuTracker.countStats();
12346                for (int i=0; i<N; i++) {
12347                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12348                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12349                        if (mi == null) {
12350                            mi = new Debug.MemoryInfo();
12351                        }
12352                        if (!brief && !oomOnly) {
12353                            Debug.getMemoryInfo(st.pid, mi);
12354                        } else {
12355                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12356                            mi.nativePrivateDirty = (int)tmpLong[0];
12357                        }
12358
12359                        final long myTotalPss = mi.getTotalPss();
12360                        totalPss += myTotalPss;
12361
12362                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12363                                st.name, myTotalPss, st.pid, false);
12364                        procMems.add(pssItem);
12365
12366                        nativePss += mi.nativePss;
12367                        dalvikPss += mi.dalvikPss;
12368                        otherPss += mi.otherPss;
12369                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12370                            long mem = mi.getOtherPss(j);
12371                            miscPss[j] += mem;
12372                            otherPss -= mem;
12373                        }
12374                        oomPss[0] += myTotalPss;
12375                        if (oomProcs[0] == null) {
12376                            oomProcs[0] = new ArrayList<MemItem>();
12377                        }
12378                        oomProcs[0].add(pssItem);
12379                    }
12380                }
12381            }
12382
12383            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12384
12385            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12386            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12387            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12388            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12389                String label = Debug.MemoryInfo.getOtherLabel(j);
12390                catMems.add(new MemItem(label, label, miscPss[j], j));
12391            }
12392
12393            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12394            for (int j=0; j<oomPss.length; j++) {
12395                if (oomPss[j] != 0) {
12396                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12397                            : DUMP_MEM_OOM_LABEL[j];
12398                    MemItem item = new MemItem(label, label, oomPss[j],
12399                            DUMP_MEM_OOM_ADJ[j]);
12400                    item.subitems = oomProcs[j];
12401                    oomMems.add(item);
12402                }
12403            }
12404
12405            if (!brief && !oomOnly && !isCompact) {
12406                pw.println();
12407                pw.println("Total PSS by process:");
12408                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12409                pw.println();
12410            }
12411            if (!isCompact) {
12412                pw.println("Total PSS by OOM adjustment:");
12413            }
12414            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12415            if (!brief && !oomOnly) {
12416                PrintWriter out = categoryPw != null ? categoryPw : pw;
12417                if (!isCompact) {
12418                    out.println();
12419                    out.println("Total PSS by category:");
12420                }
12421                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12422            }
12423            if (!isCompact) {
12424                pw.println();
12425            }
12426            MemInfoReader memInfo = new MemInfoReader();
12427            memInfo.readMemInfo();
12428            if (!brief) {
12429                if (!isCompact) {
12430                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12431                    pw.print(" kB (status ");
12432                    switch (mLastMemoryLevel) {
12433                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12434                            pw.println("normal)");
12435                            break;
12436                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12437                            pw.println("moderate)");
12438                            break;
12439                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12440                            pw.println("low)");
12441                            break;
12442                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12443                            pw.println("critical)");
12444                            break;
12445                        default:
12446                            pw.print(mLastMemoryLevel);
12447                            pw.println(")");
12448                            break;
12449                    }
12450                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12451                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12452                            pw.print(cachedPss); pw.print(" cached pss + ");
12453                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12454                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12455                } else {
12456                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12457                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12458                            + memInfo.getFreeSizeKb()); pw.print(",");
12459                    pw.println(totalPss - cachedPss);
12460                }
12461            }
12462            if (!isCompact) {
12463                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12464                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12465                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12466                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12467                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12468                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12469                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12470                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12471                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12472                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12473                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12474            }
12475            if (!brief) {
12476                if (memInfo.getZramTotalSizeKb() != 0) {
12477                    if (!isCompact) {
12478                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12479                                pw.print(" kB physical used for ");
12480                                pw.print(memInfo.getSwapTotalSizeKb()
12481                                        - memInfo.getSwapFreeSizeKb());
12482                                pw.print(" kB in swap (");
12483                                pw.print(memInfo.getSwapTotalSizeKb());
12484                                pw.println(" kB total swap)");
12485                    } else {
12486                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12487                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12488                                pw.println(memInfo.getSwapFreeSizeKb());
12489                    }
12490                }
12491                final int[] SINGLE_LONG_FORMAT = new int[] {
12492                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12493                };
12494                long[] longOut = new long[1];
12495                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12496                        SINGLE_LONG_FORMAT, null, longOut, null);
12497                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12498                longOut[0] = 0;
12499                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12500                        SINGLE_LONG_FORMAT, null, longOut, null);
12501                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12502                longOut[0] = 0;
12503                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12504                        SINGLE_LONG_FORMAT, null, longOut, null);
12505                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12506                longOut[0] = 0;
12507                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12508                        SINGLE_LONG_FORMAT, null, longOut, null);
12509                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12510                if (!isCompact) {
12511                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12512                        pw.print("      KSM: "); pw.print(sharing);
12513                                pw.print(" kB saved from shared ");
12514                                pw.print(shared); pw.println(" kB");
12515                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12516                                pw.print(voltile); pw.println(" kB volatile");
12517                    }
12518                    pw.print("   Tuning: ");
12519                    pw.print(ActivityManager.staticGetMemoryClass());
12520                    pw.print(" (large ");
12521                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12522                    pw.print("), oom ");
12523                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12524                    pw.print(" kB");
12525                    pw.print(", restore limit ");
12526                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12527                    pw.print(" kB");
12528                    if (ActivityManager.isLowRamDeviceStatic()) {
12529                        pw.print(" (low-ram)");
12530                    }
12531                    if (ActivityManager.isHighEndGfx()) {
12532                        pw.print(" (high-end-gfx)");
12533                    }
12534                    pw.println();
12535                } else {
12536                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12537                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12538                    pw.println(voltile);
12539                    pw.print("tuning,");
12540                    pw.print(ActivityManager.staticGetMemoryClass());
12541                    pw.print(',');
12542                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12543                    pw.print(',');
12544                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12545                    if (ActivityManager.isLowRamDeviceStatic()) {
12546                        pw.print(",low-ram");
12547                    }
12548                    if (ActivityManager.isHighEndGfx()) {
12549                        pw.print(",high-end-gfx");
12550                    }
12551                    pw.println();
12552                }
12553            }
12554        }
12555    }
12556
12557    /**
12558     * Searches array of arguments for the specified string
12559     * @param args array of argument strings
12560     * @param value value to search for
12561     * @return true if the value is contained in the array
12562     */
12563    private static boolean scanArgs(String[] args, String value) {
12564        if (args != null) {
12565            for (String arg : args) {
12566                if (value.equals(arg)) {
12567                    return true;
12568                }
12569            }
12570        }
12571        return false;
12572    }
12573
12574    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12575            ContentProviderRecord cpr, boolean always) {
12576        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12577
12578        if (!inLaunching || always) {
12579            synchronized (cpr) {
12580                cpr.launchingApp = null;
12581                cpr.notifyAll();
12582            }
12583            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12584            String names[] = cpr.info.authority.split(";");
12585            for (int j = 0; j < names.length; j++) {
12586                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12587            }
12588        }
12589
12590        for (int i=0; i<cpr.connections.size(); i++) {
12591            ContentProviderConnection conn = cpr.connections.get(i);
12592            if (conn.waiting) {
12593                // If this connection is waiting for the provider, then we don't
12594                // need to mess with its process unless we are always removing
12595                // or for some reason the provider is not currently launching.
12596                if (inLaunching && !always) {
12597                    continue;
12598                }
12599            }
12600            ProcessRecord capp = conn.client;
12601            conn.dead = true;
12602            if (conn.stableCount > 0) {
12603                if (!capp.persistent && capp.thread != null
12604                        && capp.pid != 0
12605                        && capp.pid != MY_PID) {
12606                    killUnneededProcessLocked(capp, "depends on provider "
12607                            + cpr.name.flattenToShortString()
12608                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12609                }
12610            } else if (capp.thread != null && conn.provider.provider != null) {
12611                try {
12612                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12613                } catch (RemoteException e) {
12614                }
12615                // In the protocol here, we don't expect the client to correctly
12616                // clean up this connection, we'll just remove it.
12617                cpr.connections.remove(i);
12618                conn.client.conProviders.remove(conn);
12619            }
12620        }
12621
12622        if (inLaunching && always) {
12623            mLaunchingProviders.remove(cpr);
12624        }
12625        return inLaunching;
12626    }
12627
12628    /**
12629     * Main code for cleaning up a process when it has gone away.  This is
12630     * called both as a result of the process dying, or directly when stopping
12631     * a process when running in single process mode.
12632     */
12633    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12634            boolean restarting, boolean allowRestart, int index) {
12635        if (index >= 0) {
12636            removeLruProcessLocked(app);
12637            ProcessList.remove(app.pid);
12638        }
12639
12640        mProcessesToGc.remove(app);
12641        mPendingPssProcesses.remove(app);
12642
12643        // Dismiss any open dialogs.
12644        if (app.crashDialog != null && !app.forceCrashReport) {
12645            app.crashDialog.dismiss();
12646            app.crashDialog = null;
12647        }
12648        if (app.anrDialog != null) {
12649            app.anrDialog.dismiss();
12650            app.anrDialog = null;
12651        }
12652        if (app.waitDialog != null) {
12653            app.waitDialog.dismiss();
12654            app.waitDialog = null;
12655        }
12656
12657        app.crashing = false;
12658        app.notResponding = false;
12659
12660        app.resetPackageList(mProcessStats);
12661        app.unlinkDeathRecipient();
12662        app.makeInactive(mProcessStats);
12663        app.forcingToForeground = null;
12664        updateProcessForegroundLocked(app, false, false);
12665        app.foregroundActivities = false;
12666        app.hasShownUi = false;
12667        app.treatLikeActivity = false;
12668        app.hasAboveClient = false;
12669        app.hasClientActivities = false;
12670
12671        mServices.killServicesLocked(app, allowRestart);
12672
12673        boolean restart = false;
12674
12675        // Remove published content providers.
12676        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12677            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12678            final boolean always = app.bad || !allowRestart;
12679            if (removeDyingProviderLocked(app, cpr, always) || always) {
12680                // We left the provider in the launching list, need to
12681                // restart it.
12682                restart = true;
12683            }
12684
12685            cpr.provider = null;
12686            cpr.proc = null;
12687        }
12688        app.pubProviders.clear();
12689
12690        // Take care of any launching providers waiting for this process.
12691        if (checkAppInLaunchingProvidersLocked(app, false)) {
12692            restart = true;
12693        }
12694
12695        // Unregister from connected content providers.
12696        if (!app.conProviders.isEmpty()) {
12697            for (int i=0; i<app.conProviders.size(); i++) {
12698                ContentProviderConnection conn = app.conProviders.get(i);
12699                conn.provider.connections.remove(conn);
12700            }
12701            app.conProviders.clear();
12702        }
12703
12704        // At this point there may be remaining entries in mLaunchingProviders
12705        // where we were the only one waiting, so they are no longer of use.
12706        // Look for these and clean up if found.
12707        // XXX Commented out for now.  Trying to figure out a way to reproduce
12708        // the actual situation to identify what is actually going on.
12709        if (false) {
12710            for (int i=0; i<mLaunchingProviders.size(); i++) {
12711                ContentProviderRecord cpr = (ContentProviderRecord)
12712                        mLaunchingProviders.get(i);
12713                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12714                    synchronized (cpr) {
12715                        cpr.launchingApp = null;
12716                        cpr.notifyAll();
12717                    }
12718                }
12719            }
12720        }
12721
12722        skipCurrentReceiverLocked(app);
12723
12724        // Unregister any receivers.
12725        for (int i=app.receivers.size()-1; i>=0; i--) {
12726            removeReceiverLocked(app.receivers.valueAt(i));
12727        }
12728        app.receivers.clear();
12729
12730        // If the app is undergoing backup, tell the backup manager about it
12731        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12732            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12733                    + mBackupTarget.appInfo + " died during backup");
12734            try {
12735                IBackupManager bm = IBackupManager.Stub.asInterface(
12736                        ServiceManager.getService(Context.BACKUP_SERVICE));
12737                bm.agentDisconnected(app.info.packageName);
12738            } catch (RemoteException e) {
12739                // can't happen; backup manager is local
12740            }
12741        }
12742
12743        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12744            ProcessChangeItem item = mPendingProcessChanges.get(i);
12745            if (item.pid == app.pid) {
12746                mPendingProcessChanges.remove(i);
12747                mAvailProcessChanges.add(item);
12748            }
12749        }
12750        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12751
12752        // If the caller is restarting this app, then leave it in its
12753        // current lists and let the caller take care of it.
12754        if (restarting) {
12755            return;
12756        }
12757
12758        if (!app.persistent || app.isolated) {
12759            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12760                    "Removing non-persistent process during cleanup: " + app);
12761            mProcessNames.remove(app.processName, app.uid);
12762            mIsolatedProcesses.remove(app.uid);
12763            if (mHeavyWeightProcess == app) {
12764                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12765                        mHeavyWeightProcess.userId, 0));
12766                mHeavyWeightProcess = null;
12767            }
12768        } else if (!app.removed) {
12769            // This app is persistent, so we need to keep its record around.
12770            // If it is not already on the pending app list, add it there
12771            // and start a new process for it.
12772            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12773                mPersistentStartingProcesses.add(app);
12774                restart = true;
12775            }
12776        }
12777        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12778                "Clean-up removing on hold: " + app);
12779        mProcessesOnHold.remove(app);
12780
12781        if (app == mHomeProcess) {
12782            mHomeProcess = null;
12783        }
12784        if (app == mPreviousProcess) {
12785            mPreviousProcess = null;
12786        }
12787
12788        if (restart && !app.isolated) {
12789            // We have components that still need to be running in the
12790            // process, so re-launch it.
12791            mProcessNames.put(app.processName, app.uid, app);
12792            startProcessLocked(app, "restart", app.processName);
12793        } else if (app.pid > 0 && app.pid != MY_PID) {
12794            // Goodbye!
12795            boolean removed;
12796            synchronized (mPidsSelfLocked) {
12797                mPidsSelfLocked.remove(app.pid);
12798                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12799            }
12800            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12801                    app.processName, app.info.uid);
12802            if (app.isolated) {
12803                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12804            }
12805            app.setPid(0);
12806        }
12807    }
12808
12809    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12810        // Look through the content providers we are waiting to have launched,
12811        // and if any run in this process then either schedule a restart of
12812        // the process or kill the client waiting for it if this process has
12813        // gone bad.
12814        int NL = mLaunchingProviders.size();
12815        boolean restart = false;
12816        for (int i=0; i<NL; i++) {
12817            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12818            if (cpr.launchingApp == app) {
12819                if (!alwaysBad && !app.bad) {
12820                    restart = true;
12821                } else {
12822                    removeDyingProviderLocked(app, cpr, true);
12823                    // cpr should have been removed from mLaunchingProviders
12824                    NL = mLaunchingProviders.size();
12825                    i--;
12826                }
12827            }
12828        }
12829        return restart;
12830    }
12831
12832    // =========================================================
12833    // SERVICES
12834    // =========================================================
12835
12836    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12837            int flags) {
12838        enforceNotIsolatedCaller("getServices");
12839        synchronized (this) {
12840            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12841        }
12842    }
12843
12844    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12845        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12846        synchronized (this) {
12847            return mServices.getRunningServiceControlPanelLocked(name);
12848        }
12849    }
12850
12851    public ComponentName startService(IApplicationThread caller, Intent service,
12852            String resolvedType, int userId) {
12853        enforceNotIsolatedCaller("startService");
12854        // Refuse possible leaked file descriptors
12855        if (service != null && service.hasFileDescriptors() == true) {
12856            throw new IllegalArgumentException("File descriptors passed in Intent");
12857        }
12858
12859        if (DEBUG_SERVICE)
12860            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12861        synchronized(this) {
12862            final int callingPid = Binder.getCallingPid();
12863            final int callingUid = Binder.getCallingUid();
12864            final long origId = Binder.clearCallingIdentity();
12865            ComponentName res = mServices.startServiceLocked(caller, service,
12866                    resolvedType, callingPid, callingUid, userId);
12867            Binder.restoreCallingIdentity(origId);
12868            return res;
12869        }
12870    }
12871
12872    ComponentName startServiceInPackage(int uid,
12873            Intent service, String resolvedType, int userId) {
12874        synchronized(this) {
12875            if (DEBUG_SERVICE)
12876                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12877            final long origId = Binder.clearCallingIdentity();
12878            ComponentName res = mServices.startServiceLocked(null, service,
12879                    resolvedType, -1, uid, userId);
12880            Binder.restoreCallingIdentity(origId);
12881            return res;
12882        }
12883    }
12884
12885    public int stopService(IApplicationThread caller, Intent service,
12886            String resolvedType, int userId) {
12887        enforceNotIsolatedCaller("stopService");
12888        // Refuse possible leaked file descriptors
12889        if (service != null && service.hasFileDescriptors() == true) {
12890            throw new IllegalArgumentException("File descriptors passed in Intent");
12891        }
12892
12893        synchronized(this) {
12894            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12895        }
12896    }
12897
12898    public IBinder peekService(Intent service, String resolvedType) {
12899        enforceNotIsolatedCaller("peekService");
12900        // Refuse possible leaked file descriptors
12901        if (service != null && service.hasFileDescriptors() == true) {
12902            throw new IllegalArgumentException("File descriptors passed in Intent");
12903        }
12904        synchronized(this) {
12905            return mServices.peekServiceLocked(service, resolvedType);
12906        }
12907    }
12908
12909    public boolean stopServiceToken(ComponentName className, IBinder token,
12910            int startId) {
12911        synchronized(this) {
12912            return mServices.stopServiceTokenLocked(className, token, startId);
12913        }
12914    }
12915
12916    public void setServiceForeground(ComponentName className, IBinder token,
12917            int id, Notification notification, boolean removeNotification) {
12918        synchronized(this) {
12919            mServices.setServiceForegroundLocked(className, token, id, notification,
12920                    removeNotification);
12921        }
12922    }
12923
12924    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12925            boolean requireFull, String name, String callerPackage) {
12926        final int callingUserId = UserHandle.getUserId(callingUid);
12927        if (callingUserId != userId) {
12928            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12929                if ((requireFull || checkComponentPermission(
12930                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12931                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12932                        && checkComponentPermission(
12933                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12934                                callingPid, callingUid, -1, true)
12935                                != PackageManager.PERMISSION_GRANTED) {
12936                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12937                        // In this case, they would like to just execute as their
12938                        // owner user instead of failing.
12939                        userId = callingUserId;
12940                    } else {
12941                        StringBuilder builder = new StringBuilder(128);
12942                        builder.append("Permission Denial: ");
12943                        builder.append(name);
12944                        if (callerPackage != null) {
12945                            builder.append(" from ");
12946                            builder.append(callerPackage);
12947                        }
12948                        builder.append(" asks to run as user ");
12949                        builder.append(userId);
12950                        builder.append(" but is calling from user ");
12951                        builder.append(UserHandle.getUserId(callingUid));
12952                        builder.append("; this requires ");
12953                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12954                        if (!requireFull) {
12955                            builder.append(" or ");
12956                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12957                        }
12958                        String msg = builder.toString();
12959                        Slog.w(TAG, msg);
12960                        throw new SecurityException(msg);
12961                    }
12962                }
12963            }
12964            if (userId == UserHandle.USER_CURRENT
12965                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12966                // Note that we may be accessing this outside of a lock...
12967                // shouldn't be a big deal, if this is being called outside
12968                // of a locked context there is intrinsically a race with
12969                // the value the caller will receive and someone else changing it.
12970                userId = mCurrentUserId;
12971            }
12972            if (!allowAll && userId < 0) {
12973                throw new IllegalArgumentException(
12974                        "Call does not support special user #" + userId);
12975            }
12976        }
12977        return userId;
12978    }
12979
12980    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12981            String className, int flags) {
12982        boolean result = false;
12983        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12984            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12985                if (ActivityManager.checkUidPermission(
12986                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12987                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12988                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12989                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12990                            + " requests FLAG_SINGLE_USER, but app does not hold "
12991                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12992                    Slog.w(TAG, msg);
12993                    throw new SecurityException(msg);
12994                }
12995                result = true;
12996            }
12997        } else if (componentProcessName == aInfo.packageName) {
12998            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12999        } else if ("system".equals(componentProcessName)) {
13000            result = true;
13001        }
13002        if (DEBUG_MU) {
13003            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13004                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13005        }
13006        return result;
13007    }
13008
13009    public int bindService(IApplicationThread caller, IBinder token,
13010            Intent service, String resolvedType,
13011            IServiceConnection connection, int flags, int userId) {
13012        enforceNotIsolatedCaller("bindService");
13013        // Refuse possible leaked file descriptors
13014        if (service != null && service.hasFileDescriptors() == true) {
13015            throw new IllegalArgumentException("File descriptors passed in Intent");
13016        }
13017
13018        synchronized(this) {
13019            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13020                    connection, flags, userId);
13021        }
13022    }
13023
13024    public boolean unbindService(IServiceConnection connection) {
13025        synchronized (this) {
13026            return mServices.unbindServiceLocked(connection);
13027        }
13028    }
13029
13030    public void publishService(IBinder token, Intent intent, IBinder service) {
13031        // Refuse possible leaked file descriptors
13032        if (intent != null && intent.hasFileDescriptors() == true) {
13033            throw new IllegalArgumentException("File descriptors passed in Intent");
13034        }
13035
13036        synchronized(this) {
13037            if (!(token instanceof ServiceRecord)) {
13038                throw new IllegalArgumentException("Invalid service token");
13039            }
13040            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13041        }
13042    }
13043
13044    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13045        // Refuse possible leaked file descriptors
13046        if (intent != null && intent.hasFileDescriptors() == true) {
13047            throw new IllegalArgumentException("File descriptors passed in Intent");
13048        }
13049
13050        synchronized(this) {
13051            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13052        }
13053    }
13054
13055    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13056        synchronized(this) {
13057            if (!(token instanceof ServiceRecord)) {
13058                throw new IllegalArgumentException("Invalid service token");
13059            }
13060            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13061        }
13062    }
13063
13064    // =========================================================
13065    // BACKUP AND RESTORE
13066    // =========================================================
13067
13068    // Cause the target app to be launched if necessary and its backup agent
13069    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13070    // activity manager to announce its creation.
13071    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13072        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13073        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13074
13075        synchronized(this) {
13076            // !!! TODO: currently no check here that we're already bound
13077            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13078            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13079            synchronized (stats) {
13080                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13081            }
13082
13083            // Backup agent is now in use, its package can't be stopped.
13084            try {
13085                AppGlobals.getPackageManager().setPackageStoppedState(
13086                        app.packageName, false, UserHandle.getUserId(app.uid));
13087            } catch (RemoteException e) {
13088            } catch (IllegalArgumentException e) {
13089                Slog.w(TAG, "Failed trying to unstop package "
13090                        + app.packageName + ": " + e);
13091            }
13092
13093            BackupRecord r = new BackupRecord(ss, app, backupMode);
13094            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13095                    ? new ComponentName(app.packageName, app.backupAgentName)
13096                    : new ComponentName("android", "FullBackupAgent");
13097            // startProcessLocked() returns existing proc's record if it's already running
13098            ProcessRecord proc = startProcessLocked(app.processName, app,
13099                    false, 0, "backup", hostingName, false, false, false);
13100            if (proc == null) {
13101                Slog.e(TAG, "Unable to start backup agent process " + r);
13102                return false;
13103            }
13104
13105            r.app = proc;
13106            mBackupTarget = r;
13107            mBackupAppName = app.packageName;
13108
13109            // Try not to kill the process during backup
13110            updateOomAdjLocked(proc);
13111
13112            // If the process is already attached, schedule the creation of the backup agent now.
13113            // If it is not yet live, this will be done when it attaches to the framework.
13114            if (proc.thread != null) {
13115                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13116                try {
13117                    proc.thread.scheduleCreateBackupAgent(app,
13118                            compatibilityInfoForPackageLocked(app), backupMode);
13119                } catch (RemoteException e) {
13120                    // Will time out on the backup manager side
13121                }
13122            } else {
13123                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13124            }
13125            // Invariants: at this point, the target app process exists and the application
13126            // is either already running or in the process of coming up.  mBackupTarget and
13127            // mBackupAppName describe the app, so that when it binds back to the AM we
13128            // know that it's scheduled for a backup-agent operation.
13129        }
13130
13131        return true;
13132    }
13133
13134    @Override
13135    public void clearPendingBackup() {
13136        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13137        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13138
13139        synchronized (this) {
13140            mBackupTarget = null;
13141            mBackupAppName = null;
13142        }
13143    }
13144
13145    // A backup agent has just come up
13146    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13147        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13148                + " = " + agent);
13149
13150        synchronized(this) {
13151            if (!agentPackageName.equals(mBackupAppName)) {
13152                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13153                return;
13154            }
13155        }
13156
13157        long oldIdent = Binder.clearCallingIdentity();
13158        try {
13159            IBackupManager bm = IBackupManager.Stub.asInterface(
13160                    ServiceManager.getService(Context.BACKUP_SERVICE));
13161            bm.agentConnected(agentPackageName, agent);
13162        } catch (RemoteException e) {
13163            // can't happen; the backup manager service is local
13164        } catch (Exception e) {
13165            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13166            e.printStackTrace();
13167        } finally {
13168            Binder.restoreCallingIdentity(oldIdent);
13169        }
13170    }
13171
13172    // done with this agent
13173    public void unbindBackupAgent(ApplicationInfo appInfo) {
13174        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13175        if (appInfo == null) {
13176            Slog.w(TAG, "unbind backup agent for null app");
13177            return;
13178        }
13179
13180        synchronized(this) {
13181            try {
13182                if (mBackupAppName == null) {
13183                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13184                    return;
13185                }
13186
13187                if (!mBackupAppName.equals(appInfo.packageName)) {
13188                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13189                    return;
13190                }
13191
13192                // Not backing this app up any more; reset its OOM adjustment
13193                final ProcessRecord proc = mBackupTarget.app;
13194                updateOomAdjLocked(proc);
13195
13196                // If the app crashed during backup, 'thread' will be null here
13197                if (proc.thread != null) {
13198                    try {
13199                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13200                                compatibilityInfoForPackageLocked(appInfo));
13201                    } catch (Exception e) {
13202                        Slog.e(TAG, "Exception when unbinding backup agent:");
13203                        e.printStackTrace();
13204                    }
13205                }
13206            } finally {
13207                mBackupTarget = null;
13208                mBackupAppName = null;
13209            }
13210        }
13211    }
13212    // =========================================================
13213    // BROADCASTS
13214    // =========================================================
13215
13216    private final List getStickiesLocked(String action, IntentFilter filter,
13217            List cur, int userId) {
13218        final ContentResolver resolver = mContext.getContentResolver();
13219        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13220        if (stickies == null) {
13221            return cur;
13222        }
13223        final ArrayList<Intent> list = stickies.get(action);
13224        if (list == null) {
13225            return cur;
13226        }
13227        int N = list.size();
13228        for (int i=0; i<N; i++) {
13229            Intent intent = list.get(i);
13230            if (filter.match(resolver, intent, true, TAG) >= 0) {
13231                if (cur == null) {
13232                    cur = new ArrayList<Intent>();
13233                }
13234                cur.add(intent);
13235            }
13236        }
13237        return cur;
13238    }
13239
13240    boolean isPendingBroadcastProcessLocked(int pid) {
13241        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13242                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13243    }
13244
13245    void skipPendingBroadcastLocked(int pid) {
13246            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13247            for (BroadcastQueue queue : mBroadcastQueues) {
13248                queue.skipPendingBroadcastLocked(pid);
13249            }
13250    }
13251
13252    // The app just attached; send any pending broadcasts that it should receive
13253    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13254        boolean didSomething = false;
13255        for (BroadcastQueue queue : mBroadcastQueues) {
13256            didSomething |= queue.sendPendingBroadcastsLocked(app);
13257        }
13258        return didSomething;
13259    }
13260
13261    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13262            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13263        enforceNotIsolatedCaller("registerReceiver");
13264        int callingUid;
13265        int callingPid;
13266        synchronized(this) {
13267            ProcessRecord callerApp = null;
13268            if (caller != null) {
13269                callerApp = getRecordForAppLocked(caller);
13270                if (callerApp == null) {
13271                    throw new SecurityException(
13272                            "Unable to find app for caller " + caller
13273                            + " (pid=" + Binder.getCallingPid()
13274                            + ") when registering receiver " + receiver);
13275                }
13276                if (callerApp.info.uid != Process.SYSTEM_UID &&
13277                        !callerApp.pkgList.containsKey(callerPackage) &&
13278                        !"android".equals(callerPackage)) {
13279                    throw new SecurityException("Given caller package " + callerPackage
13280                            + " is not running in process " + callerApp);
13281                }
13282                callingUid = callerApp.info.uid;
13283                callingPid = callerApp.pid;
13284            } else {
13285                callerPackage = null;
13286                callingUid = Binder.getCallingUid();
13287                callingPid = Binder.getCallingPid();
13288            }
13289
13290            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13291                    true, true, "registerReceiver", callerPackage);
13292
13293            List allSticky = null;
13294
13295            // Look for any matching sticky broadcasts...
13296            Iterator actions = filter.actionsIterator();
13297            if (actions != null) {
13298                while (actions.hasNext()) {
13299                    String action = (String)actions.next();
13300                    allSticky = getStickiesLocked(action, filter, allSticky,
13301                            UserHandle.USER_ALL);
13302                    allSticky = getStickiesLocked(action, filter, allSticky,
13303                            UserHandle.getUserId(callingUid));
13304                }
13305            } else {
13306                allSticky = getStickiesLocked(null, filter, allSticky,
13307                        UserHandle.USER_ALL);
13308                allSticky = getStickiesLocked(null, filter, allSticky,
13309                        UserHandle.getUserId(callingUid));
13310            }
13311
13312            // The first sticky in the list is returned directly back to
13313            // the client.
13314            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13315
13316            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13317                    + ": " + sticky);
13318
13319            if (receiver == null) {
13320                return sticky;
13321            }
13322
13323            ReceiverList rl
13324                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13325            if (rl == null) {
13326                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13327                        userId, receiver);
13328                if (rl.app != null) {
13329                    rl.app.receivers.add(rl);
13330                } else {
13331                    try {
13332                        receiver.asBinder().linkToDeath(rl, 0);
13333                    } catch (RemoteException e) {
13334                        return sticky;
13335                    }
13336                    rl.linkedToDeath = true;
13337                }
13338                mRegisteredReceivers.put(receiver.asBinder(), rl);
13339            } else if (rl.uid != callingUid) {
13340                throw new IllegalArgumentException(
13341                        "Receiver requested to register for uid " + callingUid
13342                        + " was previously registered for uid " + rl.uid);
13343            } else if (rl.pid != callingPid) {
13344                throw new IllegalArgumentException(
13345                        "Receiver requested to register for pid " + callingPid
13346                        + " was previously registered for pid " + rl.pid);
13347            } else if (rl.userId != userId) {
13348                throw new IllegalArgumentException(
13349                        "Receiver requested to register for user " + userId
13350                        + " was previously registered for user " + rl.userId);
13351            }
13352            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13353                    permission, callingUid, userId);
13354            rl.add(bf);
13355            if (!bf.debugCheck()) {
13356                Slog.w(TAG, "==> For Dynamic broadast");
13357            }
13358            mReceiverResolver.addFilter(bf);
13359
13360            // Enqueue broadcasts for all existing stickies that match
13361            // this filter.
13362            if (allSticky != null) {
13363                ArrayList receivers = new ArrayList();
13364                receivers.add(bf);
13365
13366                int N = allSticky.size();
13367                for (int i=0; i<N; i++) {
13368                    Intent intent = (Intent)allSticky.get(i);
13369                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13370                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13371                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13372                            null, null, false, true, true, -1);
13373                    queue.enqueueParallelBroadcastLocked(r);
13374                    queue.scheduleBroadcastsLocked();
13375                }
13376            }
13377
13378            return sticky;
13379        }
13380    }
13381
13382    public void unregisterReceiver(IIntentReceiver receiver) {
13383        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13384
13385        final long origId = Binder.clearCallingIdentity();
13386        try {
13387            boolean doTrim = false;
13388
13389            synchronized(this) {
13390                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13391                if (rl != null) {
13392                    if (rl.curBroadcast != null) {
13393                        BroadcastRecord r = rl.curBroadcast;
13394                        final boolean doNext = finishReceiverLocked(
13395                                receiver.asBinder(), r.resultCode, r.resultData,
13396                                r.resultExtras, r.resultAbort);
13397                        if (doNext) {
13398                            doTrim = true;
13399                            r.queue.processNextBroadcast(false);
13400                        }
13401                    }
13402
13403                    if (rl.app != null) {
13404                        rl.app.receivers.remove(rl);
13405                    }
13406                    removeReceiverLocked(rl);
13407                    if (rl.linkedToDeath) {
13408                        rl.linkedToDeath = false;
13409                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13410                    }
13411                }
13412            }
13413
13414            // If we actually concluded any broadcasts, we might now be able
13415            // to trim the recipients' apps from our working set
13416            if (doTrim) {
13417                trimApplications();
13418                return;
13419            }
13420
13421        } finally {
13422            Binder.restoreCallingIdentity(origId);
13423        }
13424    }
13425
13426    void removeReceiverLocked(ReceiverList rl) {
13427        mRegisteredReceivers.remove(rl.receiver.asBinder());
13428        int N = rl.size();
13429        for (int i=0; i<N; i++) {
13430            mReceiverResolver.removeFilter(rl.get(i));
13431        }
13432    }
13433
13434    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13435        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13436            ProcessRecord r = mLruProcesses.get(i);
13437            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13438                try {
13439                    r.thread.dispatchPackageBroadcast(cmd, packages);
13440                } catch (RemoteException ex) {
13441                }
13442            }
13443        }
13444    }
13445
13446    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13447            int[] users) {
13448        List<ResolveInfo> receivers = null;
13449        try {
13450            HashSet<ComponentName> singleUserReceivers = null;
13451            boolean scannedFirstReceivers = false;
13452            for (int user : users) {
13453                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13454                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13455                if (user != 0 && newReceivers != null) {
13456                    // If this is not the primary user, we need to check for
13457                    // any receivers that should be filtered out.
13458                    for (int i=0; i<newReceivers.size(); i++) {
13459                        ResolveInfo ri = newReceivers.get(i);
13460                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13461                            newReceivers.remove(i);
13462                            i--;
13463                        }
13464                    }
13465                }
13466                if (newReceivers != null && newReceivers.size() == 0) {
13467                    newReceivers = null;
13468                }
13469                if (receivers == null) {
13470                    receivers = newReceivers;
13471                } else if (newReceivers != null) {
13472                    // We need to concatenate the additional receivers
13473                    // found with what we have do far.  This would be easy,
13474                    // but we also need to de-dup any receivers that are
13475                    // singleUser.
13476                    if (!scannedFirstReceivers) {
13477                        // Collect any single user receivers we had already retrieved.
13478                        scannedFirstReceivers = true;
13479                        for (int i=0; i<receivers.size(); i++) {
13480                            ResolveInfo ri = receivers.get(i);
13481                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13482                                ComponentName cn = new ComponentName(
13483                                        ri.activityInfo.packageName, ri.activityInfo.name);
13484                                if (singleUserReceivers == null) {
13485                                    singleUserReceivers = new HashSet<ComponentName>();
13486                                }
13487                                singleUserReceivers.add(cn);
13488                            }
13489                        }
13490                    }
13491                    // Add the new results to the existing results, tracking
13492                    // and de-dupping single user receivers.
13493                    for (int i=0; i<newReceivers.size(); i++) {
13494                        ResolveInfo ri = newReceivers.get(i);
13495                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13496                            ComponentName cn = new ComponentName(
13497                                    ri.activityInfo.packageName, ri.activityInfo.name);
13498                            if (singleUserReceivers == null) {
13499                                singleUserReceivers = new HashSet<ComponentName>();
13500                            }
13501                            if (!singleUserReceivers.contains(cn)) {
13502                                singleUserReceivers.add(cn);
13503                                receivers.add(ri);
13504                            }
13505                        } else {
13506                            receivers.add(ri);
13507                        }
13508                    }
13509                }
13510            }
13511        } catch (RemoteException ex) {
13512            // pm is in same process, this will never happen.
13513        }
13514        return receivers;
13515    }
13516
13517    private final int broadcastIntentLocked(ProcessRecord callerApp,
13518            String callerPackage, Intent intent, String resolvedType,
13519            IIntentReceiver resultTo, int resultCode, String resultData,
13520            Bundle map, String requiredPermission, int appOp,
13521            boolean ordered, boolean sticky, int callingPid, int callingUid,
13522            int userId) {
13523        intent = new Intent(intent);
13524
13525        // By default broadcasts do not go to stopped apps.
13526        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13527
13528        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13529            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13530            + " ordered=" + ordered + " userid=" + userId);
13531        if ((resultTo != null) && !ordered) {
13532            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13533        }
13534
13535        userId = handleIncomingUser(callingPid, callingUid, userId,
13536                true, false, "broadcast", callerPackage);
13537
13538        // Make sure that the user who is receiving this broadcast is started.
13539        // If not, we will just skip it.
13540        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13541            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13542                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13543                Slog.w(TAG, "Skipping broadcast of " + intent
13544                        + ": user " + userId + " is stopped");
13545                return ActivityManager.BROADCAST_SUCCESS;
13546            }
13547        }
13548
13549        /*
13550         * Prevent non-system code (defined here to be non-persistent
13551         * processes) from sending protected broadcasts.
13552         */
13553        int callingAppId = UserHandle.getAppId(callingUid);
13554        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13555            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13556            callingUid == 0) {
13557            // Always okay.
13558        } else if (callerApp == null || !callerApp.persistent) {
13559            try {
13560                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13561                        intent.getAction())) {
13562                    String msg = "Permission Denial: not allowed to send broadcast "
13563                            + intent.getAction() + " from pid="
13564                            + callingPid + ", uid=" + callingUid;
13565                    Slog.w(TAG, msg);
13566                    throw new SecurityException(msg);
13567                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13568                    // Special case for compatibility: we don't want apps to send this,
13569                    // but historically it has not been protected and apps may be using it
13570                    // to poke their own app widget.  So, instead of making it protected,
13571                    // just limit it to the caller.
13572                    if (callerApp == null) {
13573                        String msg = "Permission Denial: not allowed to send broadcast "
13574                                + intent.getAction() + " from unknown caller.";
13575                        Slog.w(TAG, msg);
13576                        throw new SecurityException(msg);
13577                    } else if (intent.getComponent() != null) {
13578                        // They are good enough to send to an explicit component...  verify
13579                        // it is being sent to the calling app.
13580                        if (!intent.getComponent().getPackageName().equals(
13581                                callerApp.info.packageName)) {
13582                            String msg = "Permission Denial: not allowed to send broadcast "
13583                                    + intent.getAction() + " to "
13584                                    + intent.getComponent().getPackageName() + " from "
13585                                    + callerApp.info.packageName;
13586                            Slog.w(TAG, msg);
13587                            throw new SecurityException(msg);
13588                        }
13589                    } else {
13590                        // Limit broadcast to their own package.
13591                        intent.setPackage(callerApp.info.packageName);
13592                    }
13593                }
13594            } catch (RemoteException e) {
13595                Slog.w(TAG, "Remote exception", e);
13596                return ActivityManager.BROADCAST_SUCCESS;
13597            }
13598        }
13599
13600        // Handle special intents: if this broadcast is from the package
13601        // manager about a package being removed, we need to remove all of
13602        // its activities from the history stack.
13603        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13604                intent.getAction());
13605        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13606                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13607                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13608                || uidRemoved) {
13609            if (checkComponentPermission(
13610                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13611                    callingPid, callingUid, -1, true)
13612                    == PackageManager.PERMISSION_GRANTED) {
13613                if (uidRemoved) {
13614                    final Bundle intentExtras = intent.getExtras();
13615                    final int uid = intentExtras != null
13616                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13617                    if (uid >= 0) {
13618                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13619                        synchronized (bs) {
13620                            bs.removeUidStatsLocked(uid);
13621                        }
13622                        mAppOpsService.uidRemoved(uid);
13623                    }
13624                } else {
13625                    // If resources are unavailable just force stop all
13626                    // those packages and flush the attribute cache as well.
13627                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13628                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13629                        if (list != null && (list.length > 0)) {
13630                            for (String pkg : list) {
13631                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13632                                        "storage unmount");
13633                            }
13634                            sendPackageBroadcastLocked(
13635                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13636                        }
13637                    } else {
13638                        Uri data = intent.getData();
13639                        String ssp;
13640                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13641                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13642                                    intent.getAction());
13643                            boolean fullUninstall = removed &&
13644                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13645                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13646                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13647                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13648                                        false, fullUninstall, userId,
13649                                        removed ? "pkg removed" : "pkg changed");
13650                            }
13651                            if (removed) {
13652                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13653                                        new String[] {ssp}, userId);
13654                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13655                                    mAppOpsService.packageRemoved(
13656                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13657
13658                                    // Remove all permissions granted from/to this package
13659                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13660                                }
13661                            }
13662                        }
13663                    }
13664                }
13665            } else {
13666                String msg = "Permission Denial: " + intent.getAction()
13667                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13668                        + ", uid=" + callingUid + ")"
13669                        + " requires "
13670                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13671                Slog.w(TAG, msg);
13672                throw new SecurityException(msg);
13673            }
13674
13675        // Special case for adding a package: by default turn on compatibility
13676        // mode.
13677        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13678            Uri data = intent.getData();
13679            String ssp;
13680            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13681                mCompatModePackages.handlePackageAddedLocked(ssp,
13682                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13683            }
13684        }
13685
13686        /*
13687         * If this is the time zone changed action, queue up a message that will reset the timezone
13688         * of all currently running processes. This message will get queued up before the broadcast
13689         * happens.
13690         */
13691        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13692            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13693        }
13694
13695        /*
13696         * If the user set the time, let all running processes know.
13697         */
13698        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13699            final int is24Hour = intent.getBooleanExtra(
13700                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13701            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13702        }
13703
13704        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13705            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13706        }
13707
13708        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13709            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13710            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13711        }
13712
13713        // Add to the sticky list if requested.
13714        if (sticky) {
13715            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13716                    callingPid, callingUid)
13717                    != PackageManager.PERMISSION_GRANTED) {
13718                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13719                        + callingPid + ", uid=" + callingUid
13720                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13721                Slog.w(TAG, msg);
13722                throw new SecurityException(msg);
13723            }
13724            if (requiredPermission != null) {
13725                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13726                        + " and enforce permission " + requiredPermission);
13727                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13728            }
13729            if (intent.getComponent() != null) {
13730                throw new SecurityException(
13731                        "Sticky broadcasts can't target a specific component");
13732            }
13733            // We use userId directly here, since the "all" target is maintained
13734            // as a separate set of sticky broadcasts.
13735            if (userId != UserHandle.USER_ALL) {
13736                // But first, if this is not a broadcast to all users, then
13737                // make sure it doesn't conflict with an existing broadcast to
13738                // all users.
13739                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13740                        UserHandle.USER_ALL);
13741                if (stickies != null) {
13742                    ArrayList<Intent> list = stickies.get(intent.getAction());
13743                    if (list != null) {
13744                        int N = list.size();
13745                        int i;
13746                        for (i=0; i<N; i++) {
13747                            if (intent.filterEquals(list.get(i))) {
13748                                throw new IllegalArgumentException(
13749                                        "Sticky broadcast " + intent + " for user "
13750                                        + userId + " conflicts with existing global broadcast");
13751                            }
13752                        }
13753                    }
13754                }
13755            }
13756            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13757            if (stickies == null) {
13758                stickies = new ArrayMap<String, ArrayList<Intent>>();
13759                mStickyBroadcasts.put(userId, stickies);
13760            }
13761            ArrayList<Intent> list = stickies.get(intent.getAction());
13762            if (list == null) {
13763                list = new ArrayList<Intent>();
13764                stickies.put(intent.getAction(), list);
13765            }
13766            int N = list.size();
13767            int i;
13768            for (i=0; i<N; i++) {
13769                if (intent.filterEquals(list.get(i))) {
13770                    // This sticky already exists, replace it.
13771                    list.set(i, new Intent(intent));
13772                    break;
13773                }
13774            }
13775            if (i >= N) {
13776                list.add(new Intent(intent));
13777            }
13778        }
13779
13780        int[] users;
13781        if (userId == UserHandle.USER_ALL) {
13782            // Caller wants broadcast to go to all started users.
13783            users = mStartedUserArray;
13784        } else {
13785            // Caller wants broadcast to go to one specific user.
13786            users = new int[] {userId};
13787        }
13788
13789        // Figure out who all will receive this broadcast.
13790        List receivers = null;
13791        List<BroadcastFilter> registeredReceivers = null;
13792        // Need to resolve the intent to interested receivers...
13793        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13794                 == 0) {
13795            receivers = collectReceiverComponents(intent, resolvedType, users);
13796        }
13797        if (intent.getComponent() == null) {
13798            registeredReceivers = mReceiverResolver.queryIntent(intent,
13799                    resolvedType, false, userId);
13800        }
13801
13802        final boolean replacePending =
13803                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13804
13805        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13806                + " replacePending=" + replacePending);
13807
13808        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13809        if (!ordered && NR > 0) {
13810            // If we are not serializing this broadcast, then send the
13811            // registered receivers separately so they don't wait for the
13812            // components to be launched.
13813            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13814            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13815                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13816                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13817                    ordered, sticky, false, userId);
13818            if (DEBUG_BROADCAST) Slog.v(
13819                    TAG, "Enqueueing parallel broadcast " + r);
13820            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13821            if (!replaced) {
13822                queue.enqueueParallelBroadcastLocked(r);
13823                queue.scheduleBroadcastsLocked();
13824            }
13825            registeredReceivers = null;
13826            NR = 0;
13827        }
13828
13829        // Merge into one list.
13830        int ir = 0;
13831        if (receivers != null) {
13832            // A special case for PACKAGE_ADDED: do not allow the package
13833            // being added to see this broadcast.  This prevents them from
13834            // using this as a back door to get run as soon as they are
13835            // installed.  Maybe in the future we want to have a special install
13836            // broadcast or such for apps, but we'd like to deliberately make
13837            // this decision.
13838            String skipPackages[] = null;
13839            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13840                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13841                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13842                Uri data = intent.getData();
13843                if (data != null) {
13844                    String pkgName = data.getSchemeSpecificPart();
13845                    if (pkgName != null) {
13846                        skipPackages = new String[] { pkgName };
13847                    }
13848                }
13849            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13850                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13851            }
13852            if (skipPackages != null && (skipPackages.length > 0)) {
13853                for (String skipPackage : skipPackages) {
13854                    if (skipPackage != null) {
13855                        int NT = receivers.size();
13856                        for (int it=0; it<NT; it++) {
13857                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13858                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13859                                receivers.remove(it);
13860                                it--;
13861                                NT--;
13862                            }
13863                        }
13864                    }
13865                }
13866            }
13867
13868            int NT = receivers != null ? receivers.size() : 0;
13869            int it = 0;
13870            ResolveInfo curt = null;
13871            BroadcastFilter curr = null;
13872            while (it < NT && ir < NR) {
13873                if (curt == null) {
13874                    curt = (ResolveInfo)receivers.get(it);
13875                }
13876                if (curr == null) {
13877                    curr = registeredReceivers.get(ir);
13878                }
13879                if (curr.getPriority() >= curt.priority) {
13880                    // Insert this broadcast record into the final list.
13881                    receivers.add(it, curr);
13882                    ir++;
13883                    curr = null;
13884                    it++;
13885                    NT++;
13886                } else {
13887                    // Skip to the next ResolveInfo in the final list.
13888                    it++;
13889                    curt = null;
13890                }
13891            }
13892        }
13893        while (ir < NR) {
13894            if (receivers == null) {
13895                receivers = new ArrayList();
13896            }
13897            receivers.add(registeredReceivers.get(ir));
13898            ir++;
13899        }
13900
13901        if ((receivers != null && receivers.size() > 0)
13902                || resultTo != null) {
13903            BroadcastQueue queue = broadcastQueueForIntent(intent);
13904            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13905                    callerPackage, callingPid, callingUid, resolvedType,
13906                    requiredPermission, appOp, receivers, resultTo, resultCode,
13907                    resultData, map, ordered, sticky, false, userId);
13908            if (DEBUG_BROADCAST) Slog.v(
13909                    TAG, "Enqueueing ordered broadcast " + r
13910                    + ": prev had " + queue.mOrderedBroadcasts.size());
13911            if (DEBUG_BROADCAST) {
13912                int seq = r.intent.getIntExtra("seq", -1);
13913                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13914            }
13915            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13916            if (!replaced) {
13917                queue.enqueueOrderedBroadcastLocked(r);
13918                queue.scheduleBroadcastsLocked();
13919            }
13920        }
13921
13922        return ActivityManager.BROADCAST_SUCCESS;
13923    }
13924
13925    final Intent verifyBroadcastLocked(Intent intent) {
13926        // Refuse possible leaked file descriptors
13927        if (intent != null && intent.hasFileDescriptors() == true) {
13928            throw new IllegalArgumentException("File descriptors passed in Intent");
13929        }
13930
13931        int flags = intent.getFlags();
13932
13933        if (!mProcessesReady) {
13934            // if the caller really truly claims to know what they're doing, go
13935            // ahead and allow the broadcast without launching any receivers
13936            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13937                intent = new Intent(intent);
13938                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13939            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13940                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13941                        + " before boot completion");
13942                throw new IllegalStateException("Cannot broadcast before boot completed");
13943            }
13944        }
13945
13946        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13947            throw new IllegalArgumentException(
13948                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13949        }
13950
13951        return intent;
13952    }
13953
13954    public final int broadcastIntent(IApplicationThread caller,
13955            Intent intent, String resolvedType, IIntentReceiver resultTo,
13956            int resultCode, String resultData, Bundle map,
13957            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13958        enforceNotIsolatedCaller("broadcastIntent");
13959        synchronized(this) {
13960            intent = verifyBroadcastLocked(intent);
13961
13962            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13963            final int callingPid = Binder.getCallingPid();
13964            final int callingUid = Binder.getCallingUid();
13965            final long origId = Binder.clearCallingIdentity();
13966            int res = broadcastIntentLocked(callerApp,
13967                    callerApp != null ? callerApp.info.packageName : null,
13968                    intent, resolvedType, resultTo,
13969                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13970                    callingPid, callingUid, userId);
13971            Binder.restoreCallingIdentity(origId);
13972            return res;
13973        }
13974    }
13975
13976    int broadcastIntentInPackage(String packageName, int uid,
13977            Intent intent, String resolvedType, IIntentReceiver resultTo,
13978            int resultCode, String resultData, Bundle map,
13979            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13980        synchronized(this) {
13981            intent = verifyBroadcastLocked(intent);
13982
13983            final long origId = Binder.clearCallingIdentity();
13984            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13985                    resultTo, resultCode, resultData, map, requiredPermission,
13986                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13987            Binder.restoreCallingIdentity(origId);
13988            return res;
13989        }
13990    }
13991
13992    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13993        // Refuse possible leaked file descriptors
13994        if (intent != null && intent.hasFileDescriptors() == true) {
13995            throw new IllegalArgumentException("File descriptors passed in Intent");
13996        }
13997
13998        userId = handleIncomingUser(Binder.getCallingPid(),
13999                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14000
14001        synchronized(this) {
14002            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14003                    != PackageManager.PERMISSION_GRANTED) {
14004                String msg = "Permission Denial: unbroadcastIntent() from pid="
14005                        + Binder.getCallingPid()
14006                        + ", uid=" + Binder.getCallingUid()
14007                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14008                Slog.w(TAG, msg);
14009                throw new SecurityException(msg);
14010            }
14011            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14012            if (stickies != null) {
14013                ArrayList<Intent> list = stickies.get(intent.getAction());
14014                if (list != null) {
14015                    int N = list.size();
14016                    int i;
14017                    for (i=0; i<N; i++) {
14018                        if (intent.filterEquals(list.get(i))) {
14019                            list.remove(i);
14020                            break;
14021                        }
14022                    }
14023                    if (list.size() <= 0) {
14024                        stickies.remove(intent.getAction());
14025                    }
14026                }
14027                if (stickies.size() <= 0) {
14028                    mStickyBroadcasts.remove(userId);
14029                }
14030            }
14031        }
14032    }
14033
14034    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14035            String resultData, Bundle resultExtras, boolean resultAbort) {
14036        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14037        if (r == null) {
14038            Slog.w(TAG, "finishReceiver called but not found on queue");
14039            return false;
14040        }
14041
14042        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14043    }
14044
14045    void backgroundServicesFinishedLocked(int userId) {
14046        for (BroadcastQueue queue : mBroadcastQueues) {
14047            queue.backgroundServicesFinishedLocked(userId);
14048        }
14049    }
14050
14051    public void finishReceiver(IBinder who, int resultCode, String resultData,
14052            Bundle resultExtras, boolean resultAbort) {
14053        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14054
14055        // Refuse possible leaked file descriptors
14056        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14057            throw new IllegalArgumentException("File descriptors passed in Bundle");
14058        }
14059
14060        final long origId = Binder.clearCallingIdentity();
14061        try {
14062            boolean doNext = false;
14063            BroadcastRecord r;
14064
14065            synchronized(this) {
14066                r = broadcastRecordForReceiverLocked(who);
14067                if (r != null) {
14068                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14069                        resultData, resultExtras, resultAbort, true);
14070                }
14071            }
14072
14073            if (doNext) {
14074                r.queue.processNextBroadcast(false);
14075            }
14076            trimApplications();
14077        } finally {
14078            Binder.restoreCallingIdentity(origId);
14079        }
14080    }
14081
14082    // =========================================================
14083    // INSTRUMENTATION
14084    // =========================================================
14085
14086    public boolean startInstrumentation(ComponentName className,
14087            String profileFile, int flags, Bundle arguments,
14088            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14089            int userId) {
14090        enforceNotIsolatedCaller("startInstrumentation");
14091        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14092                userId, false, true, "startInstrumentation", null);
14093        // Refuse possible leaked file descriptors
14094        if (arguments != null && arguments.hasFileDescriptors()) {
14095            throw new IllegalArgumentException("File descriptors passed in Bundle");
14096        }
14097
14098        synchronized(this) {
14099            InstrumentationInfo ii = null;
14100            ApplicationInfo ai = null;
14101            try {
14102                ii = mContext.getPackageManager().getInstrumentationInfo(
14103                    className, STOCK_PM_FLAGS);
14104                ai = AppGlobals.getPackageManager().getApplicationInfo(
14105                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14106            } catch (PackageManager.NameNotFoundException e) {
14107            } catch (RemoteException e) {
14108            }
14109            if (ii == null) {
14110                reportStartInstrumentationFailure(watcher, className,
14111                        "Unable to find instrumentation info for: " + className);
14112                return false;
14113            }
14114            if (ai == null) {
14115                reportStartInstrumentationFailure(watcher, className,
14116                        "Unable to find instrumentation target package: " + ii.targetPackage);
14117                return false;
14118            }
14119
14120            int match = mContext.getPackageManager().checkSignatures(
14121                    ii.targetPackage, ii.packageName);
14122            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14123                String msg = "Permission Denial: starting instrumentation "
14124                        + className + " from pid="
14125                        + Binder.getCallingPid()
14126                        + ", uid=" + Binder.getCallingPid()
14127                        + " not allowed because package " + ii.packageName
14128                        + " does not have a signature matching the target "
14129                        + ii.targetPackage;
14130                reportStartInstrumentationFailure(watcher, className, msg);
14131                throw new SecurityException(msg);
14132            }
14133
14134            final long origId = Binder.clearCallingIdentity();
14135            // Instrumentation can kill and relaunch even persistent processes
14136            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14137                    "start instr");
14138            ProcessRecord app = addAppLocked(ai, false);
14139            app.instrumentationClass = className;
14140            app.instrumentationInfo = ai;
14141            app.instrumentationProfileFile = profileFile;
14142            app.instrumentationArguments = arguments;
14143            app.instrumentationWatcher = watcher;
14144            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14145            app.instrumentationResultClass = className;
14146            Binder.restoreCallingIdentity(origId);
14147        }
14148
14149        return true;
14150    }
14151
14152    /**
14153     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14154     * error to the logs, but if somebody is watching, send the report there too.  This enables
14155     * the "am" command to report errors with more information.
14156     *
14157     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14158     * @param cn The component name of the instrumentation.
14159     * @param report The error report.
14160     */
14161    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14162            ComponentName cn, String report) {
14163        Slog.w(TAG, report);
14164        try {
14165            if (watcher != null) {
14166                Bundle results = new Bundle();
14167                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14168                results.putString("Error", report);
14169                watcher.instrumentationStatus(cn, -1, results);
14170            }
14171        } catch (RemoteException e) {
14172            Slog.w(TAG, e);
14173        }
14174    }
14175
14176    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14177        if (app.instrumentationWatcher != null) {
14178            try {
14179                // NOTE:  IInstrumentationWatcher *must* be oneway here
14180                app.instrumentationWatcher.instrumentationFinished(
14181                    app.instrumentationClass,
14182                    resultCode,
14183                    results);
14184            } catch (RemoteException e) {
14185            }
14186        }
14187        if (app.instrumentationUiAutomationConnection != null) {
14188            try {
14189                app.instrumentationUiAutomationConnection.shutdown();
14190            } catch (RemoteException re) {
14191                /* ignore */
14192            }
14193            // Only a UiAutomation can set this flag and now that
14194            // it is finished we make sure it is reset to its default.
14195            mUserIsMonkey = false;
14196        }
14197        app.instrumentationWatcher = null;
14198        app.instrumentationUiAutomationConnection = null;
14199        app.instrumentationClass = null;
14200        app.instrumentationInfo = null;
14201        app.instrumentationProfileFile = null;
14202        app.instrumentationArguments = null;
14203
14204        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14205                "finished inst");
14206    }
14207
14208    public void finishInstrumentation(IApplicationThread target,
14209            int resultCode, Bundle results) {
14210        int userId = UserHandle.getCallingUserId();
14211        // Refuse possible leaked file descriptors
14212        if (results != null && results.hasFileDescriptors()) {
14213            throw new IllegalArgumentException("File descriptors passed in Intent");
14214        }
14215
14216        synchronized(this) {
14217            ProcessRecord app = getRecordForAppLocked(target);
14218            if (app == null) {
14219                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14220                return;
14221            }
14222            final long origId = Binder.clearCallingIdentity();
14223            finishInstrumentationLocked(app, resultCode, results);
14224            Binder.restoreCallingIdentity(origId);
14225        }
14226    }
14227
14228    // =========================================================
14229    // CONFIGURATION
14230    // =========================================================
14231
14232    public ConfigurationInfo getDeviceConfigurationInfo() {
14233        ConfigurationInfo config = new ConfigurationInfo();
14234        synchronized (this) {
14235            config.reqTouchScreen = mConfiguration.touchscreen;
14236            config.reqKeyboardType = mConfiguration.keyboard;
14237            config.reqNavigation = mConfiguration.navigation;
14238            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14239                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14240                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14241            }
14242            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14243                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14244                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14245            }
14246            config.reqGlEsVersion = GL_ES_VERSION;
14247        }
14248        return config;
14249    }
14250
14251    ActivityStack getFocusedStack() {
14252        return mStackSupervisor.getFocusedStack();
14253    }
14254
14255    public Configuration getConfiguration() {
14256        Configuration ci;
14257        synchronized(this) {
14258            ci = new Configuration(mConfiguration);
14259        }
14260        return ci;
14261    }
14262
14263    public void updatePersistentConfiguration(Configuration values) {
14264        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14265                "updateConfiguration()");
14266        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14267                "updateConfiguration()");
14268        if (values == null) {
14269            throw new NullPointerException("Configuration must not be null");
14270        }
14271
14272        synchronized(this) {
14273            final long origId = Binder.clearCallingIdentity();
14274            updateConfigurationLocked(values, null, true, false);
14275            Binder.restoreCallingIdentity(origId);
14276        }
14277    }
14278
14279    public void updateConfiguration(Configuration values) {
14280        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14281                "updateConfiguration()");
14282
14283        synchronized(this) {
14284            if (values == null && mWindowManager != null) {
14285                // sentinel: fetch the current configuration from the window manager
14286                values = mWindowManager.computeNewConfiguration();
14287            }
14288
14289            if (mWindowManager != null) {
14290                mProcessList.applyDisplaySize(mWindowManager);
14291            }
14292
14293            final long origId = Binder.clearCallingIdentity();
14294            if (values != null) {
14295                Settings.System.clearConfiguration(values);
14296            }
14297            updateConfigurationLocked(values, null, false, false);
14298            Binder.restoreCallingIdentity(origId);
14299        }
14300    }
14301
14302    /**
14303     * Do either or both things: (1) change the current configuration, and (2)
14304     * make sure the given activity is running with the (now) current
14305     * configuration.  Returns true if the activity has been left running, or
14306     * false if <var>starting</var> is being destroyed to match the new
14307     * configuration.
14308     * @param persistent TODO
14309     */
14310    boolean updateConfigurationLocked(Configuration values,
14311            ActivityRecord starting, boolean persistent, boolean initLocale) {
14312        int changes = 0;
14313
14314        if (values != null) {
14315            Configuration newConfig = new Configuration(mConfiguration);
14316            changes = newConfig.updateFrom(values);
14317            if (changes != 0) {
14318                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14319                    Slog.i(TAG, "Updating configuration to: " + values);
14320                }
14321
14322                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14323
14324                if (values.locale != null && !initLocale) {
14325                    saveLocaleLocked(values.locale,
14326                                     !values.locale.equals(mConfiguration.locale),
14327                                     values.userSetLocale);
14328                }
14329
14330                mConfigurationSeq++;
14331                if (mConfigurationSeq <= 0) {
14332                    mConfigurationSeq = 1;
14333                }
14334                newConfig.seq = mConfigurationSeq;
14335                mConfiguration = newConfig;
14336                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14337
14338                final Configuration configCopy = new Configuration(mConfiguration);
14339
14340                // TODO: If our config changes, should we auto dismiss any currently
14341                // showing dialogs?
14342                mShowDialogs = shouldShowDialogs(newConfig);
14343
14344                AttributeCache ac = AttributeCache.instance();
14345                if (ac != null) {
14346                    ac.updateConfiguration(configCopy);
14347                }
14348
14349                // Make sure all resources in our process are updated
14350                // right now, so that anyone who is going to retrieve
14351                // resource values after we return will be sure to get
14352                // the new ones.  This is especially important during
14353                // boot, where the first config change needs to guarantee
14354                // all resources have that config before following boot
14355                // code is executed.
14356                mSystemThread.applyConfigurationToResources(configCopy);
14357
14358                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14359                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14360                    msg.obj = new Configuration(configCopy);
14361                    mHandler.sendMessage(msg);
14362                }
14363
14364                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14365                    ProcessRecord app = mLruProcesses.get(i);
14366                    try {
14367                        if (app.thread != null) {
14368                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14369                                    + app.processName + " new config " + mConfiguration);
14370                            app.thread.scheduleConfigurationChanged(configCopy);
14371                        }
14372                    } catch (Exception e) {
14373                    }
14374                }
14375                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14376                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14377                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14378                        | Intent.FLAG_RECEIVER_FOREGROUND);
14379                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14380                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14381                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14382                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14383                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14384                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14385                    broadcastIntentLocked(null, null, intent,
14386                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14387                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14388                }
14389            }
14390        }
14391
14392        boolean kept = true;
14393        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14394        // mainStack is null during startup.
14395        if (mainStack != null) {
14396            if (changes != 0 && starting == null) {
14397                // If the configuration changed, and the caller is not already
14398                // in the process of starting an activity, then find the top
14399                // activity to check if its configuration needs to change.
14400                starting = mainStack.topRunningActivityLocked(null);
14401            }
14402
14403            if (starting != null) {
14404                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14405                // And we need to make sure at this point that all other activities
14406                // are made visible with the correct configuration.
14407                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14408            }
14409        }
14410
14411        if (values != null && mWindowManager != null) {
14412            mWindowManager.setNewConfiguration(mConfiguration);
14413        }
14414
14415        return kept;
14416    }
14417
14418    /**
14419     * Decide based on the configuration whether we should shouw the ANR,
14420     * crash, etc dialogs.  The idea is that if there is no affordnace to
14421     * press the on-screen buttons, we shouldn't show the dialog.
14422     *
14423     * A thought: SystemUI might also want to get told about this, the Power
14424     * dialog / global actions also might want different behaviors.
14425     */
14426    private static final boolean shouldShowDialogs(Configuration config) {
14427        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14428                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14429    }
14430
14431    /**
14432     * Save the locale.  You must be inside a synchronized (this) block.
14433     */
14434    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14435        if(isDiff) {
14436            SystemProperties.set("user.language", l.getLanguage());
14437            SystemProperties.set("user.region", l.getCountry());
14438        }
14439
14440        if(isPersist) {
14441            SystemProperties.set("persist.sys.language", l.getLanguage());
14442            SystemProperties.set("persist.sys.country", l.getCountry());
14443            SystemProperties.set("persist.sys.localevar", l.getVariant());
14444        }
14445    }
14446
14447    @Override
14448    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14449        ActivityRecord srec = ActivityRecord.forToken(token);
14450        return srec != null && srec.task.affinity != null &&
14451                srec.task.affinity.equals(destAffinity);
14452    }
14453
14454    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14455            Intent resultData) {
14456
14457        synchronized (this) {
14458            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14459            if (stack != null) {
14460                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14461            }
14462            return false;
14463        }
14464    }
14465
14466    public int getLaunchedFromUid(IBinder activityToken) {
14467        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14468        if (srec == null) {
14469            return -1;
14470        }
14471        return srec.launchedFromUid;
14472    }
14473
14474    public String getLaunchedFromPackage(IBinder activityToken) {
14475        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14476        if (srec == null) {
14477            return null;
14478        }
14479        return srec.launchedFromPackage;
14480    }
14481
14482    // =========================================================
14483    // LIFETIME MANAGEMENT
14484    // =========================================================
14485
14486    // Returns which broadcast queue the app is the current [or imminent] receiver
14487    // on, or 'null' if the app is not an active broadcast recipient.
14488    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14489        BroadcastRecord r = app.curReceiver;
14490        if (r != null) {
14491            return r.queue;
14492        }
14493
14494        // It's not the current receiver, but it might be starting up to become one
14495        synchronized (this) {
14496            for (BroadcastQueue queue : mBroadcastQueues) {
14497                r = queue.mPendingBroadcast;
14498                if (r != null && r.curApp == app) {
14499                    // found it; report which queue it's in
14500                    return queue;
14501                }
14502            }
14503        }
14504
14505        return null;
14506    }
14507
14508    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14509            boolean doingAll, long now) {
14510        if (mAdjSeq == app.adjSeq) {
14511            // This adjustment has already been computed.
14512            return app.curRawAdj;
14513        }
14514
14515        if (app.thread == null) {
14516            app.adjSeq = mAdjSeq;
14517            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14518            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14519            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14520        }
14521
14522        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14523        app.adjSource = null;
14524        app.adjTarget = null;
14525        app.empty = false;
14526        app.cached = false;
14527
14528        final int activitiesSize = app.activities.size();
14529
14530        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14531            // The max adjustment doesn't allow this app to be anything
14532            // below foreground, so it is not worth doing work for it.
14533            app.adjType = "fixed";
14534            app.adjSeq = mAdjSeq;
14535            app.curRawAdj = app.maxAdj;
14536            app.foregroundActivities = false;
14537            app.keeping = true;
14538            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14539            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14540            // System process can do UI, and when they do we want to have
14541            // them trim their memory after the user leaves the UI.  To
14542            // facilitate this, here we need to determine whether or not it
14543            // is currently showing UI.
14544            app.systemNoUi = true;
14545            if (app == TOP_APP) {
14546                app.systemNoUi = false;
14547            } else if (activitiesSize > 0) {
14548                for (int j = 0; j < activitiesSize; j++) {
14549                    final ActivityRecord r = app.activities.get(j);
14550                    if (r.visible) {
14551                        app.systemNoUi = false;
14552                    }
14553                }
14554            }
14555            if (!app.systemNoUi) {
14556                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14557            }
14558            return (app.curAdj=app.maxAdj);
14559        }
14560
14561        app.keeping = false;
14562        app.systemNoUi = false;
14563
14564        // Determine the importance of the process, starting with most
14565        // important to least, and assign an appropriate OOM adjustment.
14566        int adj;
14567        int schedGroup;
14568        int procState;
14569        boolean foregroundActivities = false;
14570        boolean interesting = false;
14571        BroadcastQueue queue;
14572        if (app == TOP_APP) {
14573            // The last app on the list is the foreground app.
14574            adj = ProcessList.FOREGROUND_APP_ADJ;
14575            schedGroup = Process.THREAD_GROUP_DEFAULT;
14576            app.adjType = "top-activity";
14577            foregroundActivities = true;
14578            interesting = true;
14579            procState = ActivityManager.PROCESS_STATE_TOP;
14580        } else if (app.instrumentationClass != null) {
14581            // Don't want to kill running instrumentation.
14582            adj = ProcessList.FOREGROUND_APP_ADJ;
14583            schedGroup = Process.THREAD_GROUP_DEFAULT;
14584            app.adjType = "instrumentation";
14585            interesting = true;
14586            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14587        } else if ((queue = isReceivingBroadcast(app)) != null) {
14588            // An app that is currently receiving a broadcast also
14589            // counts as being in the foreground for OOM killer purposes.
14590            // It's placed in a sched group based on the nature of the
14591            // broadcast as reflected by which queue it's active in.
14592            adj = ProcessList.FOREGROUND_APP_ADJ;
14593            schedGroup = (queue == mFgBroadcastQueue)
14594                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14595            app.adjType = "broadcast";
14596            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14597        } else if (app.executingServices.size() > 0) {
14598            // An app that is currently executing a service callback also
14599            // counts as being in the foreground.
14600            adj = ProcessList.FOREGROUND_APP_ADJ;
14601            schedGroup = app.execServicesFg ?
14602                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14603            app.adjType = "exec-service";
14604            procState = ActivityManager.PROCESS_STATE_SERVICE;
14605            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14606        } else {
14607            // As far as we know the process is empty.  We may change our mind later.
14608            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14609            // At this point we don't actually know the adjustment.  Use the cached adj
14610            // value that the caller wants us to.
14611            adj = cachedAdj;
14612            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14613            app.cached = true;
14614            app.empty = true;
14615            app.adjType = "cch-empty";
14616        }
14617
14618        // Examine all activities if not already foreground.
14619        if (!foregroundActivities && activitiesSize > 0) {
14620            for (int j = 0; j < activitiesSize; j++) {
14621                final ActivityRecord r = app.activities.get(j);
14622                if (r.app != app) {
14623                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14624                            + app + "?!?");
14625                    continue;
14626                }
14627                if (r.visible) {
14628                    // App has a visible activity; only upgrade adjustment.
14629                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14630                        adj = ProcessList.VISIBLE_APP_ADJ;
14631                        app.adjType = "visible";
14632                    }
14633                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14634                        procState = ActivityManager.PROCESS_STATE_TOP;
14635                    }
14636                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14637                    app.cached = false;
14638                    app.empty = false;
14639                    foregroundActivities = true;
14640                    break;
14641                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14642                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14643                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14644                        app.adjType = "pausing";
14645                    }
14646                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14647                        procState = ActivityManager.PROCESS_STATE_TOP;
14648                    }
14649                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14650                    app.cached = false;
14651                    app.empty = false;
14652                    foregroundActivities = true;
14653                } else if (r.state == ActivityState.STOPPING) {
14654                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14655                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14656                        app.adjType = "stopping";
14657                    }
14658                    // For the process state, we will at this point consider the
14659                    // process to be cached.  It will be cached either as an activity
14660                    // or empty depending on whether the activity is finishing.  We do
14661                    // this so that we can treat the process as cached for purposes of
14662                    // memory trimming (determing current memory level, trim command to
14663                    // send to process) since there can be an arbitrary number of stopping
14664                    // processes and they should soon all go into the cached state.
14665                    if (!r.finishing) {
14666                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14667                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14668                        }
14669                    }
14670                    app.cached = false;
14671                    app.empty = false;
14672                    foregroundActivities = true;
14673                } else {
14674                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14675                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14676                        app.adjType = "cch-act";
14677                    }
14678                }
14679            }
14680        }
14681
14682        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14683            if (app.foregroundServices) {
14684                // The user is aware of this app, so make it visible.
14685                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14686                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14687                app.cached = false;
14688                app.adjType = "fg-service";
14689                schedGroup = Process.THREAD_GROUP_DEFAULT;
14690            } else if (app.forcingToForeground != null) {
14691                // The user is aware of this app, so make it visible.
14692                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14693                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14694                app.cached = false;
14695                app.adjType = "force-fg";
14696                app.adjSource = app.forcingToForeground;
14697                schedGroup = Process.THREAD_GROUP_DEFAULT;
14698            }
14699        }
14700
14701        if (app.foregroundServices) {
14702            interesting = true;
14703        }
14704
14705        if (app == mHeavyWeightProcess) {
14706            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14707                // We don't want to kill the current heavy-weight process.
14708                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14709                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14710                app.cached = false;
14711                app.adjType = "heavy";
14712            }
14713            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14714                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14715            }
14716        }
14717
14718        if (app == mHomeProcess) {
14719            if (adj > ProcessList.HOME_APP_ADJ) {
14720                // This process is hosting what we currently consider to be the
14721                // home app, so we don't want to let it go into the background.
14722                adj = ProcessList.HOME_APP_ADJ;
14723                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14724                app.cached = false;
14725                app.adjType = "home";
14726            }
14727            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14728                procState = ActivityManager.PROCESS_STATE_HOME;
14729            }
14730        }
14731
14732        if (app == mPreviousProcess && app.activities.size() > 0) {
14733            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14734                // This was the previous process that showed UI to the user.
14735                // We want to try to keep it around more aggressively, to give
14736                // a good experience around switching between two apps.
14737                adj = ProcessList.PREVIOUS_APP_ADJ;
14738                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14739                app.cached = false;
14740                app.adjType = "previous";
14741            }
14742            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14743                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14744            }
14745        }
14746
14747        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14748                + " reason=" + app.adjType);
14749
14750        // By default, we use the computed adjustment.  It may be changed if
14751        // there are applications dependent on our services or providers, but
14752        // this gives us a baseline and makes sure we don't get into an
14753        // infinite recursion.
14754        app.adjSeq = mAdjSeq;
14755        app.curRawAdj = adj;
14756        app.hasStartedServices = false;
14757
14758        if (mBackupTarget != null && app == mBackupTarget.app) {
14759            // If possible we want to avoid killing apps while they're being backed up
14760            if (adj > ProcessList.BACKUP_APP_ADJ) {
14761                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14762                adj = ProcessList.BACKUP_APP_ADJ;
14763                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14764                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14765                }
14766                app.adjType = "backup";
14767                app.cached = false;
14768            }
14769            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14770                procState = ActivityManager.PROCESS_STATE_BACKUP;
14771            }
14772        }
14773
14774        boolean mayBeTop = false;
14775
14776        for (int is = app.services.size()-1;
14777                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14778                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14779                        || procState > ActivityManager.PROCESS_STATE_TOP);
14780                is--) {
14781            ServiceRecord s = app.services.valueAt(is);
14782            if (s.startRequested) {
14783                app.hasStartedServices = true;
14784                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14785                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14786                }
14787                if (app.hasShownUi && app != mHomeProcess) {
14788                    // If this process has shown some UI, let it immediately
14789                    // go to the LRU list because it may be pretty heavy with
14790                    // UI stuff.  We'll tag it with a label just to help
14791                    // debug and understand what is going on.
14792                    if (adj > ProcessList.SERVICE_ADJ) {
14793                        app.adjType = "cch-started-ui-services";
14794                    }
14795                } else {
14796                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14797                        // This service has seen some activity within
14798                        // recent memory, so we will keep its process ahead
14799                        // of the background processes.
14800                        if (adj > ProcessList.SERVICE_ADJ) {
14801                            adj = ProcessList.SERVICE_ADJ;
14802                            app.adjType = "started-services";
14803                            app.cached = false;
14804                        }
14805                    }
14806                    // If we have let the service slide into the background
14807                    // state, still have some text describing what it is doing
14808                    // even though the service no longer has an impact.
14809                    if (adj > ProcessList.SERVICE_ADJ) {
14810                        app.adjType = "cch-started-services";
14811                    }
14812                }
14813                // Don't kill this process because it is doing work; it
14814                // has said it is doing work.
14815                app.keeping = true;
14816            }
14817            for (int conni = s.connections.size()-1;
14818                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14819                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14820                            || procState > ActivityManager.PROCESS_STATE_TOP);
14821                    conni--) {
14822                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14823                for (int i = 0;
14824                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14825                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14826                                || procState > ActivityManager.PROCESS_STATE_TOP);
14827                        i++) {
14828                    // XXX should compute this based on the max of
14829                    // all connected clients.
14830                    ConnectionRecord cr = clist.get(i);
14831                    if (cr.binding.client == app) {
14832                        // Binding to ourself is not interesting.
14833                        continue;
14834                    }
14835                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14836                        ProcessRecord client = cr.binding.client;
14837                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14838                                TOP_APP, doingAll, now);
14839                        int clientProcState = client.curProcState;
14840                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14841                            // If the other app is cached for any reason, for purposes here
14842                            // we are going to consider it empty.  The specific cached state
14843                            // doesn't propagate except under certain conditions.
14844                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14845                        }
14846                        String adjType = null;
14847                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14848                            // Not doing bind OOM management, so treat
14849                            // this guy more like a started service.
14850                            if (app.hasShownUi && app != mHomeProcess) {
14851                                // If this process has shown some UI, let it immediately
14852                                // go to the LRU list because it may be pretty heavy with
14853                                // UI stuff.  We'll tag it with a label just to help
14854                                // debug and understand what is going on.
14855                                if (adj > clientAdj) {
14856                                    adjType = "cch-bound-ui-services";
14857                                }
14858                                app.cached = false;
14859                                clientAdj = adj;
14860                                clientProcState = procState;
14861                            } else {
14862                                if (now >= (s.lastActivity
14863                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14864                                    // This service has not seen activity within
14865                                    // recent memory, so allow it to drop to the
14866                                    // LRU list if there is no other reason to keep
14867                                    // it around.  We'll also tag it with a label just
14868                                    // to help debug and undertand what is going on.
14869                                    if (adj > clientAdj) {
14870                                        adjType = "cch-bound-services";
14871                                    }
14872                                    clientAdj = adj;
14873                                }
14874                            }
14875                        }
14876                        if (adj > clientAdj) {
14877                            // If this process has recently shown UI, and
14878                            // the process that is binding to it is less
14879                            // important than being visible, then we don't
14880                            // care about the binding as much as we care
14881                            // about letting this process get into the LRU
14882                            // list to be killed and restarted if needed for
14883                            // memory.
14884                            if (app.hasShownUi && app != mHomeProcess
14885                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14886                                adjType = "cch-bound-ui-services";
14887                            } else {
14888                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14889                                        |Context.BIND_IMPORTANT)) != 0) {
14890                                    adj = clientAdj;
14891                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14892                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14893                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14894                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14895                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14896                                    adj = clientAdj;
14897                                } else {
14898                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14899                                        adj = ProcessList.VISIBLE_APP_ADJ;
14900                                    }
14901                                }
14902                                if (!client.cached) {
14903                                    app.cached = false;
14904                                }
14905                                if (client.keeping) {
14906                                    app.keeping = true;
14907                                }
14908                                adjType = "service";
14909                            }
14910                        }
14911                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14912                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14913                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14914                            }
14915                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14916                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14917                                    // Special handling of clients who are in the top state.
14918                                    // We *may* want to consider this process to be in the
14919                                    // top state as well, but only if there is not another
14920                                    // reason for it to be running.  Being on the top is a
14921                                    // special state, meaning you are specifically running
14922                                    // for the current top app.  If the process is already
14923                                    // running in the background for some other reason, it
14924                                    // is more important to continue considering it to be
14925                                    // in the background state.
14926                                    mayBeTop = true;
14927                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14928                                } else {
14929                                    // Special handling for above-top states (persistent
14930                                    // processes).  These should not bring the current process
14931                                    // into the top state, since they are not on top.  Instead
14932                                    // give them the best state after that.
14933                                    clientProcState =
14934                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14935                                }
14936                            }
14937                        } else {
14938                            if (clientProcState <
14939                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14940                                clientProcState =
14941                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14942                            }
14943                        }
14944                        if (procState > clientProcState) {
14945                            procState = clientProcState;
14946                        }
14947                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14948                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14949                            app.pendingUiClean = true;
14950                        }
14951                        if (adjType != null) {
14952                            app.adjType = adjType;
14953                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14954                                    .REASON_SERVICE_IN_USE;
14955                            app.adjSource = cr.binding.client;
14956                            app.adjSourceOom = clientAdj;
14957                            app.adjTarget = s.name;
14958                        }
14959                    }
14960                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
14961                        app.treatLikeActivity = true;
14962                    }
14963                    final ActivityRecord a = cr.activity;
14964                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14965                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14966                                (a.visible || a.state == ActivityState.RESUMED
14967                                 || a.state == ActivityState.PAUSING)) {
14968                            adj = ProcessList.FOREGROUND_APP_ADJ;
14969                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14970                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14971                            }
14972                            app.cached = false;
14973                            app.adjType = "service";
14974                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14975                                    .REASON_SERVICE_IN_USE;
14976                            app.adjSource = a;
14977                            app.adjSourceOom = adj;
14978                            app.adjTarget = s.name;
14979                        }
14980                    }
14981                }
14982            }
14983        }
14984
14985        for (int provi = app.pubProviders.size()-1;
14986                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14987                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14988                        || procState > ActivityManager.PROCESS_STATE_TOP);
14989                provi--) {
14990            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14991            for (int i = cpr.connections.size()-1;
14992                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14993                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14994                            || procState > ActivityManager.PROCESS_STATE_TOP);
14995                    i--) {
14996                ContentProviderConnection conn = cpr.connections.get(i);
14997                ProcessRecord client = conn.client;
14998                if (client == app) {
14999                    // Being our own client is not interesting.
15000                    continue;
15001                }
15002                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15003                int clientProcState = client.curProcState;
15004                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15005                    // If the other app is cached for any reason, for purposes here
15006                    // we are going to consider it empty.
15007                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15008                }
15009                if (adj > clientAdj) {
15010                    if (app.hasShownUi && app != mHomeProcess
15011                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15012                        app.adjType = "cch-ui-provider";
15013                    } else {
15014                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15015                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15016                        app.adjType = "provider";
15017                    }
15018                    app.cached &= client.cached;
15019                    app.keeping |= client.keeping;
15020                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15021                            .REASON_PROVIDER_IN_USE;
15022                    app.adjSource = client;
15023                    app.adjSourceOom = clientAdj;
15024                    app.adjTarget = cpr.name;
15025                }
15026                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15027                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15028                        // Special handling of clients who are in the top state.
15029                        // We *may* want to consider this process to be in the
15030                        // top state as well, but only if there is not another
15031                        // reason for it to be running.  Being on the top is a
15032                        // special state, meaning you are specifically running
15033                        // for the current top app.  If the process is already
15034                        // running in the background for some other reason, it
15035                        // is more important to continue considering it to be
15036                        // in the background state.
15037                        mayBeTop = true;
15038                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15039                    } else {
15040                        // Special handling for above-top states (persistent
15041                        // processes).  These should not bring the current process
15042                        // into the top state, since they are not on top.  Instead
15043                        // give them the best state after that.
15044                        clientProcState =
15045                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15046                    }
15047                }
15048                if (procState > clientProcState) {
15049                    procState = clientProcState;
15050                }
15051                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15052                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15053                }
15054            }
15055            // If the provider has external (non-framework) process
15056            // dependencies, ensure that its adjustment is at least
15057            // FOREGROUND_APP_ADJ.
15058            if (cpr.hasExternalProcessHandles()) {
15059                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15060                    adj = ProcessList.FOREGROUND_APP_ADJ;
15061                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15062                    app.cached = false;
15063                    app.keeping = true;
15064                    app.adjType = "provider";
15065                    app.adjTarget = cpr.name;
15066                }
15067                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15068                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15069                }
15070            }
15071        }
15072
15073        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15074            // A client of one of our services or providers is in the top state.  We
15075            // *may* want to be in the top state, but not if we are already running in
15076            // the background for some other reason.  For the decision here, we are going
15077            // to pick out a few specific states that we want to remain in when a client
15078            // is top (states that tend to be longer-term) and otherwise allow it to go
15079            // to the top state.
15080            switch (procState) {
15081                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15082                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15083                case ActivityManager.PROCESS_STATE_SERVICE:
15084                    // These all are longer-term states, so pull them up to the top
15085                    // of the background states, but not all the way to the top state.
15086                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15087                    break;
15088                default:
15089                    // Otherwise, top is a better choice, so take it.
15090                    procState = ActivityManager.PROCESS_STATE_TOP;
15091                    break;
15092            }
15093        }
15094
15095        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15096            if (app.hasClientActivities) {
15097                // This is a cached process, but with client activities.  Mark it so.
15098                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15099                app.adjType = "cch-client-act";
15100            } else if (app.treatLikeActivity) {
15101                // This is a cached process, but somebody wants us to treat it like it has
15102                // an activity, okay!
15103                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15104                app.adjType = "cch-as-act";
15105            }
15106        }
15107
15108        if (adj == ProcessList.SERVICE_ADJ) {
15109            if (doingAll) {
15110                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15111                mNewNumServiceProcs++;
15112                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15113                if (!app.serviceb) {
15114                    // This service isn't far enough down on the LRU list to
15115                    // normally be a B service, but if we are low on RAM and it
15116                    // is large we want to force it down since we would prefer to
15117                    // keep launcher over it.
15118                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15119                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15120                        app.serviceHighRam = true;
15121                        app.serviceb = true;
15122                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15123                    } else {
15124                        mNewNumAServiceProcs++;
15125                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15126                    }
15127                } else {
15128                    app.serviceHighRam = false;
15129                }
15130            }
15131            if (app.serviceb) {
15132                adj = ProcessList.SERVICE_B_ADJ;
15133            }
15134        }
15135
15136        app.curRawAdj = adj;
15137
15138        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15139        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15140        if (adj > app.maxAdj) {
15141            adj = app.maxAdj;
15142            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15143                schedGroup = Process.THREAD_GROUP_DEFAULT;
15144            }
15145        }
15146        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15147            app.keeping = true;
15148        }
15149
15150        // Do final modification to adj.  Everything we do between here and applying
15151        // the final setAdj must be done in this function, because we will also use
15152        // it when computing the final cached adj later.  Note that we don't need to
15153        // worry about this for max adj above, since max adj will always be used to
15154        // keep it out of the cached vaues.
15155        adj = app.modifyRawOomAdj(adj);
15156
15157        app.curProcState = procState;
15158
15159        int importance = app.memImportance;
15160        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
15161            app.curAdj = adj;
15162            app.curSchedGroup = schedGroup;
15163            if (!interesting) {
15164                // For this reporting, if there is not something explicitly
15165                // interesting in this process then we will push it to the
15166                // background importance.
15167                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15168            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
15169                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15170            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
15171                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15172            } else if (adj >= ProcessList.HOME_APP_ADJ) {
15173                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15174            } else if (adj >= ProcessList.SERVICE_ADJ) {
15175                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15176            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15177                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
15178            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
15179                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
15180            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
15181                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
15182            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
15183                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
15184            } else {
15185                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
15186            }
15187        }
15188
15189        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
15190        if (foregroundActivities != app.foregroundActivities) {
15191            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15192        }
15193        if (changes != 0) {
15194            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15195            app.memImportance = importance;
15196            app.foregroundActivities = foregroundActivities;
15197            int i = mPendingProcessChanges.size()-1;
15198            ProcessChangeItem item = null;
15199            while (i >= 0) {
15200                item = mPendingProcessChanges.get(i);
15201                if (item.pid == app.pid) {
15202                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15203                    break;
15204                }
15205                i--;
15206            }
15207            if (i < 0) {
15208                // No existing item in pending changes; need a new one.
15209                final int NA = mAvailProcessChanges.size();
15210                if (NA > 0) {
15211                    item = mAvailProcessChanges.remove(NA-1);
15212                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15213                } else {
15214                    item = new ProcessChangeItem();
15215                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15216                }
15217                item.changes = 0;
15218                item.pid = app.pid;
15219                item.uid = app.info.uid;
15220                if (mPendingProcessChanges.size() == 0) {
15221                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15222                            "*** Enqueueing dispatch processes changed!");
15223                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15224                }
15225                mPendingProcessChanges.add(item);
15226            }
15227            item.changes |= changes;
15228            item.importance = importance;
15229            item.foregroundActivities = foregroundActivities;
15230            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15231                    + Integer.toHexString(System.identityHashCode(item))
15232                    + " " + app.toShortString() + ": changes=" + item.changes
15233                    + " importance=" + item.importance
15234                    + " foreground=" + item.foregroundActivities
15235                    + " type=" + app.adjType + " source=" + app.adjSource
15236                    + " target=" + app.adjTarget);
15237        }
15238
15239        return app.curRawAdj;
15240    }
15241
15242    /**
15243     * Schedule PSS collection of a process.
15244     */
15245    void requestPssLocked(ProcessRecord proc, int procState) {
15246        if (mPendingPssProcesses.contains(proc)) {
15247            return;
15248        }
15249        if (mPendingPssProcesses.size() == 0) {
15250            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15251        }
15252        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15253        proc.pssProcState = procState;
15254        mPendingPssProcesses.add(proc);
15255    }
15256
15257    /**
15258     * Schedule PSS collection of all processes.
15259     */
15260    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15261        if (!always) {
15262            if (now < (mLastFullPssTime +
15263                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15264                return;
15265            }
15266        }
15267        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15268        mLastFullPssTime = now;
15269        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15270        mPendingPssProcesses.clear();
15271        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15272            ProcessRecord app = mLruProcesses.get(i);
15273            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15274                app.pssProcState = app.setProcState;
15275                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15276                        mSleeping, now);
15277                mPendingPssProcesses.add(app);
15278            }
15279        }
15280        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15281    }
15282
15283    /**
15284     * Ask a given process to GC right now.
15285     */
15286    final void performAppGcLocked(ProcessRecord app) {
15287        try {
15288            app.lastRequestedGc = SystemClock.uptimeMillis();
15289            if (app.thread != null) {
15290                if (app.reportLowMemory) {
15291                    app.reportLowMemory = false;
15292                    app.thread.scheduleLowMemory();
15293                } else {
15294                    app.thread.processInBackground();
15295                }
15296            }
15297        } catch (Exception e) {
15298            // whatever.
15299        }
15300    }
15301
15302    /**
15303     * Returns true if things are idle enough to perform GCs.
15304     */
15305    private final boolean canGcNowLocked() {
15306        boolean processingBroadcasts = false;
15307        for (BroadcastQueue q : mBroadcastQueues) {
15308            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15309                processingBroadcasts = true;
15310            }
15311        }
15312        return !processingBroadcasts
15313                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15314    }
15315
15316    /**
15317     * Perform GCs on all processes that are waiting for it, but only
15318     * if things are idle.
15319     */
15320    final void performAppGcsLocked() {
15321        final int N = mProcessesToGc.size();
15322        if (N <= 0) {
15323            return;
15324        }
15325        if (canGcNowLocked()) {
15326            while (mProcessesToGc.size() > 0) {
15327                ProcessRecord proc = mProcessesToGc.remove(0);
15328                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15329                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15330                            <= SystemClock.uptimeMillis()) {
15331                        // To avoid spamming the system, we will GC processes one
15332                        // at a time, waiting a few seconds between each.
15333                        performAppGcLocked(proc);
15334                        scheduleAppGcsLocked();
15335                        return;
15336                    } else {
15337                        // It hasn't been long enough since we last GCed this
15338                        // process...  put it in the list to wait for its time.
15339                        addProcessToGcListLocked(proc);
15340                        break;
15341                    }
15342                }
15343            }
15344
15345            scheduleAppGcsLocked();
15346        }
15347    }
15348
15349    /**
15350     * If all looks good, perform GCs on all processes waiting for them.
15351     */
15352    final void performAppGcsIfAppropriateLocked() {
15353        if (canGcNowLocked()) {
15354            performAppGcsLocked();
15355            return;
15356        }
15357        // Still not idle, wait some more.
15358        scheduleAppGcsLocked();
15359    }
15360
15361    /**
15362     * Schedule the execution of all pending app GCs.
15363     */
15364    final void scheduleAppGcsLocked() {
15365        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15366
15367        if (mProcessesToGc.size() > 0) {
15368            // Schedule a GC for the time to the next process.
15369            ProcessRecord proc = mProcessesToGc.get(0);
15370            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15371
15372            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15373            long now = SystemClock.uptimeMillis();
15374            if (when < (now+GC_TIMEOUT)) {
15375                when = now + GC_TIMEOUT;
15376            }
15377            mHandler.sendMessageAtTime(msg, when);
15378        }
15379    }
15380
15381    /**
15382     * Add a process to the array of processes waiting to be GCed.  Keeps the
15383     * list in sorted order by the last GC time.  The process can't already be
15384     * on the list.
15385     */
15386    final void addProcessToGcListLocked(ProcessRecord proc) {
15387        boolean added = false;
15388        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15389            if (mProcessesToGc.get(i).lastRequestedGc <
15390                    proc.lastRequestedGc) {
15391                added = true;
15392                mProcessesToGc.add(i+1, proc);
15393                break;
15394            }
15395        }
15396        if (!added) {
15397            mProcessesToGc.add(0, proc);
15398        }
15399    }
15400
15401    /**
15402     * Set up to ask a process to GC itself.  This will either do it
15403     * immediately, or put it on the list of processes to gc the next
15404     * time things are idle.
15405     */
15406    final void scheduleAppGcLocked(ProcessRecord app) {
15407        long now = SystemClock.uptimeMillis();
15408        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15409            return;
15410        }
15411        if (!mProcessesToGc.contains(app)) {
15412            addProcessToGcListLocked(app);
15413            scheduleAppGcsLocked();
15414        }
15415    }
15416
15417    final void checkExcessivePowerUsageLocked(boolean doKills) {
15418        updateCpuStatsNow();
15419
15420        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15421        boolean doWakeKills = doKills;
15422        boolean doCpuKills = doKills;
15423        if (mLastPowerCheckRealtime == 0) {
15424            doWakeKills = false;
15425        }
15426        if (mLastPowerCheckUptime == 0) {
15427            doCpuKills = false;
15428        }
15429        if (stats.isScreenOn()) {
15430            doWakeKills = false;
15431        }
15432        final long curRealtime = SystemClock.elapsedRealtime();
15433        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15434        final long curUptime = SystemClock.uptimeMillis();
15435        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15436        mLastPowerCheckRealtime = curRealtime;
15437        mLastPowerCheckUptime = curUptime;
15438        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15439            doWakeKills = false;
15440        }
15441        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15442            doCpuKills = false;
15443        }
15444        int i = mLruProcesses.size();
15445        while (i > 0) {
15446            i--;
15447            ProcessRecord app = mLruProcesses.get(i);
15448            if (!app.keeping) {
15449                long wtime;
15450                synchronized (stats) {
15451                    wtime = stats.getProcessWakeTime(app.info.uid,
15452                            app.pid, curRealtime);
15453                }
15454                long wtimeUsed = wtime - app.lastWakeTime;
15455                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15456                if (DEBUG_POWER) {
15457                    StringBuilder sb = new StringBuilder(128);
15458                    sb.append("Wake for ");
15459                    app.toShortString(sb);
15460                    sb.append(": over ");
15461                    TimeUtils.formatDuration(realtimeSince, sb);
15462                    sb.append(" used ");
15463                    TimeUtils.formatDuration(wtimeUsed, sb);
15464                    sb.append(" (");
15465                    sb.append((wtimeUsed*100)/realtimeSince);
15466                    sb.append("%)");
15467                    Slog.i(TAG, sb.toString());
15468                    sb.setLength(0);
15469                    sb.append("CPU for ");
15470                    app.toShortString(sb);
15471                    sb.append(": over ");
15472                    TimeUtils.formatDuration(uptimeSince, sb);
15473                    sb.append(" used ");
15474                    TimeUtils.formatDuration(cputimeUsed, sb);
15475                    sb.append(" (");
15476                    sb.append((cputimeUsed*100)/uptimeSince);
15477                    sb.append("%)");
15478                    Slog.i(TAG, sb.toString());
15479                }
15480                // If a process has held a wake lock for more
15481                // than 50% of the time during this period,
15482                // that sounds bad.  Kill!
15483                if (doWakeKills && realtimeSince > 0
15484                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15485                    synchronized (stats) {
15486                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15487                                realtimeSince, wtimeUsed);
15488                    }
15489                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15490                            + " during " + realtimeSince);
15491                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15492                } else if (doCpuKills && uptimeSince > 0
15493                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15494                    synchronized (stats) {
15495                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15496                                uptimeSince, cputimeUsed);
15497                    }
15498                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15499                            + " during " + uptimeSince);
15500                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15501                } else {
15502                    app.lastWakeTime = wtime;
15503                    app.lastCpuTime = app.curCpuTime;
15504                }
15505            }
15506        }
15507    }
15508
15509    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15510            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15511        boolean success = true;
15512
15513        if (app.curRawAdj != app.setRawAdj) {
15514            if (wasKeeping && !app.keeping) {
15515                // This app is no longer something we want to keep.  Note
15516                // its current wake lock time to later know to kill it if
15517                // it is not behaving well.
15518                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15519                synchronized (stats) {
15520                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15521                            app.pid, SystemClock.elapsedRealtime());
15522                }
15523                app.lastCpuTime = app.curCpuTime;
15524            }
15525
15526            app.setRawAdj = app.curRawAdj;
15527        }
15528
15529        if (app.curAdj != app.setAdj) {
15530            ProcessList.setOomAdj(app.pid, app.curAdj);
15531            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15532                TAG, "Set " + app.pid + " " + app.processName +
15533                " adj " + app.curAdj + ": " + app.adjType);
15534            app.setAdj = app.curAdj;
15535        }
15536
15537        if (app.setSchedGroup != app.curSchedGroup) {
15538            app.setSchedGroup = app.curSchedGroup;
15539            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15540                    "Setting process group of " + app.processName
15541                    + " to " + app.curSchedGroup);
15542            if (app.waitingToKill != null &&
15543                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15544                killUnneededProcessLocked(app, app.waitingToKill);
15545                success = false;
15546            } else {
15547                if (true) {
15548                    long oldId = Binder.clearCallingIdentity();
15549                    try {
15550                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15551                    } catch (Exception e) {
15552                        Slog.w(TAG, "Failed setting process group of " + app.pid
15553                                + " to " + app.curSchedGroup);
15554                        e.printStackTrace();
15555                    } finally {
15556                        Binder.restoreCallingIdentity(oldId);
15557                    }
15558                } else {
15559                    if (app.thread != null) {
15560                        try {
15561                            app.thread.setSchedulingGroup(app.curSchedGroup);
15562                        } catch (RemoteException e) {
15563                        }
15564                    }
15565                }
15566                Process.setSwappiness(app.pid,
15567                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15568            }
15569        }
15570        if (app.repProcState != app.curProcState) {
15571            app.repProcState = app.curProcState;
15572            if (!reportingProcessState && app.thread != null) {
15573                try {
15574                    if (false) {
15575                        //RuntimeException h = new RuntimeException("here");
15576                        Slog.i(TAG, "Sending new process state " + app.repProcState
15577                                + " to " + app /*, h*/);
15578                    }
15579                    app.thread.setProcessState(app.repProcState);
15580                } catch (RemoteException e) {
15581                }
15582            }
15583        }
15584        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15585                app.setProcState)) {
15586            app.lastStateTime = now;
15587            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15588                    mSleeping, now);
15589            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15590                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15591                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15592                    + (app.nextPssTime-now) + ": " + app);
15593        } else {
15594            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15595                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15596                requestPssLocked(app, app.setProcState);
15597                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15598                        mSleeping, now);
15599            } else if (false && DEBUG_PSS) {
15600                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15601            }
15602        }
15603        if (app.setProcState != app.curProcState) {
15604            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15605                    "Proc state change of " + app.processName
15606                    + " to " + app.curProcState);
15607            app.setProcState = app.curProcState;
15608            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15609                app.notCachedSinceIdle = false;
15610            }
15611            if (!doingAll) {
15612                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15613            } else {
15614                app.procStateChanged = true;
15615            }
15616        }
15617        return success;
15618    }
15619
15620    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15621        if (proc.thread != null && proc.baseProcessTracker != null) {
15622            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15623        }
15624    }
15625
15626    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15627            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15628        if (app.thread == null) {
15629            return false;
15630        }
15631
15632        final boolean wasKeeping = app.keeping;
15633
15634        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15635
15636        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15637                reportingProcessState, now);
15638    }
15639
15640    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15641            boolean oomAdj) {
15642        if (isForeground != proc.foregroundServices) {
15643            proc.foregroundServices = isForeground;
15644            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15645                    proc.info.uid);
15646            if (isForeground) {
15647                if (curProcs == null) {
15648                    curProcs = new ArrayList<ProcessRecord>();
15649                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15650                }
15651                if (!curProcs.contains(proc)) {
15652                    curProcs.add(proc);
15653                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15654                            proc.info.packageName, proc.info.uid);
15655                }
15656            } else {
15657                if (curProcs != null) {
15658                    if (curProcs.remove(proc)) {
15659                        mBatteryStatsService.noteEvent(
15660                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15661                                proc.info.packageName, proc.info.uid);
15662                        if (curProcs.size() <= 0) {
15663                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15664                        }
15665                    }
15666                }
15667            }
15668            if (oomAdj) {
15669                updateOomAdjLocked();
15670            }
15671        }
15672    }
15673
15674    private final ActivityRecord resumedAppLocked() {
15675        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15676        String pkg;
15677        int uid;
15678        if (act != null && !act.sleeping) {
15679            pkg = act.packageName;
15680            uid = act.info.applicationInfo.uid;
15681        } else {
15682            pkg = null;
15683            uid = -1;
15684        }
15685        // Has the UID or resumed package name changed?
15686        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15687                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15688            if (mCurResumedPackage != null) {
15689                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15690                        mCurResumedPackage, mCurResumedUid);
15691            }
15692            mCurResumedPackage = pkg;
15693            mCurResumedUid = uid;
15694            if (mCurResumedPackage != null) {
15695                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15696                        mCurResumedPackage, mCurResumedUid);
15697            }
15698        }
15699        return act;
15700    }
15701
15702    final boolean updateOomAdjLocked(ProcessRecord app) {
15703        return updateOomAdjLocked(app, false);
15704    }
15705
15706    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15707        final ActivityRecord TOP_ACT = resumedAppLocked();
15708        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15709        final boolean wasCached = app.cached;
15710
15711        mAdjSeq++;
15712
15713        // This is the desired cached adjusment we want to tell it to use.
15714        // If our app is currently cached, we know it, and that is it.  Otherwise,
15715        // we don't know it yet, and it needs to now be cached we will then
15716        // need to do a complete oom adj.
15717        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15718                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15719        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15720                SystemClock.uptimeMillis());
15721        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15722            // Changed to/from cached state, so apps after it in the LRU
15723            // list may also be changed.
15724            updateOomAdjLocked();
15725        }
15726        return success;
15727    }
15728
15729    final void updateOomAdjLocked() {
15730        final ActivityRecord TOP_ACT = resumedAppLocked();
15731        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15732        final long now = SystemClock.uptimeMillis();
15733        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15734        final int N = mLruProcesses.size();
15735
15736        if (false) {
15737            RuntimeException e = new RuntimeException();
15738            e.fillInStackTrace();
15739            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15740        }
15741
15742        mAdjSeq++;
15743        mNewNumServiceProcs = 0;
15744        mNewNumAServiceProcs = 0;
15745
15746        final int emptyProcessLimit;
15747        final int cachedProcessLimit;
15748        if (mProcessLimit <= 0) {
15749            emptyProcessLimit = cachedProcessLimit = 0;
15750        } else if (mProcessLimit == 1) {
15751            emptyProcessLimit = 1;
15752            cachedProcessLimit = 0;
15753        } else {
15754            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15755            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15756        }
15757
15758        // Let's determine how many processes we have running vs.
15759        // how many slots we have for background processes; we may want
15760        // to put multiple processes in a slot of there are enough of
15761        // them.
15762        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15763                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15764        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15765        if (numEmptyProcs > cachedProcessLimit) {
15766            // If there are more empty processes than our limit on cached
15767            // processes, then use the cached process limit for the factor.
15768            // This ensures that the really old empty processes get pushed
15769            // down to the bottom, so if we are running low on memory we will
15770            // have a better chance at keeping around more cached processes
15771            // instead of a gazillion empty processes.
15772            numEmptyProcs = cachedProcessLimit;
15773        }
15774        int emptyFactor = numEmptyProcs/numSlots;
15775        if (emptyFactor < 1) emptyFactor = 1;
15776        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15777        if (cachedFactor < 1) cachedFactor = 1;
15778        int stepCached = 0;
15779        int stepEmpty = 0;
15780        int numCached = 0;
15781        int numEmpty = 0;
15782        int numTrimming = 0;
15783
15784        mNumNonCachedProcs = 0;
15785        mNumCachedHiddenProcs = 0;
15786
15787        // First update the OOM adjustment for each of the
15788        // application processes based on their current state.
15789        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15790        int nextCachedAdj = curCachedAdj+1;
15791        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15792        int nextEmptyAdj = curEmptyAdj+2;
15793        for (int i=N-1; i>=0; i--) {
15794            ProcessRecord app = mLruProcesses.get(i);
15795            if (!app.killedByAm && app.thread != null) {
15796                app.procStateChanged = false;
15797                final boolean wasKeeping = app.keeping;
15798                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15799
15800                // If we haven't yet assigned the final cached adj
15801                // to the process, do that now.
15802                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15803                    switch (app.curProcState) {
15804                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15805                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15806                            // This process is a cached process holding activities...
15807                            // assign it the next cached value for that type, and then
15808                            // step that cached level.
15809                            app.curRawAdj = curCachedAdj;
15810                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15811                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15812                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15813                                    + ")");
15814                            if (curCachedAdj != nextCachedAdj) {
15815                                stepCached++;
15816                                if (stepCached >= cachedFactor) {
15817                                    stepCached = 0;
15818                                    curCachedAdj = nextCachedAdj;
15819                                    nextCachedAdj += 2;
15820                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15821                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15822                                    }
15823                                }
15824                            }
15825                            break;
15826                        default:
15827                            // For everything else, assign next empty cached process
15828                            // level and bump that up.  Note that this means that
15829                            // long-running services that have dropped down to the
15830                            // cached level will be treated as empty (since their process
15831                            // state is still as a service), which is what we want.
15832                            app.curRawAdj = curEmptyAdj;
15833                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15834                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15835                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15836                                    + ")");
15837                            if (curEmptyAdj != nextEmptyAdj) {
15838                                stepEmpty++;
15839                                if (stepEmpty >= emptyFactor) {
15840                                    stepEmpty = 0;
15841                                    curEmptyAdj = nextEmptyAdj;
15842                                    nextEmptyAdj += 2;
15843                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15844                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15845                                    }
15846                                }
15847                            }
15848                            break;
15849                    }
15850                }
15851
15852                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15853
15854                // Count the number of process types.
15855                switch (app.curProcState) {
15856                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15857                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15858                        mNumCachedHiddenProcs++;
15859                        numCached++;
15860                        if (numCached > cachedProcessLimit) {
15861                            killUnneededProcessLocked(app, "cached #" + numCached);
15862                        }
15863                        break;
15864                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15865                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15866                                && app.lastActivityTime < oldTime) {
15867                            killUnneededProcessLocked(app, "empty for "
15868                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15869                                    / 1000) + "s");
15870                        } else {
15871                            numEmpty++;
15872                            if (numEmpty > emptyProcessLimit) {
15873                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15874                            }
15875                        }
15876                        break;
15877                    default:
15878                        mNumNonCachedProcs++;
15879                        break;
15880                }
15881
15882                if (app.isolated && app.services.size() <= 0) {
15883                    // If this is an isolated process, and there are no
15884                    // services running in it, then the process is no longer
15885                    // needed.  We agressively kill these because we can by
15886                    // definition not re-use the same process again, and it is
15887                    // good to avoid having whatever code was running in them
15888                    // left sitting around after no longer needed.
15889                    killUnneededProcessLocked(app, "isolated not needed");
15890                }
15891
15892                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15893                        && !app.killedByAm) {
15894                    numTrimming++;
15895                }
15896            }
15897        }
15898
15899        mNumServiceProcs = mNewNumServiceProcs;
15900
15901        // Now determine the memory trimming level of background processes.
15902        // Unfortunately we need to start at the back of the list to do this
15903        // properly.  We only do this if the number of background apps we
15904        // are managing to keep around is less than half the maximum we desire;
15905        // if we are keeping a good number around, we'll let them use whatever
15906        // memory they want.
15907        final int numCachedAndEmpty = numCached + numEmpty;
15908        int memFactor;
15909        if (numCached <= ProcessList.TRIM_CACHED_APPS
15910                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15911            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15912                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15913            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15914                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15915            } else {
15916                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15917            }
15918        } else {
15919            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15920        }
15921        // We always allow the memory level to go up (better).  We only allow it to go
15922        // down if we are in a state where that is allowed, *and* the total number of processes
15923        // has gone down since last time.
15924        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15925                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15926                + " last=" + mLastNumProcesses);
15927        if (memFactor > mLastMemoryLevel) {
15928            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15929                memFactor = mLastMemoryLevel;
15930                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15931            }
15932        }
15933        mLastMemoryLevel = memFactor;
15934        mLastNumProcesses = mLruProcesses.size();
15935        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15936        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15937        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15938            if (mLowRamStartTime == 0) {
15939                mLowRamStartTime = now;
15940            }
15941            int step = 0;
15942            int fgTrimLevel;
15943            switch (memFactor) {
15944                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15945                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15946                    break;
15947                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15948                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15949                    break;
15950                default:
15951                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15952                    break;
15953            }
15954            int factor = numTrimming/3;
15955            int minFactor = 2;
15956            if (mHomeProcess != null) minFactor++;
15957            if (mPreviousProcess != null) minFactor++;
15958            if (factor < minFactor) factor = minFactor;
15959            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15960            for (int i=N-1; i>=0; i--) {
15961                ProcessRecord app = mLruProcesses.get(i);
15962                if (allChanged || app.procStateChanged) {
15963                    setProcessTrackerState(app, trackerMemFactor, now);
15964                    app.procStateChanged = false;
15965                }
15966                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15967                        && !app.killedByAm) {
15968                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15969                        try {
15970                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15971                                    "Trimming memory of " + app.processName
15972                                    + " to " + curLevel);
15973                            app.thread.scheduleTrimMemory(curLevel);
15974                        } catch (RemoteException e) {
15975                        }
15976                        if (false) {
15977                            // For now we won't do this; our memory trimming seems
15978                            // to be good enough at this point that destroying
15979                            // activities causes more harm than good.
15980                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15981                                    && app != mHomeProcess && app != mPreviousProcess) {
15982                                // Need to do this on its own message because the stack may not
15983                                // be in a consistent state at this point.
15984                                // For these apps we will also finish their activities
15985                                // to help them free memory.
15986                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15987                            }
15988                        }
15989                    }
15990                    app.trimMemoryLevel = curLevel;
15991                    step++;
15992                    if (step >= factor) {
15993                        step = 0;
15994                        switch (curLevel) {
15995                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15996                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15997                                break;
15998                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15999                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16000                                break;
16001                        }
16002                    }
16003                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16004                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16005                            && app.thread != null) {
16006                        try {
16007                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16008                                    "Trimming memory of heavy-weight " + app.processName
16009                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16010                            app.thread.scheduleTrimMemory(
16011                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16012                        } catch (RemoteException e) {
16013                        }
16014                    }
16015                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16016                } else {
16017                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16018                            || app.systemNoUi) && app.pendingUiClean) {
16019                        // If this application is now in the background and it
16020                        // had done UI, then give it the special trim level to
16021                        // have it free UI resources.
16022                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16023                        if (app.trimMemoryLevel < level && app.thread != null) {
16024                            try {
16025                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16026                                        "Trimming memory of bg-ui " + app.processName
16027                                        + " to " + level);
16028                                app.thread.scheduleTrimMemory(level);
16029                            } catch (RemoteException e) {
16030                            }
16031                        }
16032                        app.pendingUiClean = false;
16033                    }
16034                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16035                        try {
16036                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16037                                    "Trimming memory of fg " + app.processName
16038                                    + " to " + fgTrimLevel);
16039                            app.thread.scheduleTrimMemory(fgTrimLevel);
16040                        } catch (RemoteException e) {
16041                        }
16042                    }
16043                    app.trimMemoryLevel = fgTrimLevel;
16044                }
16045            }
16046        } else {
16047            if (mLowRamStartTime != 0) {
16048                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16049                mLowRamStartTime = 0;
16050            }
16051            for (int i=N-1; i>=0; i--) {
16052                ProcessRecord app = mLruProcesses.get(i);
16053                if (allChanged || app.procStateChanged) {
16054                    setProcessTrackerState(app, trackerMemFactor, now);
16055                    app.procStateChanged = false;
16056                }
16057                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16058                        || app.systemNoUi) && app.pendingUiClean) {
16059                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16060                            && app.thread != null) {
16061                        try {
16062                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16063                                    "Trimming memory of ui hidden " + app.processName
16064                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16065                            app.thread.scheduleTrimMemory(
16066                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16067                        } catch (RemoteException e) {
16068                        }
16069                    }
16070                    app.pendingUiClean = false;
16071                }
16072                app.trimMemoryLevel = 0;
16073            }
16074        }
16075
16076        if (mAlwaysFinishActivities) {
16077            // Need to do this on its own message because the stack may not
16078            // be in a consistent state at this point.
16079            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16080        }
16081
16082        if (allChanged) {
16083            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16084        }
16085
16086        if (mProcessStats.shouldWriteNowLocked(now)) {
16087            mHandler.post(new Runnable() {
16088                @Override public void run() {
16089                    synchronized (ActivityManagerService.this) {
16090                        mProcessStats.writeStateAsyncLocked();
16091                    }
16092                }
16093            });
16094        }
16095
16096        if (DEBUG_OOM_ADJ) {
16097            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16098        }
16099    }
16100
16101    final void trimApplications() {
16102        synchronized (this) {
16103            int i;
16104
16105            // First remove any unused application processes whose package
16106            // has been removed.
16107            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16108                final ProcessRecord app = mRemovedProcesses.get(i);
16109                if (app.activities.size() == 0
16110                        && app.curReceiver == null && app.services.size() == 0) {
16111                    Slog.i(
16112                        TAG, "Exiting empty application process "
16113                        + app.processName + " ("
16114                        + (app.thread != null ? app.thread.asBinder() : null)
16115                        + ")\n");
16116                    if (app.pid > 0 && app.pid != MY_PID) {
16117                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16118                                app.processName, app.setAdj, "empty");
16119                        app.killedByAm = true;
16120                        Process.killProcessQuiet(app.pid);
16121                    } else {
16122                        try {
16123                            app.thread.scheduleExit();
16124                        } catch (Exception e) {
16125                            // Ignore exceptions.
16126                        }
16127                    }
16128                    cleanUpApplicationRecordLocked(app, false, true, -1);
16129                    mRemovedProcesses.remove(i);
16130
16131                    if (app.persistent) {
16132                        if (app.persistent) {
16133                            addAppLocked(app.info, false);
16134                        }
16135                    }
16136                }
16137            }
16138
16139            // Now update the oom adj for all processes.
16140            updateOomAdjLocked();
16141        }
16142    }
16143
16144    /** This method sends the specified signal to each of the persistent apps */
16145    public void signalPersistentProcesses(int sig) throws RemoteException {
16146        if (sig != Process.SIGNAL_USR1) {
16147            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16148        }
16149
16150        synchronized (this) {
16151            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16152                    != PackageManager.PERMISSION_GRANTED) {
16153                throw new SecurityException("Requires permission "
16154                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16155            }
16156
16157            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16158                ProcessRecord r = mLruProcesses.get(i);
16159                if (r.thread != null && r.persistent) {
16160                    Process.sendSignal(r.pid, sig);
16161                }
16162            }
16163        }
16164    }
16165
16166    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16167        if (proc == null || proc == mProfileProc) {
16168            proc = mProfileProc;
16169            path = mProfileFile;
16170            profileType = mProfileType;
16171            clearProfilerLocked();
16172        }
16173        if (proc == null) {
16174            return;
16175        }
16176        try {
16177            proc.thread.profilerControl(false, path, null, profileType);
16178        } catch (RemoteException e) {
16179            throw new IllegalStateException("Process disappeared");
16180        }
16181    }
16182
16183    private void clearProfilerLocked() {
16184        if (mProfileFd != null) {
16185            try {
16186                mProfileFd.close();
16187            } catch (IOException e) {
16188            }
16189        }
16190        mProfileApp = null;
16191        mProfileProc = null;
16192        mProfileFile = null;
16193        mProfileType = 0;
16194        mAutoStopProfiler = false;
16195    }
16196
16197    public boolean profileControl(String process, int userId, boolean start,
16198            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16199
16200        try {
16201            synchronized (this) {
16202                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16203                // its own permission.
16204                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16205                        != PackageManager.PERMISSION_GRANTED) {
16206                    throw new SecurityException("Requires permission "
16207                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16208                }
16209
16210                if (start && fd == null) {
16211                    throw new IllegalArgumentException("null fd");
16212                }
16213
16214                ProcessRecord proc = null;
16215                if (process != null) {
16216                    proc = findProcessLocked(process, userId, "profileControl");
16217                }
16218
16219                if (start && (proc == null || proc.thread == null)) {
16220                    throw new IllegalArgumentException("Unknown process: " + process);
16221                }
16222
16223                if (start) {
16224                    stopProfilerLocked(null, null, 0);
16225                    setProfileApp(proc.info, proc.processName, path, fd, false);
16226                    mProfileProc = proc;
16227                    mProfileType = profileType;
16228                    try {
16229                        fd = fd.dup();
16230                    } catch (IOException e) {
16231                        fd = null;
16232                    }
16233                    proc.thread.profilerControl(start, path, fd, profileType);
16234                    fd = null;
16235                    mProfileFd = null;
16236                } else {
16237                    stopProfilerLocked(proc, path, profileType);
16238                    if (fd != null) {
16239                        try {
16240                            fd.close();
16241                        } catch (IOException e) {
16242                        }
16243                    }
16244                }
16245
16246                return true;
16247            }
16248        } catch (RemoteException e) {
16249            throw new IllegalStateException("Process disappeared");
16250        } finally {
16251            if (fd != null) {
16252                try {
16253                    fd.close();
16254                } catch (IOException e) {
16255                }
16256            }
16257        }
16258    }
16259
16260    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16261        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16262                userId, true, true, callName, null);
16263        ProcessRecord proc = null;
16264        try {
16265            int pid = Integer.parseInt(process);
16266            synchronized (mPidsSelfLocked) {
16267                proc = mPidsSelfLocked.get(pid);
16268            }
16269        } catch (NumberFormatException e) {
16270        }
16271
16272        if (proc == null) {
16273            ArrayMap<String, SparseArray<ProcessRecord>> all
16274                    = mProcessNames.getMap();
16275            SparseArray<ProcessRecord> procs = all.get(process);
16276            if (procs != null && procs.size() > 0) {
16277                proc = procs.valueAt(0);
16278                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16279                    for (int i=1; i<procs.size(); i++) {
16280                        ProcessRecord thisProc = procs.valueAt(i);
16281                        if (thisProc.userId == userId) {
16282                            proc = thisProc;
16283                            break;
16284                        }
16285                    }
16286                }
16287            }
16288        }
16289
16290        return proc;
16291    }
16292
16293    public boolean dumpHeap(String process, int userId, boolean managed,
16294            String path, ParcelFileDescriptor fd) throws RemoteException {
16295
16296        try {
16297            synchronized (this) {
16298                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16299                // its own permission (same as profileControl).
16300                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16301                        != PackageManager.PERMISSION_GRANTED) {
16302                    throw new SecurityException("Requires permission "
16303                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16304                }
16305
16306                if (fd == null) {
16307                    throw new IllegalArgumentException("null fd");
16308                }
16309
16310                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16311                if (proc == null || proc.thread == null) {
16312                    throw new IllegalArgumentException("Unknown process: " + process);
16313                }
16314
16315                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16316                if (!isDebuggable) {
16317                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16318                        throw new SecurityException("Process not debuggable: " + proc);
16319                    }
16320                }
16321
16322                proc.thread.dumpHeap(managed, path, fd);
16323                fd = null;
16324                return true;
16325            }
16326        } catch (RemoteException e) {
16327            throw new IllegalStateException("Process disappeared");
16328        } finally {
16329            if (fd != null) {
16330                try {
16331                    fd.close();
16332                } catch (IOException e) {
16333                }
16334            }
16335        }
16336    }
16337
16338    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16339    public void monitor() {
16340        synchronized (this) { }
16341    }
16342
16343    void onCoreSettingsChange(Bundle settings) {
16344        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16345            ProcessRecord processRecord = mLruProcesses.get(i);
16346            try {
16347                if (processRecord.thread != null) {
16348                    processRecord.thread.setCoreSettings(settings);
16349                }
16350            } catch (RemoteException re) {
16351                /* ignore */
16352            }
16353        }
16354    }
16355
16356    // Multi-user methods
16357
16358    /**
16359     * Start user, if its not already running, but don't bring it to foreground.
16360     */
16361    @Override
16362    public boolean startUserInBackground(final int userId) {
16363        return startUser(userId, /* foreground */ false);
16364    }
16365
16366    /**
16367     * Refreshes the list of users related to the current user when either a
16368     * user switch happens or when a new related user is started in the
16369     * background.
16370     */
16371    private void updateCurrentProfileIdsLocked() {
16372        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16373                mCurrentUserId, false /* enabledOnly */);
16374        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16375        for (int i = 0; i < currentProfileIds.length; i++) {
16376            currentProfileIds[i] = profiles.get(i).id;
16377        }
16378        mCurrentProfileIds = currentProfileIds;
16379    }
16380
16381    private Set getProfileIdsLocked(int userId) {
16382        Set userIds = new HashSet<Integer>();
16383        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16384                userId, false /* enabledOnly */);
16385        for (UserInfo user : profiles) {
16386            userIds.add(Integer.valueOf(user.id));
16387        }
16388        return userIds;
16389    }
16390
16391    @Override
16392    public boolean switchUser(final int userId) {
16393        return startUser(userId, /* foregound */ true);
16394    }
16395
16396    private boolean startUser(final int userId, boolean foreground) {
16397        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16398                != PackageManager.PERMISSION_GRANTED) {
16399            String msg = "Permission Denial: switchUser() from pid="
16400                    + Binder.getCallingPid()
16401                    + ", uid=" + Binder.getCallingUid()
16402                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16403            Slog.w(TAG, msg);
16404            throw new SecurityException(msg);
16405        }
16406
16407        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16408
16409        final long ident = Binder.clearCallingIdentity();
16410        try {
16411            synchronized (this) {
16412                final int oldUserId = mCurrentUserId;
16413                if (oldUserId == userId) {
16414                    return true;
16415                }
16416
16417                mStackSupervisor.setLockTaskModeLocked(null);
16418
16419                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16420                if (userInfo == null) {
16421                    Slog.w(TAG, "No user info for user #" + userId);
16422                    return false;
16423                }
16424
16425                if (foreground) {
16426                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16427                            R.anim.screen_user_enter);
16428                }
16429
16430                boolean needStart = false;
16431
16432                // If the user we are switching to is not currently started, then
16433                // we need to start it now.
16434                if (mStartedUsers.get(userId) == null) {
16435                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16436                    updateStartedUserArrayLocked();
16437                    needStart = true;
16438                }
16439
16440                final Integer userIdInt = Integer.valueOf(userId);
16441                mUserLru.remove(userIdInt);
16442                mUserLru.add(userIdInt);
16443
16444                if (foreground) {
16445                    mCurrentUserId = userId;
16446                    updateCurrentProfileIdsLocked();
16447                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16448                    // Once the internal notion of the active user has switched, we lock the device
16449                    // with the option to show the user switcher on the keyguard.
16450                    mWindowManager.lockNow(null);
16451                } else {
16452                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16453                    updateCurrentProfileIdsLocked();
16454                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16455                    mUserLru.remove(currentUserIdInt);
16456                    mUserLru.add(currentUserIdInt);
16457                }
16458
16459                final UserStartedState uss = mStartedUsers.get(userId);
16460
16461                // Make sure user is in the started state.  If it is currently
16462                // stopping, we need to knock that off.
16463                if (uss.mState == UserStartedState.STATE_STOPPING) {
16464                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16465                    // so we can just fairly silently bring the user back from
16466                    // the almost-dead.
16467                    uss.mState = UserStartedState.STATE_RUNNING;
16468                    updateStartedUserArrayLocked();
16469                    needStart = true;
16470                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16471                    // This means ACTION_SHUTDOWN has been sent, so we will
16472                    // need to treat this as a new boot of the user.
16473                    uss.mState = UserStartedState.STATE_BOOTING;
16474                    updateStartedUserArrayLocked();
16475                    needStart = true;
16476                }
16477
16478                if (foreground) {
16479                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16480                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16481                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16482                            oldUserId, userId, uss));
16483                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16484                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16485                }
16486
16487                if (needStart) {
16488                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16489                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16490                            | Intent.FLAG_RECEIVER_FOREGROUND);
16491                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16492                    broadcastIntentLocked(null, null, intent,
16493                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16494                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16495                }
16496
16497                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16498                    if (userId != 0) {
16499                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16500                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16501                        broadcastIntentLocked(null, null, intent, null,
16502                                new IIntentReceiver.Stub() {
16503                                    public void performReceive(Intent intent, int resultCode,
16504                                            String data, Bundle extras, boolean ordered,
16505                                            boolean sticky, int sendingUser) {
16506                                        userInitialized(uss, userId);
16507                                    }
16508                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16509                                true, false, MY_PID, Process.SYSTEM_UID,
16510                                userId);
16511                        uss.initializing = true;
16512                    } else {
16513                        getUserManagerLocked().makeInitialized(userInfo.id);
16514                    }
16515                }
16516
16517                if (foreground) {
16518                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16519                    if (homeInFront) {
16520                        startHomeActivityLocked(userId);
16521                    } else {
16522                        mStackSupervisor.resumeTopActivitiesLocked();
16523                    }
16524                    EventLogTags.writeAmSwitchUser(userId);
16525                    getUserManagerLocked().userForeground(userId);
16526                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16527                }
16528
16529                if (needStart) {
16530                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16531                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16532                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16533                    broadcastIntentLocked(null, null, intent,
16534                            null, new IIntentReceiver.Stub() {
16535                                @Override
16536                                public void performReceive(Intent intent, int resultCode, String data,
16537                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16538                                        throws RemoteException {
16539                                }
16540                            }, 0, null, null,
16541                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16542                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16543                }
16544            }
16545        } finally {
16546            Binder.restoreCallingIdentity(ident);
16547        }
16548
16549        return true;
16550    }
16551
16552    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16553        long ident = Binder.clearCallingIdentity();
16554        try {
16555            Intent intent;
16556            if (oldUserId >= 0) {
16557                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16558                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16559                        | Intent.FLAG_RECEIVER_FOREGROUND);
16560                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16561                broadcastIntentLocked(null, null, intent,
16562                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16563                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16564            }
16565            if (newUserId >= 0) {
16566                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16567                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16568                        | Intent.FLAG_RECEIVER_FOREGROUND);
16569                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16570                broadcastIntentLocked(null, null, intent,
16571                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16572                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16573                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16574                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16575                        | Intent.FLAG_RECEIVER_FOREGROUND);
16576                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16577                broadcastIntentLocked(null, null, intent,
16578                        null, null, 0, null, null,
16579                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16580                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16581            }
16582        } finally {
16583            Binder.restoreCallingIdentity(ident);
16584        }
16585    }
16586
16587    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16588            final int newUserId) {
16589        final int N = mUserSwitchObservers.beginBroadcast();
16590        if (N > 0) {
16591            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16592                int mCount = 0;
16593                @Override
16594                public void sendResult(Bundle data) throws RemoteException {
16595                    synchronized (ActivityManagerService.this) {
16596                        if (mCurUserSwitchCallback == this) {
16597                            mCount++;
16598                            if (mCount == N) {
16599                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16600                            }
16601                        }
16602                    }
16603                }
16604            };
16605            synchronized (this) {
16606                uss.switching = true;
16607                mCurUserSwitchCallback = callback;
16608            }
16609            for (int i=0; i<N; i++) {
16610                try {
16611                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16612                            newUserId, callback);
16613                } catch (RemoteException e) {
16614                }
16615            }
16616        } else {
16617            synchronized (this) {
16618                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16619            }
16620        }
16621        mUserSwitchObservers.finishBroadcast();
16622    }
16623
16624    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16625        synchronized (this) {
16626            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16627            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16628        }
16629    }
16630
16631    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16632        mCurUserSwitchCallback = null;
16633        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16634        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16635                oldUserId, newUserId, uss));
16636    }
16637
16638    void userInitialized(UserStartedState uss, int newUserId) {
16639        completeSwitchAndInitalize(uss, newUserId, true, false);
16640    }
16641
16642    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16643        completeSwitchAndInitalize(uss, newUserId, false, true);
16644    }
16645
16646    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16647            boolean clearInitializing, boolean clearSwitching) {
16648        boolean unfrozen = false;
16649        synchronized (this) {
16650            if (clearInitializing) {
16651                uss.initializing = false;
16652                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16653            }
16654            if (clearSwitching) {
16655                uss.switching = false;
16656            }
16657            if (!uss.switching && !uss.initializing) {
16658                mWindowManager.stopFreezingScreen();
16659                unfrozen = true;
16660            }
16661        }
16662        if (unfrozen) {
16663            final int N = mUserSwitchObservers.beginBroadcast();
16664            for (int i=0; i<N; i++) {
16665                try {
16666                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16667                } catch (RemoteException e) {
16668                }
16669            }
16670            mUserSwitchObservers.finishBroadcast();
16671        }
16672    }
16673
16674    void scheduleStartProfilesLocked() {
16675        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16676            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16677                    DateUtils.SECOND_IN_MILLIS);
16678        }
16679    }
16680
16681    void startProfilesLocked() {
16682        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16683        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16684                mCurrentUserId, false /* enabledOnly */);
16685        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16686        for (UserInfo user : profiles) {
16687            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16688                    && user.id != mCurrentUserId) {
16689                toStart.add(user);
16690            }
16691        }
16692        final int n = toStart.size();
16693        int i = 0;
16694        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16695            startUserInBackground(toStart.get(i).id);
16696        }
16697        if (i < n) {
16698            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16699        }
16700    }
16701
16702    void finishUserSwitch(UserStartedState uss) {
16703        synchronized (this) {
16704            if (uss.mState == UserStartedState.STATE_BOOTING
16705                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16706                uss.mState = UserStartedState.STATE_RUNNING;
16707                final int userId = uss.mHandle.getIdentifier();
16708                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16709                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16710                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16711                broadcastIntentLocked(null, null, intent,
16712                        null, null, 0, null, null,
16713                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16714                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16715            }
16716
16717            startProfilesLocked();
16718
16719            int num = mUserLru.size();
16720            int i = 0;
16721            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16722                Integer oldUserId = mUserLru.get(i);
16723                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16724                if (oldUss == null) {
16725                    // Shouldn't happen, but be sane if it does.
16726                    mUserLru.remove(i);
16727                    num--;
16728                    continue;
16729                }
16730                if (oldUss.mState == UserStartedState.STATE_STOPPING
16731                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16732                    // This user is already stopping, doesn't count.
16733                    num--;
16734                    i++;
16735                    continue;
16736                }
16737                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16738                    // Owner and current can't be stopped, but count as running.
16739                    i++;
16740                    continue;
16741                }
16742                // This is a user to be stopped.
16743                stopUserLocked(oldUserId, null);
16744                num--;
16745                i++;
16746            }
16747        }
16748    }
16749
16750    @Override
16751    public int stopUser(final int userId, final IStopUserCallback callback) {
16752        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16753                != PackageManager.PERMISSION_GRANTED) {
16754            String msg = "Permission Denial: switchUser() from pid="
16755                    + Binder.getCallingPid()
16756                    + ", uid=" + Binder.getCallingUid()
16757                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16758            Slog.w(TAG, msg);
16759            throw new SecurityException(msg);
16760        }
16761        if (userId <= 0) {
16762            throw new IllegalArgumentException("Can't stop primary user " + userId);
16763        }
16764        synchronized (this) {
16765            return stopUserLocked(userId, callback);
16766        }
16767    }
16768
16769    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16770        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16771        if (mCurrentUserId == userId) {
16772            return ActivityManager.USER_OP_IS_CURRENT;
16773        }
16774
16775        final UserStartedState uss = mStartedUsers.get(userId);
16776        if (uss == null) {
16777            // User is not started, nothing to do...  but we do need to
16778            // callback if requested.
16779            if (callback != null) {
16780                mHandler.post(new Runnable() {
16781                    @Override
16782                    public void run() {
16783                        try {
16784                            callback.userStopped(userId);
16785                        } catch (RemoteException e) {
16786                        }
16787                    }
16788                });
16789            }
16790            return ActivityManager.USER_OP_SUCCESS;
16791        }
16792
16793        if (callback != null) {
16794            uss.mStopCallbacks.add(callback);
16795        }
16796
16797        if (uss.mState != UserStartedState.STATE_STOPPING
16798                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16799            uss.mState = UserStartedState.STATE_STOPPING;
16800            updateStartedUserArrayLocked();
16801
16802            long ident = Binder.clearCallingIdentity();
16803            try {
16804                // We are going to broadcast ACTION_USER_STOPPING and then
16805                // once that is done send a final ACTION_SHUTDOWN and then
16806                // stop the user.
16807                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16808                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16809                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16810                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16811                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16812                // This is the result receiver for the final shutdown broadcast.
16813                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16814                    @Override
16815                    public void performReceive(Intent intent, int resultCode, String data,
16816                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16817                        finishUserStop(uss);
16818                    }
16819                };
16820                // This is the result receiver for the initial stopping broadcast.
16821                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16822                    @Override
16823                    public void performReceive(Intent intent, int resultCode, String data,
16824                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16825                        // On to the next.
16826                        synchronized (ActivityManagerService.this) {
16827                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16828                                // Whoops, we are being started back up.  Abort, abort!
16829                                return;
16830                            }
16831                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16832                        }
16833                        broadcastIntentLocked(null, null, shutdownIntent,
16834                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16835                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16836                    }
16837                };
16838                // Kick things off.
16839                broadcastIntentLocked(null, null, stoppingIntent,
16840                        null, stoppingReceiver, 0, null, null,
16841                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16842                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16843            } finally {
16844                Binder.restoreCallingIdentity(ident);
16845            }
16846        }
16847
16848        return ActivityManager.USER_OP_SUCCESS;
16849    }
16850
16851    void finishUserStop(UserStartedState uss) {
16852        final int userId = uss.mHandle.getIdentifier();
16853        boolean stopped;
16854        ArrayList<IStopUserCallback> callbacks;
16855        synchronized (this) {
16856            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16857            if (mStartedUsers.get(userId) != uss) {
16858                stopped = false;
16859            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16860                stopped = false;
16861            } else {
16862                stopped = true;
16863                // User can no longer run.
16864                mStartedUsers.remove(userId);
16865                mUserLru.remove(Integer.valueOf(userId));
16866                updateStartedUserArrayLocked();
16867
16868                // Clean up all state and processes associated with the user.
16869                // Kill all the processes for the user.
16870                forceStopUserLocked(userId, "finish user");
16871            }
16872        }
16873
16874        for (int i=0; i<callbacks.size(); i++) {
16875            try {
16876                if (stopped) callbacks.get(i).userStopped(userId);
16877                else callbacks.get(i).userStopAborted(userId);
16878            } catch (RemoteException e) {
16879            }
16880        }
16881
16882        mStackSupervisor.removeUserLocked(userId);
16883    }
16884
16885    @Override
16886    public UserInfo getCurrentUser() {
16887        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16888                != PackageManager.PERMISSION_GRANTED) && (
16889                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16890                != PackageManager.PERMISSION_GRANTED)) {
16891            String msg = "Permission Denial: getCurrentUser() from pid="
16892                    + Binder.getCallingPid()
16893                    + ", uid=" + Binder.getCallingUid()
16894                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16895            Slog.w(TAG, msg);
16896            throw new SecurityException(msg);
16897        }
16898        synchronized (this) {
16899            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16900        }
16901    }
16902
16903    int getCurrentUserIdLocked() {
16904        return mCurrentUserId;
16905    }
16906
16907    @Override
16908    public boolean isUserRunning(int userId, boolean orStopped) {
16909        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16910                != PackageManager.PERMISSION_GRANTED) {
16911            String msg = "Permission Denial: isUserRunning() from pid="
16912                    + Binder.getCallingPid()
16913                    + ", uid=" + Binder.getCallingUid()
16914                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16915            Slog.w(TAG, msg);
16916            throw new SecurityException(msg);
16917        }
16918        synchronized (this) {
16919            return isUserRunningLocked(userId, orStopped);
16920        }
16921    }
16922
16923    boolean isUserRunningLocked(int userId, boolean orStopped) {
16924        UserStartedState state = mStartedUsers.get(userId);
16925        if (state == null) {
16926            return false;
16927        }
16928        if (orStopped) {
16929            return true;
16930        }
16931        return state.mState != UserStartedState.STATE_STOPPING
16932                && state.mState != UserStartedState.STATE_SHUTDOWN;
16933    }
16934
16935    @Override
16936    public int[] getRunningUserIds() {
16937        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16938                != PackageManager.PERMISSION_GRANTED) {
16939            String msg = "Permission Denial: isUserRunning() from pid="
16940                    + Binder.getCallingPid()
16941                    + ", uid=" + Binder.getCallingUid()
16942                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16943            Slog.w(TAG, msg);
16944            throw new SecurityException(msg);
16945        }
16946        synchronized (this) {
16947            return mStartedUserArray;
16948        }
16949    }
16950
16951    private void updateStartedUserArrayLocked() {
16952        int num = 0;
16953        for (int i=0; i<mStartedUsers.size();  i++) {
16954            UserStartedState uss = mStartedUsers.valueAt(i);
16955            // This list does not include stopping users.
16956            if (uss.mState != UserStartedState.STATE_STOPPING
16957                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16958                num++;
16959            }
16960        }
16961        mStartedUserArray = new int[num];
16962        num = 0;
16963        for (int i=0; i<mStartedUsers.size();  i++) {
16964            UserStartedState uss = mStartedUsers.valueAt(i);
16965            if (uss.mState != UserStartedState.STATE_STOPPING
16966                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16967                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16968                num++;
16969            }
16970        }
16971    }
16972
16973    @Override
16974    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16975        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16976                != PackageManager.PERMISSION_GRANTED) {
16977            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16978                    + Binder.getCallingPid()
16979                    + ", uid=" + Binder.getCallingUid()
16980                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16981            Slog.w(TAG, msg);
16982            throw new SecurityException(msg);
16983        }
16984
16985        mUserSwitchObservers.register(observer);
16986    }
16987
16988    @Override
16989    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16990        mUserSwitchObservers.unregister(observer);
16991    }
16992
16993    private boolean userExists(int userId) {
16994        if (userId == 0) {
16995            return true;
16996        }
16997        UserManagerService ums = getUserManagerLocked();
16998        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16999    }
17000
17001    int[] getUsersLocked() {
17002        UserManagerService ums = getUserManagerLocked();
17003        return ums != null ? ums.getUserIds() : new int[] { 0 };
17004    }
17005
17006    UserManagerService getUserManagerLocked() {
17007        if (mUserManager == null) {
17008            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17009            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17010        }
17011        return mUserManager;
17012    }
17013
17014    private int applyUserId(int uid, int userId) {
17015        return UserHandle.getUid(userId, uid);
17016    }
17017
17018    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17019        if (info == null) return null;
17020        ApplicationInfo newInfo = new ApplicationInfo(info);
17021        newInfo.uid = applyUserId(info.uid, userId);
17022        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17023                + info.packageName;
17024        return newInfo;
17025    }
17026
17027    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17028        if (aInfo == null
17029                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17030            return aInfo;
17031        }
17032
17033        ActivityInfo info = new ActivityInfo(aInfo);
17034        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17035        return info;
17036    }
17037
17038    private final class LocalService extends ActivityManagerInternal {
17039        @Override
17040        public void goingToSleep() {
17041            ActivityManagerService.this.goingToSleep();
17042        }
17043
17044        @Override
17045        public void wakingUp() {
17046            ActivityManagerService.this.wakingUp();
17047        }
17048    }
17049}
17050