ActivityManagerService.java revision 21de56a94668e0fda1b8bb4ee4f99a09b40d28fd
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     *
3457     * @return Returns true if the activity successfully finished, or false if it is still running.
3458     */
3459    @Override
3460    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3461        // Refuse possible leaked file descriptors
3462        if (resultData != null && resultData.hasFileDescriptors() == true) {
3463            throw new IllegalArgumentException("File descriptors passed in Intent");
3464        }
3465
3466        synchronized(this) {
3467            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3468            if (r == null) {
3469                return true;
3470            }
3471            if (mController != null) {
3472                // Find the first activity that is not finishing.
3473                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3474                if (next != null) {
3475                    // ask watcher if this is allowed
3476                    boolean resumeOK = true;
3477                    try {
3478                        resumeOK = mController.activityResuming(next.packageName);
3479                    } catch (RemoteException e) {
3480                        mController = null;
3481                        Watchdog.getInstance().setActivityController(null);
3482                    }
3483
3484                    if (!resumeOK) {
3485                        return false;
3486                    }
3487                }
3488            }
3489            final long origId = Binder.clearCallingIdentity();
3490            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3491                    resultData, "app-request", true);
3492            Binder.restoreCallingIdentity(origId);
3493            return res;
3494        }
3495    }
3496
3497    @Override
3498    public final void finishHeavyWeightApp() {
3499        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3500                != PackageManager.PERMISSION_GRANTED) {
3501            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3502                    + Binder.getCallingPid()
3503                    + ", uid=" + Binder.getCallingUid()
3504                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3505            Slog.w(TAG, msg);
3506            throw new SecurityException(msg);
3507        }
3508
3509        synchronized(this) {
3510            if (mHeavyWeightProcess == null) {
3511                return;
3512            }
3513
3514            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3515                    mHeavyWeightProcess.activities);
3516            for (int i=0; i<activities.size(); i++) {
3517                ActivityRecord r = activities.get(i);
3518                if (!r.finishing) {
3519                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3520                            null, "finish-heavy", true);
3521                }
3522            }
3523
3524            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3525                    mHeavyWeightProcess.userId, 0));
3526            mHeavyWeightProcess = null;
3527        }
3528    }
3529
3530    @Override
3531    public void crashApplication(int uid, int initialPid, String packageName,
3532            String message) {
3533        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3534                != PackageManager.PERMISSION_GRANTED) {
3535            String msg = "Permission Denial: crashApplication() from pid="
3536                    + Binder.getCallingPid()
3537                    + ", uid=" + Binder.getCallingUid()
3538                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3539            Slog.w(TAG, msg);
3540            throw new SecurityException(msg);
3541        }
3542
3543        synchronized(this) {
3544            ProcessRecord proc = null;
3545
3546            // Figure out which process to kill.  We don't trust that initialPid
3547            // still has any relation to current pids, so must scan through the
3548            // list.
3549            synchronized (mPidsSelfLocked) {
3550                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3551                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3552                    if (p.uid != uid) {
3553                        continue;
3554                    }
3555                    if (p.pid == initialPid) {
3556                        proc = p;
3557                        break;
3558                    }
3559                    if (p.pkgList.containsKey(packageName)) {
3560                        proc = p;
3561                    }
3562                }
3563            }
3564
3565            if (proc == null) {
3566                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3567                        + " initialPid=" + initialPid
3568                        + " packageName=" + packageName);
3569                return;
3570            }
3571
3572            if (proc.thread != null) {
3573                if (proc.pid == Process.myPid()) {
3574                    Log.w(TAG, "crashApplication: trying to crash self!");
3575                    return;
3576                }
3577                long ident = Binder.clearCallingIdentity();
3578                try {
3579                    proc.thread.scheduleCrash(message);
3580                } catch (RemoteException e) {
3581                }
3582                Binder.restoreCallingIdentity(ident);
3583            }
3584        }
3585    }
3586
3587    @Override
3588    public final void finishSubActivity(IBinder token, String resultWho,
3589            int requestCode) {
3590        synchronized(this) {
3591            final long origId = Binder.clearCallingIdentity();
3592            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3593            if (r != null) {
3594                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3595            }
3596            Binder.restoreCallingIdentity(origId);
3597        }
3598    }
3599
3600    @Override
3601    public boolean finishActivityAffinity(IBinder token) {
3602        synchronized(this) {
3603            final long origId = Binder.clearCallingIdentity();
3604            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3605            boolean res = false;
3606            if (r != null) {
3607                res = r.task.stack.finishActivityAffinityLocked(r);
3608            }
3609            Binder.restoreCallingIdentity(origId);
3610            return res;
3611        }
3612    }
3613
3614    @Override
3615    public boolean willActivityBeVisible(IBinder token) {
3616        synchronized(this) {
3617            ActivityStack stack = ActivityRecord.getStackLocked(token);
3618            if (stack != null) {
3619                return stack.willActivityBeVisibleLocked(token);
3620            }
3621            return false;
3622        }
3623    }
3624
3625    @Override
3626    public void overridePendingTransition(IBinder token, String packageName,
3627            int enterAnim, int exitAnim) {
3628        synchronized(this) {
3629            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3630            if (self == null) {
3631                return;
3632            }
3633
3634            final long origId = Binder.clearCallingIdentity();
3635
3636            if (self.state == ActivityState.RESUMED
3637                    || self.state == ActivityState.PAUSING) {
3638                mWindowManager.overridePendingAppTransition(packageName,
3639                        enterAnim, exitAnim, null);
3640            }
3641
3642            Binder.restoreCallingIdentity(origId);
3643        }
3644    }
3645
3646    /**
3647     * Main function for removing an existing process from the activity manager
3648     * as a result of that process going away.  Clears out all connections
3649     * to the process.
3650     */
3651    private final void handleAppDiedLocked(ProcessRecord app,
3652            boolean restarting, boolean allowRestart) {
3653        int pid = app.pid;
3654        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3655        if (!restarting) {
3656            removeLruProcessLocked(app);
3657            if (pid > 0) {
3658                ProcessList.remove(pid);
3659            }
3660        }
3661
3662        if (mProfileProc == app) {
3663            clearProfilerLocked();
3664        }
3665
3666        // Remove this application's activities from active lists.
3667        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3668
3669        app.activities.clear();
3670
3671        if (app.instrumentationClass != null) {
3672            Slog.w(TAG, "Crash of app " + app.processName
3673                  + " running instrumentation " + app.instrumentationClass);
3674            Bundle info = new Bundle();
3675            info.putString("shortMsg", "Process crashed.");
3676            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3677        }
3678
3679        if (!restarting) {
3680            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3681                // If there was nothing to resume, and we are not already
3682                // restarting this process, but there is a visible activity that
3683                // is hosted by the process...  then make sure all visible
3684                // activities are running, taking care of restarting this
3685                // process.
3686                if (hasVisibleActivities) {
3687                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3688                }
3689            }
3690        }
3691    }
3692
3693    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3694        IBinder threadBinder = thread.asBinder();
3695        // Find the application record.
3696        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3697            ProcessRecord rec = mLruProcesses.get(i);
3698            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3699                return i;
3700            }
3701        }
3702        return -1;
3703    }
3704
3705    final ProcessRecord getRecordForAppLocked(
3706            IApplicationThread thread) {
3707        if (thread == null) {
3708            return null;
3709        }
3710
3711        int appIndex = getLRURecordIndexForAppLocked(thread);
3712        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3713    }
3714
3715    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3716        // If there are no longer any background processes running,
3717        // and the app that died was not running instrumentation,
3718        // then tell everyone we are now low on memory.
3719        boolean haveBg = false;
3720        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3721            ProcessRecord rec = mLruProcesses.get(i);
3722            if (rec.thread != null
3723                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3724                haveBg = true;
3725                break;
3726            }
3727        }
3728
3729        if (!haveBg) {
3730            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3731            if (doReport) {
3732                long now = SystemClock.uptimeMillis();
3733                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3734                    doReport = false;
3735                } else {
3736                    mLastMemUsageReportTime = now;
3737                }
3738            }
3739            final ArrayList<ProcessMemInfo> memInfos
3740                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3741            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3742            long now = SystemClock.uptimeMillis();
3743            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3744                ProcessRecord rec = mLruProcesses.get(i);
3745                if (rec == dyingProc || rec.thread == null) {
3746                    continue;
3747                }
3748                if (doReport) {
3749                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3750                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3751                }
3752                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3753                    // The low memory report is overriding any current
3754                    // state for a GC request.  Make sure to do
3755                    // heavy/important/visible/foreground processes first.
3756                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3757                        rec.lastRequestedGc = 0;
3758                    } else {
3759                        rec.lastRequestedGc = rec.lastLowMemory;
3760                    }
3761                    rec.reportLowMemory = true;
3762                    rec.lastLowMemory = now;
3763                    mProcessesToGc.remove(rec);
3764                    addProcessToGcListLocked(rec);
3765                }
3766            }
3767            if (doReport) {
3768                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3769                mHandler.sendMessage(msg);
3770            }
3771            scheduleAppGcsLocked();
3772        }
3773    }
3774
3775    final void appDiedLocked(ProcessRecord app, int pid,
3776            IApplicationThread thread) {
3777
3778        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3779        synchronized (stats) {
3780            stats.noteProcessDiedLocked(app.info.uid, pid);
3781        }
3782
3783        // Clean up already done if the process has been re-started.
3784        if (app.pid == pid && app.thread != null &&
3785                app.thread.asBinder() == thread.asBinder()) {
3786            boolean doLowMem = app.instrumentationClass == null;
3787            boolean doOomAdj = doLowMem;
3788            if (!app.killedByAm) {
3789                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3790                        + ") has died.");
3791                mAllowLowerMemLevel = true;
3792            } else {
3793                // Note that we always want to do oom adj to update our state with the
3794                // new number of procs.
3795                mAllowLowerMemLevel = false;
3796                doLowMem = false;
3797            }
3798            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3799            if (DEBUG_CLEANUP) Slog.v(
3800                TAG, "Dying app: " + app + ", pid: " + pid
3801                + ", thread: " + thread.asBinder());
3802            handleAppDiedLocked(app, false, true);
3803
3804            if (doOomAdj) {
3805                updateOomAdjLocked();
3806            }
3807            if (doLowMem) {
3808                doLowMemReportIfNeededLocked(app);
3809            }
3810        } else if (app.pid != pid) {
3811            // A new process has already been started.
3812            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3813                    + ") has died and restarted (pid " + app.pid + ").");
3814            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3815        } else if (DEBUG_PROCESSES) {
3816            Slog.d(TAG, "Received spurious death notification for thread "
3817                    + thread.asBinder());
3818        }
3819    }
3820
3821    /**
3822     * If a stack trace dump file is configured, dump process stack traces.
3823     * @param clearTraces causes the dump file to be erased prior to the new
3824     *    traces being written, if true; when false, the new traces will be
3825     *    appended to any existing file content.
3826     * @param firstPids of dalvik VM processes to dump stack traces for first
3827     * @param lastPids of dalvik VM processes to dump stack traces for last
3828     * @param nativeProcs optional list of native process names to dump stack crawls
3829     * @return file containing stack traces, or null if no dump file is configured
3830     */
3831    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3832            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3833        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3834        if (tracesPath == null || tracesPath.length() == 0) {
3835            return null;
3836        }
3837
3838        File tracesFile = new File(tracesPath);
3839        try {
3840            File tracesDir = tracesFile.getParentFile();
3841            if (!tracesDir.exists()) {
3842                tracesFile.mkdirs();
3843                if (!SELinux.restorecon(tracesDir)) {
3844                    return null;
3845                }
3846            }
3847            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3848
3849            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3850            tracesFile.createNewFile();
3851            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3852        } catch (IOException e) {
3853            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3854            return null;
3855        }
3856
3857        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3858        return tracesFile;
3859    }
3860
3861    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3862            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3863        // Use a FileObserver to detect when traces finish writing.
3864        // The order of traces is considered important to maintain for legibility.
3865        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3866            @Override
3867            public synchronized void onEvent(int event, String path) { notify(); }
3868        };
3869
3870        try {
3871            observer.startWatching();
3872
3873            // First collect all of the stacks of the most important pids.
3874            if (firstPids != null) {
3875                try {
3876                    int num = firstPids.size();
3877                    for (int i = 0; i < num; i++) {
3878                        synchronized (observer) {
3879                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3880                            observer.wait(200);  // Wait for write-close, give up after 200msec
3881                        }
3882                    }
3883                } catch (InterruptedException e) {
3884                    Log.wtf(TAG, e);
3885                }
3886            }
3887
3888            // Next collect the stacks of the native pids
3889            if (nativeProcs != null) {
3890                int[] pids = Process.getPidsForCommands(nativeProcs);
3891                if (pids != null) {
3892                    for (int pid : pids) {
3893                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3894                    }
3895                }
3896            }
3897
3898            // Lastly, measure CPU usage.
3899            if (processCpuTracker != null) {
3900                processCpuTracker.init();
3901                System.gc();
3902                processCpuTracker.update();
3903                try {
3904                    synchronized (processCpuTracker) {
3905                        processCpuTracker.wait(500); // measure over 1/2 second.
3906                    }
3907                } catch (InterruptedException e) {
3908                }
3909                processCpuTracker.update();
3910
3911                // We'll take the stack crawls of just the top apps using CPU.
3912                final int N = processCpuTracker.countWorkingStats();
3913                int numProcs = 0;
3914                for (int i=0; i<N && numProcs<5; i++) {
3915                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3916                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3917                        numProcs++;
3918                        try {
3919                            synchronized (observer) {
3920                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3921                                observer.wait(200);  // Wait for write-close, give up after 200msec
3922                            }
3923                        } catch (InterruptedException e) {
3924                            Log.wtf(TAG, e);
3925                        }
3926
3927                    }
3928                }
3929            }
3930        } finally {
3931            observer.stopWatching();
3932        }
3933    }
3934
3935    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3936        if (true || IS_USER_BUILD) {
3937            return;
3938        }
3939        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3940        if (tracesPath == null || tracesPath.length() == 0) {
3941            return;
3942        }
3943
3944        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3945        StrictMode.allowThreadDiskWrites();
3946        try {
3947            final File tracesFile = new File(tracesPath);
3948            final File tracesDir = tracesFile.getParentFile();
3949            final File tracesTmp = new File(tracesDir, "__tmp__");
3950            try {
3951                if (!tracesDir.exists()) {
3952                    tracesFile.mkdirs();
3953                    if (!SELinux.restorecon(tracesDir.getPath())) {
3954                        return;
3955                    }
3956                }
3957                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3958
3959                if (tracesFile.exists()) {
3960                    tracesTmp.delete();
3961                    tracesFile.renameTo(tracesTmp);
3962                }
3963                StringBuilder sb = new StringBuilder();
3964                Time tobj = new Time();
3965                tobj.set(System.currentTimeMillis());
3966                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3967                sb.append(": ");
3968                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3969                sb.append(" since ");
3970                sb.append(msg);
3971                FileOutputStream fos = new FileOutputStream(tracesFile);
3972                fos.write(sb.toString().getBytes());
3973                if (app == null) {
3974                    fos.write("\n*** No application process!".getBytes());
3975                }
3976                fos.close();
3977                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3978            } catch (IOException e) {
3979                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3980                return;
3981            }
3982
3983            if (app != null) {
3984                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3985                firstPids.add(app.pid);
3986                dumpStackTraces(tracesPath, firstPids, null, null, null);
3987            }
3988
3989            File lastTracesFile = null;
3990            File curTracesFile = null;
3991            for (int i=9; i>=0; i--) {
3992                String name = String.format(Locale.US, "slow%02d.txt", i);
3993                curTracesFile = new File(tracesDir, name);
3994                if (curTracesFile.exists()) {
3995                    if (lastTracesFile != null) {
3996                        curTracesFile.renameTo(lastTracesFile);
3997                    } else {
3998                        curTracesFile.delete();
3999                    }
4000                }
4001                lastTracesFile = curTracesFile;
4002            }
4003            tracesFile.renameTo(curTracesFile);
4004            if (tracesTmp.exists()) {
4005                tracesTmp.renameTo(tracesFile);
4006            }
4007        } finally {
4008            StrictMode.setThreadPolicy(oldPolicy);
4009        }
4010    }
4011
4012    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4013            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4014        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4015        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4016
4017        if (mController != null) {
4018            try {
4019                // 0 == continue, -1 = kill process immediately
4020                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4021                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4022            } catch (RemoteException e) {
4023                mController = null;
4024                Watchdog.getInstance().setActivityController(null);
4025            }
4026        }
4027
4028        long anrTime = SystemClock.uptimeMillis();
4029        if (MONITOR_CPU_USAGE) {
4030            updateCpuStatsNow();
4031        }
4032
4033        synchronized (this) {
4034            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4035            if (mShuttingDown) {
4036                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4037                return;
4038            } else if (app.notResponding) {
4039                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4040                return;
4041            } else if (app.crashing) {
4042                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4043                return;
4044            }
4045
4046            // In case we come through here for the same app before completing
4047            // this one, mark as anring now so we will bail out.
4048            app.notResponding = true;
4049
4050            // Log the ANR to the event log.
4051            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4052                    app.processName, app.info.flags, annotation);
4053
4054            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4055            firstPids.add(app.pid);
4056
4057            int parentPid = app.pid;
4058            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4059            if (parentPid != app.pid) firstPids.add(parentPid);
4060
4061            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4062
4063            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4064                ProcessRecord r = mLruProcesses.get(i);
4065                if (r != null && r.thread != null) {
4066                    int pid = r.pid;
4067                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4068                        if (r.persistent) {
4069                            firstPids.add(pid);
4070                        } else {
4071                            lastPids.put(pid, Boolean.TRUE);
4072                        }
4073                    }
4074                }
4075            }
4076        }
4077
4078        // Log the ANR to the main log.
4079        StringBuilder info = new StringBuilder();
4080        info.setLength(0);
4081        info.append("ANR in ").append(app.processName);
4082        if (activity != null && activity.shortComponentName != null) {
4083            info.append(" (").append(activity.shortComponentName).append(")");
4084        }
4085        info.append("\n");
4086        info.append("PID: ").append(app.pid).append("\n");
4087        if (annotation != null) {
4088            info.append("Reason: ").append(annotation).append("\n");
4089        }
4090        if (parent != null && parent != activity) {
4091            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4092        }
4093
4094        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4095
4096        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4097                NATIVE_STACKS_OF_INTEREST);
4098
4099        String cpuInfo = null;
4100        if (MONITOR_CPU_USAGE) {
4101            updateCpuStatsNow();
4102            synchronized (mProcessCpuThread) {
4103                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4104            }
4105            info.append(processCpuTracker.printCurrentLoad());
4106            info.append(cpuInfo);
4107        }
4108
4109        info.append(processCpuTracker.printCurrentState(anrTime));
4110
4111        Slog.e(TAG, info.toString());
4112        if (tracesFile == null) {
4113            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4114            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4115        }
4116
4117        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4118                cpuInfo, tracesFile, null);
4119
4120        if (mController != null) {
4121            try {
4122                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4123                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4124                if (res != 0) {
4125                    if (res < 0 && app.pid != MY_PID) {
4126                        Process.killProcess(app.pid);
4127                    } else {
4128                        synchronized (this) {
4129                            mServices.scheduleServiceTimeoutLocked(app);
4130                        }
4131                    }
4132                    return;
4133                }
4134            } catch (RemoteException e) {
4135                mController = null;
4136                Watchdog.getInstance().setActivityController(null);
4137            }
4138        }
4139
4140        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4141        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4142                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4143
4144        synchronized (this) {
4145            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4146                killUnneededProcessLocked(app, "background ANR");
4147                return;
4148            }
4149
4150            // Set the app's notResponding state, and look up the errorReportReceiver
4151            makeAppNotRespondingLocked(app,
4152                    activity != null ? activity.shortComponentName : null,
4153                    annotation != null ? "ANR " + annotation : "ANR",
4154                    info.toString());
4155
4156            // Bring up the infamous App Not Responding dialog
4157            Message msg = Message.obtain();
4158            HashMap<String, Object> map = new HashMap<String, Object>();
4159            msg.what = SHOW_NOT_RESPONDING_MSG;
4160            msg.obj = map;
4161            msg.arg1 = aboveSystem ? 1 : 0;
4162            map.put("app", app);
4163            if (activity != null) {
4164                map.put("activity", activity);
4165            }
4166
4167            mHandler.sendMessage(msg);
4168        }
4169    }
4170
4171    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4172        if (!mLaunchWarningShown) {
4173            mLaunchWarningShown = true;
4174            mHandler.post(new Runnable() {
4175                @Override
4176                public void run() {
4177                    synchronized (ActivityManagerService.this) {
4178                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4179                        d.show();
4180                        mHandler.postDelayed(new Runnable() {
4181                            @Override
4182                            public void run() {
4183                                synchronized (ActivityManagerService.this) {
4184                                    d.dismiss();
4185                                    mLaunchWarningShown = false;
4186                                }
4187                            }
4188                        }, 4000);
4189                    }
4190                }
4191            });
4192        }
4193    }
4194
4195    @Override
4196    public boolean clearApplicationUserData(final String packageName,
4197            final IPackageDataObserver observer, int userId) {
4198        enforceNotIsolatedCaller("clearApplicationUserData");
4199        int uid = Binder.getCallingUid();
4200        int pid = Binder.getCallingPid();
4201        userId = handleIncomingUser(pid, uid,
4202                userId, false, true, "clearApplicationUserData", null);
4203        long callingId = Binder.clearCallingIdentity();
4204        try {
4205            IPackageManager pm = AppGlobals.getPackageManager();
4206            int pkgUid = -1;
4207            synchronized(this) {
4208                try {
4209                    pkgUid = pm.getPackageUid(packageName, userId);
4210                } catch (RemoteException e) {
4211                }
4212                if (pkgUid == -1) {
4213                    Slog.w(TAG, "Invalid packageName: " + packageName);
4214                    if (observer != null) {
4215                        try {
4216                            observer.onRemoveCompleted(packageName, false);
4217                        } catch (RemoteException e) {
4218                            Slog.i(TAG, "Observer no longer exists.");
4219                        }
4220                    }
4221                    return false;
4222                }
4223                if (uid == pkgUid || checkComponentPermission(
4224                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4225                        pid, uid, -1, true)
4226                        == PackageManager.PERMISSION_GRANTED) {
4227                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4228                } else {
4229                    throw new SecurityException("PID " + pid + " does not have permission "
4230                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4231                                    + " of package " + packageName);
4232                }
4233            }
4234
4235            try {
4236                // Clear application user data
4237                pm.clearApplicationUserData(packageName, observer, userId);
4238
4239                // Remove all permissions granted from/to this package
4240                removeUriPermissionsForPackageLocked(packageName, userId, true);
4241
4242                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4243                        Uri.fromParts("package", packageName, null));
4244                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4245                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4246                        null, null, 0, null, null, null, false, false, userId);
4247            } catch (RemoteException e) {
4248            }
4249        } finally {
4250            Binder.restoreCallingIdentity(callingId);
4251        }
4252        return true;
4253    }
4254
4255    @Override
4256    public void killBackgroundProcesses(final String packageName, int userId) {
4257        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4258                != PackageManager.PERMISSION_GRANTED &&
4259                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4260                        != PackageManager.PERMISSION_GRANTED) {
4261            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4262                    + Binder.getCallingPid()
4263                    + ", uid=" + Binder.getCallingUid()
4264                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4265            Slog.w(TAG, msg);
4266            throw new SecurityException(msg);
4267        }
4268
4269        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4270                userId, true, true, "killBackgroundProcesses", null);
4271        long callingId = Binder.clearCallingIdentity();
4272        try {
4273            IPackageManager pm = AppGlobals.getPackageManager();
4274            synchronized(this) {
4275                int appId = -1;
4276                try {
4277                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4278                } catch (RemoteException e) {
4279                }
4280                if (appId == -1) {
4281                    Slog.w(TAG, "Invalid packageName: " + packageName);
4282                    return;
4283                }
4284                killPackageProcessesLocked(packageName, appId, userId,
4285                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4286            }
4287        } finally {
4288            Binder.restoreCallingIdentity(callingId);
4289        }
4290    }
4291
4292    @Override
4293    public void killAllBackgroundProcesses() {
4294        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4295                != PackageManager.PERMISSION_GRANTED) {
4296            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4297                    + Binder.getCallingPid()
4298                    + ", uid=" + Binder.getCallingUid()
4299                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4300            Slog.w(TAG, msg);
4301            throw new SecurityException(msg);
4302        }
4303
4304        long callingId = Binder.clearCallingIdentity();
4305        try {
4306            synchronized(this) {
4307                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4308                final int NP = mProcessNames.getMap().size();
4309                for (int ip=0; ip<NP; ip++) {
4310                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4311                    final int NA = apps.size();
4312                    for (int ia=0; ia<NA; ia++) {
4313                        ProcessRecord app = apps.valueAt(ia);
4314                        if (app.persistent) {
4315                            // we don't kill persistent processes
4316                            continue;
4317                        }
4318                        if (app.removed) {
4319                            procs.add(app);
4320                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4321                            app.removed = true;
4322                            procs.add(app);
4323                        }
4324                    }
4325                }
4326
4327                int N = procs.size();
4328                for (int i=0; i<N; i++) {
4329                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4330                }
4331                mAllowLowerMemLevel = true;
4332                updateOomAdjLocked();
4333                doLowMemReportIfNeededLocked(null);
4334            }
4335        } finally {
4336            Binder.restoreCallingIdentity(callingId);
4337        }
4338    }
4339
4340    @Override
4341    public void forceStopPackage(final String packageName, int userId) {
4342        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4343                != PackageManager.PERMISSION_GRANTED) {
4344            String msg = "Permission Denial: forceStopPackage() from pid="
4345                    + Binder.getCallingPid()
4346                    + ", uid=" + Binder.getCallingUid()
4347                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4348            Slog.w(TAG, msg);
4349            throw new SecurityException(msg);
4350        }
4351        final int callingPid = Binder.getCallingPid();
4352        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4353                userId, true, true, "forceStopPackage", null);
4354        long callingId = Binder.clearCallingIdentity();
4355        try {
4356            IPackageManager pm = AppGlobals.getPackageManager();
4357            synchronized(this) {
4358                int[] users = userId == UserHandle.USER_ALL
4359                        ? getUsersLocked() : new int[] { userId };
4360                for (int user : users) {
4361                    int pkgUid = -1;
4362                    try {
4363                        pkgUid = pm.getPackageUid(packageName, user);
4364                    } catch (RemoteException e) {
4365                    }
4366                    if (pkgUid == -1) {
4367                        Slog.w(TAG, "Invalid packageName: " + packageName);
4368                        continue;
4369                    }
4370                    try {
4371                        pm.setPackageStoppedState(packageName, true, user);
4372                    } catch (RemoteException e) {
4373                    } catch (IllegalArgumentException e) {
4374                        Slog.w(TAG, "Failed trying to unstop package "
4375                                + packageName + ": " + e);
4376                    }
4377                    if (isUserRunningLocked(user, false)) {
4378                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4379                    }
4380                }
4381            }
4382        } finally {
4383            Binder.restoreCallingIdentity(callingId);
4384        }
4385    }
4386
4387    /*
4388     * The pkg name and app id have to be specified.
4389     */
4390    @Override
4391    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4392        if (pkg == null) {
4393            return;
4394        }
4395        // Make sure the uid is valid.
4396        if (appid < 0) {
4397            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4398            return;
4399        }
4400        int callerUid = Binder.getCallingUid();
4401        // Only the system server can kill an application
4402        if (callerUid == Process.SYSTEM_UID) {
4403            // Post an aysnc message to kill the application
4404            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4405            msg.arg1 = appid;
4406            msg.arg2 = 0;
4407            Bundle bundle = new Bundle();
4408            bundle.putString("pkg", pkg);
4409            bundle.putString("reason", reason);
4410            msg.obj = bundle;
4411            mHandler.sendMessage(msg);
4412        } else {
4413            throw new SecurityException(callerUid + " cannot kill pkg: " +
4414                    pkg);
4415        }
4416    }
4417
4418    @Override
4419    public void closeSystemDialogs(String reason) {
4420        enforceNotIsolatedCaller("closeSystemDialogs");
4421
4422        final int pid = Binder.getCallingPid();
4423        final int uid = Binder.getCallingUid();
4424        final long origId = Binder.clearCallingIdentity();
4425        try {
4426            synchronized (this) {
4427                // Only allow this from foreground processes, so that background
4428                // applications can't abuse it to prevent system UI from being shown.
4429                if (uid >= Process.FIRST_APPLICATION_UID) {
4430                    ProcessRecord proc;
4431                    synchronized (mPidsSelfLocked) {
4432                        proc = mPidsSelfLocked.get(pid);
4433                    }
4434                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4435                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4436                                + " from background process " + proc);
4437                        return;
4438                    }
4439                }
4440                closeSystemDialogsLocked(reason);
4441            }
4442        } finally {
4443            Binder.restoreCallingIdentity(origId);
4444        }
4445    }
4446
4447    void closeSystemDialogsLocked(String reason) {
4448        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4449        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4450                | Intent.FLAG_RECEIVER_FOREGROUND);
4451        if (reason != null) {
4452            intent.putExtra("reason", reason);
4453        }
4454        mWindowManager.closeSystemDialogs(reason);
4455
4456        mStackSupervisor.closeSystemDialogsLocked();
4457
4458        broadcastIntentLocked(null, null, intent, null,
4459                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4460                Process.SYSTEM_UID, UserHandle.USER_ALL);
4461    }
4462
4463    @Override
4464    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4465        enforceNotIsolatedCaller("getProcessMemoryInfo");
4466        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4467        for (int i=pids.length-1; i>=0; i--) {
4468            ProcessRecord proc;
4469            int oomAdj;
4470            synchronized (this) {
4471                synchronized (mPidsSelfLocked) {
4472                    proc = mPidsSelfLocked.get(pids[i]);
4473                    oomAdj = proc != null ? proc.setAdj : 0;
4474                }
4475            }
4476            infos[i] = new Debug.MemoryInfo();
4477            Debug.getMemoryInfo(pids[i], infos[i]);
4478            if (proc != null) {
4479                synchronized (this) {
4480                    if (proc.thread != null && proc.setAdj == oomAdj) {
4481                        // Record this for posterity if the process has been stable.
4482                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4483                                infos[i].getTotalUss(), false, proc.pkgList);
4484                    }
4485                }
4486            }
4487        }
4488        return infos;
4489    }
4490
4491    @Override
4492    public long[] getProcessPss(int[] pids) {
4493        enforceNotIsolatedCaller("getProcessPss");
4494        long[] pss = new long[pids.length];
4495        for (int i=pids.length-1; i>=0; i--) {
4496            ProcessRecord proc;
4497            int oomAdj;
4498            synchronized (this) {
4499                synchronized (mPidsSelfLocked) {
4500                    proc = mPidsSelfLocked.get(pids[i]);
4501                    oomAdj = proc != null ? proc.setAdj : 0;
4502                }
4503            }
4504            long[] tmpUss = new long[1];
4505            pss[i] = Debug.getPss(pids[i], tmpUss);
4506            if (proc != null) {
4507                synchronized (this) {
4508                    if (proc.thread != null && proc.setAdj == oomAdj) {
4509                        // Record this for posterity if the process has been stable.
4510                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4511                    }
4512                }
4513            }
4514        }
4515        return pss;
4516    }
4517
4518    @Override
4519    public void killApplicationProcess(String processName, int uid) {
4520        if (processName == null) {
4521            return;
4522        }
4523
4524        int callerUid = Binder.getCallingUid();
4525        // Only the system server can kill an application
4526        if (callerUid == Process.SYSTEM_UID) {
4527            synchronized (this) {
4528                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4529                if (app != null && app.thread != null) {
4530                    try {
4531                        app.thread.scheduleSuicide();
4532                    } catch (RemoteException e) {
4533                        // If the other end already died, then our work here is done.
4534                    }
4535                } else {
4536                    Slog.w(TAG, "Process/uid not found attempting kill of "
4537                            + processName + " / " + uid);
4538                }
4539            }
4540        } else {
4541            throw new SecurityException(callerUid + " cannot kill app process: " +
4542                    processName);
4543        }
4544    }
4545
4546    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4547        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4548                false, true, false, false, UserHandle.getUserId(uid), reason);
4549        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4550                Uri.fromParts("package", packageName, null));
4551        if (!mProcessesReady) {
4552            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4553                    | Intent.FLAG_RECEIVER_FOREGROUND);
4554        }
4555        intent.putExtra(Intent.EXTRA_UID, uid);
4556        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4557        broadcastIntentLocked(null, null, intent,
4558                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4559                false, false,
4560                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4561    }
4562
4563    private void forceStopUserLocked(int userId, String reason) {
4564        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4565        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4566        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4567                | Intent.FLAG_RECEIVER_FOREGROUND);
4568        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4569        broadcastIntentLocked(null, null, intent,
4570                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4571                false, false,
4572                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4573    }
4574
4575    private final boolean killPackageProcessesLocked(String packageName, int appId,
4576            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4577            boolean doit, boolean evenPersistent, String reason) {
4578        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4579
4580        // Remove all processes this package may have touched: all with the
4581        // same UID (except for the system or root user), and all whose name
4582        // matches the package name.
4583        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4584        final int NP = mProcessNames.getMap().size();
4585        for (int ip=0; ip<NP; ip++) {
4586            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4587            final int NA = apps.size();
4588            for (int ia=0; ia<NA; ia++) {
4589                ProcessRecord app = apps.valueAt(ia);
4590                if (app.persistent && !evenPersistent) {
4591                    // we don't kill persistent processes
4592                    continue;
4593                }
4594                if (app.removed) {
4595                    if (doit) {
4596                        procs.add(app);
4597                    }
4598                    continue;
4599                }
4600
4601                // Skip process if it doesn't meet our oom adj requirement.
4602                if (app.setAdj < minOomAdj) {
4603                    continue;
4604                }
4605
4606                // If no package is specified, we call all processes under the
4607                // give user id.
4608                if (packageName == null) {
4609                    if (app.userId != userId) {
4610                        continue;
4611                    }
4612                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4613                        continue;
4614                    }
4615                // Package has been specified, we want to hit all processes
4616                // that match it.  We need to qualify this by the processes
4617                // that are running under the specified app and user ID.
4618                } else {
4619                    if (UserHandle.getAppId(app.uid) != appId) {
4620                        continue;
4621                    }
4622                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4623                        continue;
4624                    }
4625                    if (!app.pkgList.containsKey(packageName)) {
4626                        continue;
4627                    }
4628                }
4629
4630                // Process has passed all conditions, kill it!
4631                if (!doit) {
4632                    return true;
4633                }
4634                app.removed = true;
4635                procs.add(app);
4636            }
4637        }
4638
4639        int N = procs.size();
4640        for (int i=0; i<N; i++) {
4641            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4642        }
4643        updateOomAdjLocked();
4644        return N > 0;
4645    }
4646
4647    private final boolean forceStopPackageLocked(String name, int appId,
4648            boolean callerWillRestart, boolean purgeCache, boolean doit,
4649            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4650        int i;
4651        int N;
4652
4653        if (userId == UserHandle.USER_ALL && name == null) {
4654            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4655        }
4656
4657        if (appId < 0 && name != null) {
4658            try {
4659                appId = UserHandle.getAppId(
4660                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4661            } catch (RemoteException e) {
4662            }
4663        }
4664
4665        if (doit) {
4666            if (name != null) {
4667                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4668                        + " user=" + userId + ": " + reason);
4669            } else {
4670                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4671            }
4672
4673            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4674            for (int ip=pmap.size()-1; ip>=0; ip--) {
4675                SparseArray<Long> ba = pmap.valueAt(ip);
4676                for (i=ba.size()-1; i>=0; i--) {
4677                    boolean remove = false;
4678                    final int entUid = ba.keyAt(i);
4679                    if (name != null) {
4680                        if (userId == UserHandle.USER_ALL) {
4681                            if (UserHandle.getAppId(entUid) == appId) {
4682                                remove = true;
4683                            }
4684                        } else {
4685                            if (entUid == UserHandle.getUid(userId, appId)) {
4686                                remove = true;
4687                            }
4688                        }
4689                    } else if (UserHandle.getUserId(entUid) == userId) {
4690                        remove = true;
4691                    }
4692                    if (remove) {
4693                        ba.removeAt(i);
4694                    }
4695                }
4696                if (ba.size() == 0) {
4697                    pmap.removeAt(ip);
4698                }
4699            }
4700        }
4701
4702        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4703                -100, callerWillRestart, true, doit, evenPersistent,
4704                name == null ? ("stop user " + userId) : ("stop " + name));
4705
4706        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4707            if (!doit) {
4708                return true;
4709            }
4710            didSomething = true;
4711        }
4712
4713        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4714            if (!doit) {
4715                return true;
4716            }
4717            didSomething = true;
4718        }
4719
4720        if (name == null) {
4721            // Remove all sticky broadcasts from this user.
4722            mStickyBroadcasts.remove(userId);
4723        }
4724
4725        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4726        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4727                userId, providers)) {
4728            if (!doit) {
4729                return true;
4730            }
4731            didSomething = true;
4732        }
4733        N = providers.size();
4734        for (i=0; i<N; i++) {
4735            removeDyingProviderLocked(null, providers.get(i), true);
4736        }
4737
4738        // Remove transient permissions granted from/to this package/user
4739        removeUriPermissionsForPackageLocked(name, userId, false);
4740
4741        if (name == null || uninstalling) {
4742            // Remove pending intents.  For now we only do this when force
4743            // stopping users, because we have some problems when doing this
4744            // for packages -- app widgets are not currently cleaned up for
4745            // such packages, so they can be left with bad pending intents.
4746            if (mIntentSenderRecords.size() > 0) {
4747                Iterator<WeakReference<PendingIntentRecord>> it
4748                        = mIntentSenderRecords.values().iterator();
4749                while (it.hasNext()) {
4750                    WeakReference<PendingIntentRecord> wpir = it.next();
4751                    if (wpir == null) {
4752                        it.remove();
4753                        continue;
4754                    }
4755                    PendingIntentRecord pir = wpir.get();
4756                    if (pir == null) {
4757                        it.remove();
4758                        continue;
4759                    }
4760                    if (name == null) {
4761                        // Stopping user, remove all objects for the user.
4762                        if (pir.key.userId != userId) {
4763                            // Not the same user, skip it.
4764                            continue;
4765                        }
4766                    } else {
4767                        if (UserHandle.getAppId(pir.uid) != appId) {
4768                            // Different app id, skip it.
4769                            continue;
4770                        }
4771                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4772                            // Different user, skip it.
4773                            continue;
4774                        }
4775                        if (!pir.key.packageName.equals(name)) {
4776                            // Different package, skip it.
4777                            continue;
4778                        }
4779                    }
4780                    if (!doit) {
4781                        return true;
4782                    }
4783                    didSomething = true;
4784                    it.remove();
4785                    pir.canceled = true;
4786                    if (pir.key.activity != null) {
4787                        pir.key.activity.pendingResults.remove(pir.ref);
4788                    }
4789                }
4790            }
4791        }
4792
4793        if (doit) {
4794            if (purgeCache && name != null) {
4795                AttributeCache ac = AttributeCache.instance();
4796                if (ac != null) {
4797                    ac.removePackage(name);
4798                }
4799            }
4800            if (mBooted) {
4801                mStackSupervisor.resumeTopActivitiesLocked();
4802                mStackSupervisor.scheduleIdleLocked();
4803            }
4804        }
4805
4806        return didSomething;
4807    }
4808
4809    private final boolean removeProcessLocked(ProcessRecord app,
4810            boolean callerWillRestart, boolean allowRestart, String reason) {
4811        final String name = app.processName;
4812        final int uid = app.uid;
4813        if (DEBUG_PROCESSES) Slog.d(
4814            TAG, "Force removing proc " + app.toShortString() + " (" + name
4815            + "/" + uid + ")");
4816
4817        mProcessNames.remove(name, uid);
4818        mIsolatedProcesses.remove(app.uid);
4819        if (mHeavyWeightProcess == app) {
4820            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4821                    mHeavyWeightProcess.userId, 0));
4822            mHeavyWeightProcess = null;
4823        }
4824        boolean needRestart = false;
4825        if (app.pid > 0 && app.pid != MY_PID) {
4826            int pid = app.pid;
4827            synchronized (mPidsSelfLocked) {
4828                mPidsSelfLocked.remove(pid);
4829                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4830            }
4831            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4832                    app.processName, app.info.uid);
4833            if (app.isolated) {
4834                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4835            }
4836            killUnneededProcessLocked(app, reason);
4837            handleAppDiedLocked(app, true, allowRestart);
4838            removeLruProcessLocked(app);
4839
4840            if (app.persistent && !app.isolated) {
4841                if (!callerWillRestart) {
4842                    addAppLocked(app.info, false);
4843                } else {
4844                    needRestart = true;
4845                }
4846            }
4847        } else {
4848            mRemovedProcesses.add(app);
4849        }
4850
4851        return needRestart;
4852    }
4853
4854    private final void processStartTimedOutLocked(ProcessRecord app) {
4855        final int pid = app.pid;
4856        boolean gone = false;
4857        synchronized (mPidsSelfLocked) {
4858            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4859            if (knownApp != null && knownApp.thread == null) {
4860                mPidsSelfLocked.remove(pid);
4861                gone = true;
4862            }
4863        }
4864
4865        if (gone) {
4866            Slog.w(TAG, "Process " + app + " failed to attach");
4867            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4868                    pid, app.uid, app.processName);
4869            mProcessNames.remove(app.processName, app.uid);
4870            mIsolatedProcesses.remove(app.uid);
4871            if (mHeavyWeightProcess == app) {
4872                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4873                        mHeavyWeightProcess.userId, 0));
4874                mHeavyWeightProcess = null;
4875            }
4876            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4877                    app.processName, app.info.uid);
4878            if (app.isolated) {
4879                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4880            }
4881            // Take care of any launching providers waiting for this process.
4882            checkAppInLaunchingProvidersLocked(app, true);
4883            // Take care of any services that are waiting for the process.
4884            mServices.processStartTimedOutLocked(app);
4885            killUnneededProcessLocked(app, "start timeout");
4886            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4887                Slog.w(TAG, "Unattached app died before backup, skipping");
4888                try {
4889                    IBackupManager bm = IBackupManager.Stub.asInterface(
4890                            ServiceManager.getService(Context.BACKUP_SERVICE));
4891                    bm.agentDisconnected(app.info.packageName);
4892                } catch (RemoteException e) {
4893                    // Can't happen; the backup manager is local
4894                }
4895            }
4896            if (isPendingBroadcastProcessLocked(pid)) {
4897                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4898                skipPendingBroadcastLocked(pid);
4899            }
4900        } else {
4901            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4902        }
4903    }
4904
4905    private final boolean attachApplicationLocked(IApplicationThread thread,
4906            int pid) {
4907
4908        // Find the application record that is being attached...  either via
4909        // the pid if we are running in multiple processes, or just pull the
4910        // next app record if we are emulating process with anonymous threads.
4911        ProcessRecord app;
4912        if (pid != MY_PID && pid >= 0) {
4913            synchronized (mPidsSelfLocked) {
4914                app = mPidsSelfLocked.get(pid);
4915            }
4916        } else {
4917            app = null;
4918        }
4919
4920        if (app == null) {
4921            Slog.w(TAG, "No pending application record for pid " + pid
4922                    + " (IApplicationThread " + thread + "); dropping process");
4923            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4924            if (pid > 0 && pid != MY_PID) {
4925                Process.killProcessQuiet(pid);
4926            } else {
4927                try {
4928                    thread.scheduleExit();
4929                } catch (Exception e) {
4930                    // Ignore exceptions.
4931                }
4932            }
4933            return false;
4934        }
4935
4936        // If this application record is still attached to a previous
4937        // process, clean it up now.
4938        if (app.thread != null) {
4939            handleAppDiedLocked(app, true, true);
4940        }
4941
4942        // Tell the process all about itself.
4943
4944        if (localLOGV) Slog.v(
4945                TAG, "Binding process pid " + pid + " to record " + app);
4946
4947        final String processName = app.processName;
4948        try {
4949            AppDeathRecipient adr = new AppDeathRecipient(
4950                    app, pid, thread);
4951            thread.asBinder().linkToDeath(adr, 0);
4952            app.deathRecipient = adr;
4953        } catch (RemoteException e) {
4954            app.resetPackageList(mProcessStats);
4955            startProcessLocked(app, "link fail", processName);
4956            return false;
4957        }
4958
4959        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4960
4961        app.makeActive(thread, mProcessStats);
4962        app.curAdj = app.setAdj = -100;
4963        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4964        app.forcingToForeground = null;
4965        updateProcessForegroundLocked(app, false, false);
4966        app.hasShownUi = false;
4967        app.debugging = false;
4968        app.cached = false;
4969
4970        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4971
4972        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4973        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4974
4975        if (!normalMode) {
4976            Slog.i(TAG, "Launching preboot mode app: " + app);
4977        }
4978
4979        if (localLOGV) Slog.v(
4980            TAG, "New app record " + app
4981            + " thread=" + thread.asBinder() + " pid=" + pid);
4982        try {
4983            int testMode = IApplicationThread.DEBUG_OFF;
4984            if (mDebugApp != null && mDebugApp.equals(processName)) {
4985                testMode = mWaitForDebugger
4986                    ? IApplicationThread.DEBUG_WAIT
4987                    : IApplicationThread.DEBUG_ON;
4988                app.debugging = true;
4989                if (mDebugTransient) {
4990                    mDebugApp = mOrigDebugApp;
4991                    mWaitForDebugger = mOrigWaitForDebugger;
4992                }
4993            }
4994            String profileFile = app.instrumentationProfileFile;
4995            ParcelFileDescriptor profileFd = null;
4996            boolean profileAutoStop = false;
4997            if (mProfileApp != null && mProfileApp.equals(processName)) {
4998                mProfileProc = app;
4999                profileFile = mProfileFile;
5000                profileFd = mProfileFd;
5001                profileAutoStop = mAutoStopProfiler;
5002            }
5003            boolean enableOpenGlTrace = false;
5004            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5005                enableOpenGlTrace = true;
5006                mOpenGlTraceApp = null;
5007            }
5008
5009            // If the app is being launched for restore or full backup, set it up specially
5010            boolean isRestrictedBackupMode = false;
5011            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5012                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5013                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5014                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5015            }
5016
5017            ensurePackageDexOpt(app.instrumentationInfo != null
5018                    ? app.instrumentationInfo.packageName
5019                    : app.info.packageName);
5020            if (app.instrumentationClass != null) {
5021                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5022            }
5023            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5024                    + processName + " with config " + mConfiguration);
5025            ApplicationInfo appInfo = app.instrumentationInfo != null
5026                    ? app.instrumentationInfo : app.info;
5027            app.compat = compatibilityInfoForPackageLocked(appInfo);
5028            if (profileFd != null) {
5029                profileFd = profileFd.dup();
5030            }
5031            thread.bindApplication(processName, appInfo, providers,
5032                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5033                    app.instrumentationArguments, app.instrumentationWatcher,
5034                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5035                    isRestrictedBackupMode || !normalMode, app.persistent,
5036                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5037                    mCoreSettingsObserver.getCoreSettingsLocked());
5038            updateLruProcessLocked(app, false, null);
5039            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5040        } catch (Exception e) {
5041            // todo: Yikes!  What should we do?  For now we will try to
5042            // start another process, but that could easily get us in
5043            // an infinite loop of restarting processes...
5044            Slog.w(TAG, "Exception thrown during bind!", e);
5045
5046            app.resetPackageList(mProcessStats);
5047            app.unlinkDeathRecipient();
5048            startProcessLocked(app, "bind fail", processName);
5049            return false;
5050        }
5051
5052        // Remove this record from the list of starting applications.
5053        mPersistentStartingProcesses.remove(app);
5054        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5055                "Attach application locked removing on hold: " + app);
5056        mProcessesOnHold.remove(app);
5057
5058        boolean badApp = false;
5059        boolean didSomething = false;
5060
5061        // See if the top visible activity is waiting to run in this process...
5062        if (normalMode) {
5063            try {
5064                if (mStackSupervisor.attachApplicationLocked(app)) {
5065                    didSomething = true;
5066                }
5067            } catch (Exception e) {
5068                badApp = true;
5069            }
5070        }
5071
5072        // Find any services that should be running in this process...
5073        if (!badApp) {
5074            try {
5075                didSomething |= mServices.attachApplicationLocked(app, processName);
5076            } catch (Exception e) {
5077                badApp = true;
5078            }
5079        }
5080
5081        // Check if a next-broadcast receiver is in this process...
5082        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5083            try {
5084                didSomething |= sendPendingBroadcastsLocked(app);
5085            } catch (Exception e) {
5086                // If the app died trying to launch the receiver we declare it 'bad'
5087                badApp = true;
5088            }
5089        }
5090
5091        // Check whether the next backup agent is in this process...
5092        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5093            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5094            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5095            try {
5096                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5097                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5098                        mBackupTarget.backupMode);
5099            } catch (Exception e) {
5100                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5101                e.printStackTrace();
5102            }
5103        }
5104
5105        if (badApp) {
5106            // todo: Also need to kill application to deal with all
5107            // kinds of exceptions.
5108            handleAppDiedLocked(app, false, true);
5109            return false;
5110        }
5111
5112        if (!didSomething) {
5113            updateOomAdjLocked();
5114        }
5115
5116        return true;
5117    }
5118
5119    @Override
5120    public final void attachApplication(IApplicationThread thread) {
5121        synchronized (this) {
5122            int callingPid = Binder.getCallingPid();
5123            final long origId = Binder.clearCallingIdentity();
5124            attachApplicationLocked(thread, callingPid);
5125            Binder.restoreCallingIdentity(origId);
5126        }
5127    }
5128
5129    @Override
5130    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5131        final long origId = Binder.clearCallingIdentity();
5132        synchronized (this) {
5133            ActivityStack stack = ActivityRecord.getStackLocked(token);
5134            if (stack != null) {
5135                ActivityRecord r =
5136                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5137                if (stopProfiling) {
5138                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5139                        try {
5140                            mProfileFd.close();
5141                        } catch (IOException e) {
5142                        }
5143                        clearProfilerLocked();
5144                    }
5145                }
5146            }
5147        }
5148        Binder.restoreCallingIdentity(origId);
5149    }
5150
5151    void enableScreenAfterBoot() {
5152        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5153                SystemClock.uptimeMillis());
5154        mWindowManager.enableScreenAfterBoot();
5155
5156        synchronized (this) {
5157            updateEventDispatchingLocked();
5158        }
5159    }
5160
5161    @Override
5162    public void showBootMessage(final CharSequence msg, final boolean always) {
5163        enforceNotIsolatedCaller("showBootMessage");
5164        mWindowManager.showBootMessage(msg, always);
5165    }
5166
5167    @Override
5168    public void dismissKeyguardOnNextActivity() {
5169        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5170        final long token = Binder.clearCallingIdentity();
5171        try {
5172            synchronized (this) {
5173                if (DEBUG_LOCKSCREEN) logLockScreen("");
5174                if (mLockScreenShown) {
5175                    mLockScreenShown = false;
5176                    comeOutOfSleepIfNeededLocked();
5177                }
5178                mStackSupervisor.setDismissKeyguard(true);
5179            }
5180        } finally {
5181            Binder.restoreCallingIdentity(token);
5182        }
5183    }
5184
5185    final void finishBooting() {
5186        IntentFilter pkgFilter = new IntentFilter();
5187        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5188        pkgFilter.addDataScheme("package");
5189        mContext.registerReceiver(new BroadcastReceiver() {
5190            @Override
5191            public void onReceive(Context context, Intent intent) {
5192                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5193                if (pkgs != null) {
5194                    for (String pkg : pkgs) {
5195                        synchronized (ActivityManagerService.this) {
5196                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5197                                    "finished booting")) {
5198                                setResultCode(Activity.RESULT_OK);
5199                                return;
5200                            }
5201                        }
5202                    }
5203                }
5204            }
5205        }, pkgFilter);
5206
5207        synchronized (this) {
5208            // Ensure that any processes we had put on hold are now started
5209            // up.
5210            final int NP = mProcessesOnHold.size();
5211            if (NP > 0) {
5212                ArrayList<ProcessRecord> procs =
5213                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5214                for (int ip=0; ip<NP; ip++) {
5215                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5216                            + procs.get(ip));
5217                    startProcessLocked(procs.get(ip), "on-hold", null);
5218                }
5219            }
5220
5221            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5222                // Start looking for apps that are abusing wake locks.
5223                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5224                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5225                // Tell anyone interested that we are done booting!
5226                SystemProperties.set("sys.boot_completed", "1");
5227                SystemProperties.set("dev.bootcomplete", "1");
5228                for (int i=0; i<mStartedUsers.size(); i++) {
5229                    UserStartedState uss = mStartedUsers.valueAt(i);
5230                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5231                        uss.mState = UserStartedState.STATE_RUNNING;
5232                        final int userId = mStartedUsers.keyAt(i);
5233                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5234                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5235                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5236                        broadcastIntentLocked(null, null, intent, null,
5237                                new IIntentReceiver.Stub() {
5238                                    @Override
5239                                    public void performReceive(Intent intent, int resultCode,
5240                                            String data, Bundle extras, boolean ordered,
5241                                            boolean sticky, int sendingUser) {
5242                                        synchronized (ActivityManagerService.this) {
5243                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5244                                                    true, false);
5245                                        }
5246                                    }
5247                                },
5248                                0, null, null,
5249                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5250                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5251                                userId);
5252                    }
5253                }
5254                scheduleStartProfilesLocked();
5255            }
5256        }
5257    }
5258
5259    final void ensureBootCompleted() {
5260        boolean booting;
5261        boolean enableScreen;
5262        synchronized (this) {
5263            booting = mBooting;
5264            mBooting = false;
5265            enableScreen = !mBooted;
5266            mBooted = true;
5267        }
5268
5269        if (booting) {
5270            finishBooting();
5271        }
5272
5273        if (enableScreen) {
5274            enableScreenAfterBoot();
5275        }
5276    }
5277
5278    @Override
5279    public final void activityResumed(IBinder token) {
5280        final long origId = Binder.clearCallingIdentity();
5281        synchronized(this) {
5282            ActivityStack stack = ActivityRecord.getStackLocked(token);
5283            if (stack != null) {
5284                ActivityRecord.activityResumedLocked(token);
5285            }
5286        }
5287        Binder.restoreCallingIdentity(origId);
5288    }
5289
5290    @Override
5291    public final void activityPaused(IBinder token) {
5292        final long origId = Binder.clearCallingIdentity();
5293        synchronized(this) {
5294            ActivityStack stack = ActivityRecord.getStackLocked(token);
5295            if (stack != null) {
5296                stack.activityPausedLocked(token, false);
5297            }
5298        }
5299        Binder.restoreCallingIdentity(origId);
5300    }
5301
5302    @Override
5303    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5304            CharSequence description) {
5305        if (localLOGV) Slog.v(
5306            TAG, "Activity stopped: token=" + token);
5307
5308        // Refuse possible leaked file descriptors
5309        if (icicle != null && icicle.hasFileDescriptors()) {
5310            throw new IllegalArgumentException("File descriptors passed in Bundle");
5311        }
5312
5313        ActivityRecord r = null;
5314
5315        final long origId = Binder.clearCallingIdentity();
5316
5317        synchronized (this) {
5318            r = ActivityRecord.isInStackLocked(token);
5319            if (r != null) {
5320                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5321            }
5322        }
5323
5324        if (r != null) {
5325            sendPendingThumbnail(r, null, null, null, false);
5326        }
5327
5328        trimApplications();
5329
5330        Binder.restoreCallingIdentity(origId);
5331    }
5332
5333    @Override
5334    public final void activityDestroyed(IBinder token) {
5335        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5336        synchronized (this) {
5337            ActivityStack stack = ActivityRecord.getStackLocked(token);
5338            if (stack != null) {
5339                stack.activityDestroyedLocked(token);
5340            }
5341        }
5342    }
5343
5344    @Override
5345    public String getCallingPackage(IBinder token) {
5346        synchronized (this) {
5347            ActivityRecord r = getCallingRecordLocked(token);
5348            return r != null ? r.info.packageName : null;
5349        }
5350    }
5351
5352    @Override
5353    public ComponentName getCallingActivity(IBinder token) {
5354        synchronized (this) {
5355            ActivityRecord r = getCallingRecordLocked(token);
5356            return r != null ? r.intent.getComponent() : null;
5357        }
5358    }
5359
5360    private ActivityRecord getCallingRecordLocked(IBinder token) {
5361        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5362        if (r == null) {
5363            return null;
5364        }
5365        return r.resultTo;
5366    }
5367
5368    @Override
5369    public ComponentName getActivityClassForToken(IBinder token) {
5370        synchronized(this) {
5371            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5372            if (r == null) {
5373                return null;
5374            }
5375            return r.intent.getComponent();
5376        }
5377    }
5378
5379    @Override
5380    public String getPackageForToken(IBinder token) {
5381        synchronized(this) {
5382            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5383            if (r == null) {
5384                return null;
5385            }
5386            return r.packageName;
5387        }
5388    }
5389
5390    @Override
5391    public IIntentSender getIntentSender(int type,
5392            String packageName, IBinder token, String resultWho,
5393            int requestCode, Intent[] intents, String[] resolvedTypes,
5394            int flags, Bundle options, int userId) {
5395        enforceNotIsolatedCaller("getIntentSender");
5396        // Refuse possible leaked file descriptors
5397        if (intents != null) {
5398            if (intents.length < 1) {
5399                throw new IllegalArgumentException("Intents array length must be >= 1");
5400            }
5401            for (int i=0; i<intents.length; i++) {
5402                Intent intent = intents[i];
5403                if (intent != null) {
5404                    if (intent.hasFileDescriptors()) {
5405                        throw new IllegalArgumentException("File descriptors passed in Intent");
5406                    }
5407                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5408                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5409                        throw new IllegalArgumentException(
5410                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5411                    }
5412                    intents[i] = new Intent(intent);
5413                }
5414            }
5415            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5416                throw new IllegalArgumentException(
5417                        "Intent array length does not match resolvedTypes length");
5418            }
5419        }
5420        if (options != null) {
5421            if (options.hasFileDescriptors()) {
5422                throw new IllegalArgumentException("File descriptors passed in options");
5423            }
5424        }
5425
5426        synchronized(this) {
5427            int callingUid = Binder.getCallingUid();
5428            int origUserId = userId;
5429            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5430                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5431                    "getIntentSender", null);
5432            if (origUserId == UserHandle.USER_CURRENT) {
5433                // We don't want to evaluate this until the pending intent is
5434                // actually executed.  However, we do want to always do the
5435                // security checking for it above.
5436                userId = UserHandle.USER_CURRENT;
5437            }
5438            try {
5439                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5440                    int uid = AppGlobals.getPackageManager()
5441                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5442                    if (!UserHandle.isSameApp(callingUid, uid)) {
5443                        String msg = "Permission Denial: getIntentSender() from pid="
5444                            + Binder.getCallingPid()
5445                            + ", uid=" + Binder.getCallingUid()
5446                            + ", (need uid=" + uid + ")"
5447                            + " is not allowed to send as package " + packageName;
5448                        Slog.w(TAG, msg);
5449                        throw new SecurityException(msg);
5450                    }
5451                }
5452
5453                return getIntentSenderLocked(type, packageName, callingUid, userId,
5454                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5455
5456            } catch (RemoteException e) {
5457                throw new SecurityException(e);
5458            }
5459        }
5460    }
5461
5462    IIntentSender getIntentSenderLocked(int type, String packageName,
5463            int callingUid, int userId, IBinder token, String resultWho,
5464            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5465            Bundle options) {
5466        if (DEBUG_MU)
5467            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5468        ActivityRecord activity = null;
5469        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5470            activity = ActivityRecord.isInStackLocked(token);
5471            if (activity == null) {
5472                return null;
5473            }
5474            if (activity.finishing) {
5475                return null;
5476            }
5477        }
5478
5479        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5480        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5481        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5482        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5483                |PendingIntent.FLAG_UPDATE_CURRENT);
5484
5485        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5486                type, packageName, activity, resultWho,
5487                requestCode, intents, resolvedTypes, flags, options, userId);
5488        WeakReference<PendingIntentRecord> ref;
5489        ref = mIntentSenderRecords.get(key);
5490        PendingIntentRecord rec = ref != null ? ref.get() : null;
5491        if (rec != null) {
5492            if (!cancelCurrent) {
5493                if (updateCurrent) {
5494                    if (rec.key.requestIntent != null) {
5495                        rec.key.requestIntent.replaceExtras(intents != null ?
5496                                intents[intents.length - 1] : null);
5497                    }
5498                    if (intents != null) {
5499                        intents[intents.length-1] = rec.key.requestIntent;
5500                        rec.key.allIntents = intents;
5501                        rec.key.allResolvedTypes = resolvedTypes;
5502                    } else {
5503                        rec.key.allIntents = null;
5504                        rec.key.allResolvedTypes = null;
5505                    }
5506                }
5507                return rec;
5508            }
5509            rec.canceled = true;
5510            mIntentSenderRecords.remove(key);
5511        }
5512        if (noCreate) {
5513            return rec;
5514        }
5515        rec = new PendingIntentRecord(this, key, callingUid);
5516        mIntentSenderRecords.put(key, rec.ref);
5517        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5518            if (activity.pendingResults == null) {
5519                activity.pendingResults
5520                        = new HashSet<WeakReference<PendingIntentRecord>>();
5521            }
5522            activity.pendingResults.add(rec.ref);
5523        }
5524        return rec;
5525    }
5526
5527    @Override
5528    public void cancelIntentSender(IIntentSender sender) {
5529        if (!(sender instanceof PendingIntentRecord)) {
5530            return;
5531        }
5532        synchronized(this) {
5533            PendingIntentRecord rec = (PendingIntentRecord)sender;
5534            try {
5535                int uid = AppGlobals.getPackageManager()
5536                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5537                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5538                    String msg = "Permission Denial: cancelIntentSender() from pid="
5539                        + Binder.getCallingPid()
5540                        + ", uid=" + Binder.getCallingUid()
5541                        + " is not allowed to cancel packges "
5542                        + rec.key.packageName;
5543                    Slog.w(TAG, msg);
5544                    throw new SecurityException(msg);
5545                }
5546            } catch (RemoteException e) {
5547                throw new SecurityException(e);
5548            }
5549            cancelIntentSenderLocked(rec, true);
5550        }
5551    }
5552
5553    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5554        rec.canceled = true;
5555        mIntentSenderRecords.remove(rec.key);
5556        if (cleanActivity && rec.key.activity != null) {
5557            rec.key.activity.pendingResults.remove(rec.ref);
5558        }
5559    }
5560
5561    @Override
5562    public String getPackageForIntentSender(IIntentSender pendingResult) {
5563        if (!(pendingResult instanceof PendingIntentRecord)) {
5564            return null;
5565        }
5566        try {
5567            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5568            return res.key.packageName;
5569        } catch (ClassCastException e) {
5570        }
5571        return null;
5572    }
5573
5574    @Override
5575    public int getUidForIntentSender(IIntentSender sender) {
5576        if (sender instanceof PendingIntentRecord) {
5577            try {
5578                PendingIntentRecord res = (PendingIntentRecord)sender;
5579                return res.uid;
5580            } catch (ClassCastException e) {
5581            }
5582        }
5583        return -1;
5584    }
5585
5586    @Override
5587    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5588        if (!(pendingResult instanceof PendingIntentRecord)) {
5589            return false;
5590        }
5591        try {
5592            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5593            if (res.key.allIntents == null) {
5594                return false;
5595            }
5596            for (int i=0; i<res.key.allIntents.length; i++) {
5597                Intent intent = res.key.allIntents[i];
5598                if (intent.getPackage() != null && intent.getComponent() != null) {
5599                    return false;
5600                }
5601            }
5602            return true;
5603        } catch (ClassCastException e) {
5604        }
5605        return false;
5606    }
5607
5608    @Override
5609    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5610        if (!(pendingResult instanceof PendingIntentRecord)) {
5611            return false;
5612        }
5613        try {
5614            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5615            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5616                return true;
5617            }
5618            return false;
5619        } catch (ClassCastException e) {
5620        }
5621        return false;
5622    }
5623
5624    @Override
5625    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5626        if (!(pendingResult instanceof PendingIntentRecord)) {
5627            return null;
5628        }
5629        try {
5630            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5631            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5632        } catch (ClassCastException e) {
5633        }
5634        return null;
5635    }
5636
5637    @Override
5638    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5639        if (!(pendingResult instanceof PendingIntentRecord)) {
5640            return null;
5641        }
5642        try {
5643            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5644            Intent intent = res.key.requestIntent;
5645            if (intent != null) {
5646                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5647                        || res.lastTagPrefix.equals(prefix))) {
5648                    return res.lastTag;
5649                }
5650                res.lastTagPrefix = prefix;
5651                StringBuilder sb = new StringBuilder(128);
5652                if (prefix != null) {
5653                    sb.append(prefix);
5654                }
5655                if (intent.getAction() != null) {
5656                    sb.append(intent.getAction());
5657                } else if (intent.getComponent() != null) {
5658                    intent.getComponent().appendShortString(sb);
5659                } else {
5660                    sb.append("?");
5661                }
5662                return res.lastTag = sb.toString();
5663            }
5664        } catch (ClassCastException e) {
5665        }
5666        return null;
5667    }
5668
5669    @Override
5670    public void setProcessLimit(int max) {
5671        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5672                "setProcessLimit()");
5673        synchronized (this) {
5674            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5675            mProcessLimitOverride = max;
5676        }
5677        trimApplications();
5678    }
5679
5680    @Override
5681    public int getProcessLimit() {
5682        synchronized (this) {
5683            return mProcessLimitOverride;
5684        }
5685    }
5686
5687    void foregroundTokenDied(ForegroundToken token) {
5688        synchronized (ActivityManagerService.this) {
5689            synchronized (mPidsSelfLocked) {
5690                ForegroundToken cur
5691                    = mForegroundProcesses.get(token.pid);
5692                if (cur != token) {
5693                    return;
5694                }
5695                mForegroundProcesses.remove(token.pid);
5696                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5697                if (pr == null) {
5698                    return;
5699                }
5700                pr.forcingToForeground = null;
5701                updateProcessForegroundLocked(pr, false, false);
5702            }
5703            updateOomAdjLocked();
5704        }
5705    }
5706
5707    @Override
5708    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5709        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5710                "setProcessForeground()");
5711        synchronized(this) {
5712            boolean changed = false;
5713
5714            synchronized (mPidsSelfLocked) {
5715                ProcessRecord pr = mPidsSelfLocked.get(pid);
5716                if (pr == null && isForeground) {
5717                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5718                    return;
5719                }
5720                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5721                if (oldToken != null) {
5722                    oldToken.token.unlinkToDeath(oldToken, 0);
5723                    mForegroundProcesses.remove(pid);
5724                    if (pr != null) {
5725                        pr.forcingToForeground = null;
5726                    }
5727                    changed = true;
5728                }
5729                if (isForeground && token != null) {
5730                    ForegroundToken newToken = new ForegroundToken() {
5731                        @Override
5732                        public void binderDied() {
5733                            foregroundTokenDied(this);
5734                        }
5735                    };
5736                    newToken.pid = pid;
5737                    newToken.token = token;
5738                    try {
5739                        token.linkToDeath(newToken, 0);
5740                        mForegroundProcesses.put(pid, newToken);
5741                        pr.forcingToForeground = token;
5742                        changed = true;
5743                    } catch (RemoteException e) {
5744                        // If the process died while doing this, we will later
5745                        // do the cleanup with the process death link.
5746                    }
5747                }
5748            }
5749
5750            if (changed) {
5751                updateOomAdjLocked();
5752            }
5753        }
5754    }
5755
5756    // =========================================================
5757    // PERMISSIONS
5758    // =========================================================
5759
5760    static class PermissionController extends IPermissionController.Stub {
5761        ActivityManagerService mActivityManagerService;
5762        PermissionController(ActivityManagerService activityManagerService) {
5763            mActivityManagerService = activityManagerService;
5764        }
5765
5766        @Override
5767        public boolean checkPermission(String permission, int pid, int uid) {
5768            return mActivityManagerService.checkPermission(permission, pid,
5769                    uid) == PackageManager.PERMISSION_GRANTED;
5770        }
5771    }
5772
5773    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5774        @Override
5775        public int checkComponentPermission(String permission, int pid, int uid,
5776                int owningUid, boolean exported) {
5777            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5778                    owningUid, exported);
5779        }
5780
5781        @Override
5782        public Object getAMSLock() {
5783            return ActivityManagerService.this;
5784        }
5785    }
5786
5787    /**
5788     * This can be called with or without the global lock held.
5789     */
5790    int checkComponentPermission(String permission, int pid, int uid,
5791            int owningUid, boolean exported) {
5792        // We might be performing an operation on behalf of an indirect binder
5793        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5794        // client identity accordingly before proceeding.
5795        Identity tlsIdentity = sCallerIdentity.get();
5796        if (tlsIdentity != null) {
5797            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5798                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5799            uid = tlsIdentity.uid;
5800            pid = tlsIdentity.pid;
5801        }
5802
5803        if (pid == MY_PID) {
5804            return PackageManager.PERMISSION_GRANTED;
5805        }
5806
5807        return ActivityManager.checkComponentPermission(permission, uid,
5808                owningUid, exported);
5809    }
5810
5811    /**
5812     * As the only public entry point for permissions checking, this method
5813     * can enforce the semantic that requesting a check on a null global
5814     * permission is automatically denied.  (Internally a null permission
5815     * string is used when calling {@link #checkComponentPermission} in cases
5816     * when only uid-based security is needed.)
5817     *
5818     * This can be called with or without the global lock held.
5819     */
5820    @Override
5821    public int checkPermission(String permission, int pid, int uid) {
5822        if (permission == null) {
5823            return PackageManager.PERMISSION_DENIED;
5824        }
5825        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5826    }
5827
5828    /**
5829     * Binder IPC calls go through the public entry point.
5830     * This can be called with or without the global lock held.
5831     */
5832    int checkCallingPermission(String permission) {
5833        return checkPermission(permission,
5834                Binder.getCallingPid(),
5835                UserHandle.getAppId(Binder.getCallingUid()));
5836    }
5837
5838    /**
5839     * This can be called with or without the global lock held.
5840     */
5841    void enforceCallingPermission(String permission, String func) {
5842        if (checkCallingPermission(permission)
5843                == PackageManager.PERMISSION_GRANTED) {
5844            return;
5845        }
5846
5847        String msg = "Permission Denial: " + func + " from pid="
5848                + Binder.getCallingPid()
5849                + ", uid=" + Binder.getCallingUid()
5850                + " requires " + permission;
5851        Slog.w(TAG, msg);
5852        throw new SecurityException(msg);
5853    }
5854
5855    /**
5856     * Determine if UID is holding permissions required to access {@link Uri} in
5857     * the given {@link ProviderInfo}. Final permission checking is always done
5858     * in {@link ContentProvider}.
5859     */
5860    private final boolean checkHoldingPermissionsLocked(
5861            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) {
5862        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5863                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5864
5865        if (pi.applicationInfo.uid == uid) {
5866            return true;
5867        } else if (!pi.exported) {
5868            return false;
5869        }
5870
5871        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5872        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5873        try {
5874            // check if target holds top-level <provider> permissions
5875            if (!readMet && pi.readPermission != null
5876                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5877                readMet = true;
5878            }
5879            if (!writeMet && pi.writePermission != null
5880                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5881                writeMet = true;
5882            }
5883
5884            // track if unprotected read/write is allowed; any denied
5885            // <path-permission> below removes this ability
5886            boolean allowDefaultRead = pi.readPermission == null;
5887            boolean allowDefaultWrite = pi.writePermission == null;
5888
5889            // check if target holds any <path-permission> that match uri
5890            final PathPermission[] pps = pi.pathPermissions;
5891            if (pps != null) {
5892                final String path = uri.getPath();
5893                int i = pps.length;
5894                while (i > 0 && (!readMet || !writeMet)) {
5895                    i--;
5896                    PathPermission pp = pps[i];
5897                    if (pp.match(path)) {
5898                        if (!readMet) {
5899                            final String pprperm = pp.getReadPermission();
5900                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5901                                    + pprperm + " for " + pp.getPath()
5902                                    + ": match=" + pp.match(path)
5903                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5904                            if (pprperm != null) {
5905                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5906                                    readMet = true;
5907                                } else {
5908                                    allowDefaultRead = false;
5909                                }
5910                            }
5911                        }
5912                        if (!writeMet) {
5913                            final String ppwperm = pp.getWritePermission();
5914                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5915                                    + ppwperm + " for " + pp.getPath()
5916                                    + ": match=" + pp.match(path)
5917                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5918                            if (ppwperm != null) {
5919                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5920                                    writeMet = true;
5921                                } else {
5922                                    allowDefaultWrite = false;
5923                                }
5924                            }
5925                        }
5926                    }
5927                }
5928            }
5929
5930            // grant unprotected <provider> read/write, if not blocked by
5931            // <path-permission> above
5932            if (allowDefaultRead) readMet = true;
5933            if (allowDefaultWrite) writeMet = true;
5934
5935        } catch (RemoteException e) {
5936            return false;
5937        }
5938
5939        return readMet && writeMet;
5940    }
5941
5942    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5943        ProviderInfo pi = null;
5944        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5945        if (cpr != null) {
5946            pi = cpr.info;
5947        } else {
5948            try {
5949                pi = AppGlobals.getPackageManager().resolveContentProvider(
5950                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5951            } catch (RemoteException ex) {
5952            }
5953        }
5954        return pi;
5955    }
5956
5957    private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) {
5958        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5959        if (targetUris != null) {
5960            return targetUris.get(uri);
5961        }
5962        return null;
5963    }
5964
5965    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
5966            String targetPkg, int targetUid, GrantUri uri) {
5967        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5968        if (targetUris == null) {
5969            targetUris = Maps.newArrayMap();
5970            mGrantedUriPermissions.put(targetUid, targetUris);
5971        }
5972
5973        UriPermission perm = targetUris.get(uri);
5974        if (perm == null) {
5975            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5976            targetUris.put(uri, perm);
5977        }
5978
5979        return perm;
5980    }
5981
5982    private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) {
5983        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5984        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
5985                : UriPermission.STRENGTH_OWNED;
5986
5987        // Root gets to do everything.
5988        if (uid == 0) {
5989            return true;
5990        }
5991
5992        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5993        if (perms == null) return false;
5994
5995        // First look for exact match
5996        final UriPermission exactPerm = perms.get(new GrantUri(uri, false));
5997        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
5998            return true;
5999        }
6000
6001        // No exact match, look for prefixes
6002        final int N = perms.size();
6003        for (int i = 0; i < N; i++) {
6004            final UriPermission perm = perms.valueAt(i);
6005            if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri)
6006                    && perm.getStrength(modeFlags) >= minStrength) {
6007                return true;
6008            }
6009        }
6010
6011        return false;
6012    }
6013
6014    @Override
6015    public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) {
6016        enforceNotIsolatedCaller("checkUriPermission");
6017
6018        // Another redirected-binder-call permissions check as in
6019        // {@link checkComponentPermission}.
6020        Identity tlsIdentity = sCallerIdentity.get();
6021        if (tlsIdentity != null) {
6022            uid = tlsIdentity.uid;
6023            pid = tlsIdentity.pid;
6024        }
6025
6026        // Our own process gets to do everything.
6027        if (pid == MY_PID) {
6028            return PackageManager.PERMISSION_GRANTED;
6029        }
6030        synchronized (this) {
6031            return checkUriPermissionLocked(uri, uid, modeFlags)
6032                    ? PackageManager.PERMISSION_GRANTED
6033                    : PackageManager.PERMISSION_DENIED;
6034        }
6035    }
6036
6037    /**
6038     * Check if the targetPkg can be granted permission to access uri by
6039     * the callingUid using the given modeFlags.  Throws a security exception
6040     * if callingUid is not allowed to do this.  Returns the uid of the target
6041     * if the URI permission grant should be performed; returns -1 if it is not
6042     * needed (for example targetPkg already has permission to access the URI).
6043     * If you already know the uid of the target, you can supply it in
6044     * lastTargetUid else set that to -1.
6045     */
6046    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
6047            Uri uri, final int modeFlags, int lastTargetUid) {
6048        if (!Intent.isAccessUriMode(modeFlags)) {
6049            return -1;
6050        }
6051
6052        if (targetPkg != null) {
6053            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6054                    "Checking grant " + targetPkg + " permission to " + uri);
6055        }
6056
6057        final IPackageManager pm = AppGlobals.getPackageManager();
6058
6059        // If this is not a content: uri, we can't do anything with it.
6060        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6061            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6062                    "Can't grant URI permission for non-content URI: " + uri);
6063            return -1;
6064        }
6065
6066        final String authority = uri.getAuthority();
6067        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6068        if (pi == null) {
6069            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6070            return -1;
6071        }
6072
6073        int targetUid = lastTargetUid;
6074        if (targetUid < 0 && targetPkg != null) {
6075            try {
6076                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6077                if (targetUid < 0) {
6078                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6079                            "Can't grant URI permission no uid for: " + targetPkg);
6080                    return -1;
6081                }
6082            } catch (RemoteException ex) {
6083                return -1;
6084            }
6085        }
6086
6087        if (targetUid >= 0) {
6088            // First...  does the target actually need this permission?
6089            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6090                // No need to grant the target this permission.
6091                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6092                        "Target " + targetPkg + " already has full permission to " + uri);
6093                return -1;
6094            }
6095        } else {
6096            // First...  there is no target package, so can anyone access it?
6097            boolean allowed = pi.exported;
6098            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6099                if (pi.readPermission != null) {
6100                    allowed = false;
6101                }
6102            }
6103            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6104                if (pi.writePermission != null) {
6105                    allowed = false;
6106                }
6107            }
6108            if (allowed) {
6109                return -1;
6110            }
6111        }
6112
6113        // Second...  is the provider allowing granting of URI permissions?
6114        if (!pi.grantUriPermissions) {
6115            throw new SecurityException("Provider " + pi.packageName
6116                    + "/" + pi.name
6117                    + " does not allow granting of Uri permissions (uri "
6118                    + uri + ")");
6119        }
6120        if (pi.uriPermissionPatterns != null) {
6121            final int N = pi.uriPermissionPatterns.length;
6122            boolean allowed = false;
6123            for (int i=0; i<N; i++) {
6124                if (pi.uriPermissionPatterns[i] != null
6125                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6126                    allowed = true;
6127                    break;
6128                }
6129            }
6130            if (!allowed) {
6131                throw new SecurityException("Provider " + pi.packageName
6132                        + "/" + pi.name
6133                        + " does not allow granting of permission to path of Uri "
6134                        + uri);
6135            }
6136        }
6137
6138        // Third...  does the caller itself have permission to access
6139        // this uri?
6140        if (callingUid != Process.myUid()) {
6141            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6142                // Require they hold a strong enough Uri permission
6143                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6144                    throw new SecurityException("Uid " + callingUid
6145                            + " does not have permission to uri " + uri);
6146                }
6147            }
6148        }
6149
6150        return targetUid;
6151    }
6152
6153    @Override
6154    public int checkGrantUriPermission(int callingUid, String targetPkg,
6155            Uri uri, final int modeFlags) {
6156        enforceNotIsolatedCaller("checkGrantUriPermission");
6157        synchronized(this) {
6158            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6159        }
6160    }
6161
6162    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri,
6163            final int modeFlags, UriPermissionOwner owner) {
6164        if (!Intent.isAccessUriMode(modeFlags)) {
6165            return;
6166        }
6167
6168        // So here we are: the caller has the assumed permission
6169        // to the uri, and the target doesn't.  Let's now give this to
6170        // the target.
6171
6172        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6173                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6174
6175        final String authority = uri.getAuthority();
6176        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6177        if (pi == null) {
6178            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6179            return;
6180        }
6181
6182        final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
6183        final UriPermission perm = findOrCreateUriPermissionLocked(
6184                pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix));
6185        perm.grantModes(modeFlags, owner);
6186    }
6187
6188    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6189            final int modeFlags, UriPermissionOwner owner) {
6190        if (targetPkg == null) {
6191            throw new NullPointerException("targetPkg");
6192        }
6193
6194        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6195        if (targetUid < 0) {
6196            return;
6197        }
6198
6199        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6200    }
6201
6202    static class NeededUriGrants extends ArrayList<Uri> {
6203        final String targetPkg;
6204        final int targetUid;
6205        final int flags;
6206
6207        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6208            this.targetPkg = targetPkg;
6209            this.targetUid = targetUid;
6210            this.flags = flags;
6211        }
6212    }
6213
6214    /**
6215     * Like checkGrantUriPermissionLocked, but takes an Intent.
6216     */
6217    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6218            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6219        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6220                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6221                + " clip=" + (intent != null ? intent.getClipData() : null)
6222                + " from " + intent + "; flags=0x"
6223                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6224
6225        if (targetPkg == null) {
6226            throw new NullPointerException("targetPkg");
6227        }
6228
6229        if (intent == null) {
6230            return null;
6231        }
6232        Uri data = intent.getData();
6233        ClipData clip = intent.getClipData();
6234        if (data == null && clip == null) {
6235            return null;
6236        }
6237
6238        if (data != null) {
6239            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6240                mode, needed != null ? needed.targetUid : -1);
6241            if (targetUid > 0) {
6242                if (needed == null) {
6243                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6244                }
6245                needed.add(data);
6246            }
6247        }
6248        if (clip != null) {
6249            for (int i=0; i<clip.getItemCount(); i++) {
6250                Uri uri = clip.getItemAt(i).getUri();
6251                if (uri != null) {
6252                    int targetUid = -1;
6253                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6254                            mode, needed != null ? needed.targetUid : -1);
6255                    if (targetUid > 0) {
6256                        if (needed == null) {
6257                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6258                        }
6259                        needed.add(uri);
6260                    }
6261                } else {
6262                    Intent clipIntent = clip.getItemAt(i).getIntent();
6263                    if (clipIntent != null) {
6264                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6265                                callingUid, targetPkg, clipIntent, mode, needed);
6266                        if (newNeeded != null) {
6267                            needed = newNeeded;
6268                        }
6269                    }
6270                }
6271            }
6272        }
6273
6274        return needed;
6275    }
6276
6277    /**
6278     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6279     */
6280    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6281            UriPermissionOwner owner) {
6282        if (needed != null) {
6283            for (int i=0; i<needed.size(); i++) {
6284                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6285                        needed.get(i), needed.flags, owner);
6286            }
6287        }
6288    }
6289
6290    void grantUriPermissionFromIntentLocked(int callingUid,
6291            String targetPkg, Intent intent, UriPermissionOwner owner) {
6292        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6293                intent, intent != null ? intent.getFlags() : 0, null);
6294        if (needed == null) {
6295            return;
6296        }
6297
6298        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6299    }
6300
6301    @Override
6302    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6303            Uri uri, final int modeFlags) {
6304        enforceNotIsolatedCaller("grantUriPermission");
6305        synchronized(this) {
6306            final ProcessRecord r = getRecordForAppLocked(caller);
6307            if (r == null) {
6308                throw new SecurityException("Unable to find app for caller "
6309                        + caller
6310                        + " when granting permission to uri " + uri);
6311            }
6312            if (targetPkg == null) {
6313                throw new IllegalArgumentException("null target");
6314            }
6315            if (uri == null) {
6316                throw new IllegalArgumentException("null uri");
6317            }
6318
6319            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6320                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6321                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6322                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6323
6324            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null);
6325        }
6326    }
6327
6328    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6329        if (perm.modeFlags == 0) {
6330            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6331                    perm.targetUid);
6332            if (perms != null) {
6333                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6334                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6335
6336                perms.remove(perm.uri);
6337                if (perms.isEmpty()) {
6338                    mGrantedUriPermissions.remove(perm.targetUid);
6339                }
6340            }
6341        }
6342    }
6343
6344    private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) {
6345        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6346
6347        final IPackageManager pm = AppGlobals.getPackageManager();
6348        final String authority = uri.getAuthority();
6349        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6350        if (pi == null) {
6351            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6352            return;
6353        }
6354
6355        // Does the caller have this permission on the URI?
6356        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6357            // Right now, if you are not the original owner of the permission,
6358            // you are not allowed to revoke it.
6359            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6360                throw new SecurityException("Uid " + callingUid
6361                        + " does not have permission to uri " + uri);
6362            //}
6363        }
6364
6365        boolean persistChanged = false;
6366
6367        // Go through all of the permissions and remove any that match.
6368        int N = mGrantedUriPermissions.size();
6369        for (int i = 0; i < N; i++) {
6370            final int targetUid = mGrantedUriPermissions.keyAt(i);
6371            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6372
6373            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6374                final UriPermission perm = it.next();
6375                if (perm.uri.uri.isPathPrefixMatch(uri)) {
6376                    if (DEBUG_URI_PERMISSION)
6377                        Slog.v(TAG,
6378                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6379                    persistChanged |= perm.revokeModes(
6380                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6381                    if (perm.modeFlags == 0) {
6382                        it.remove();
6383                    }
6384                }
6385            }
6386
6387            if (perms.isEmpty()) {
6388                mGrantedUriPermissions.remove(targetUid);
6389                N--;
6390                i--;
6391            }
6392        }
6393
6394        if (persistChanged) {
6395            schedulePersistUriGrants();
6396        }
6397    }
6398
6399    @Override
6400    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6401            final int modeFlags) {
6402        enforceNotIsolatedCaller("revokeUriPermission");
6403        synchronized(this) {
6404            final ProcessRecord r = getRecordForAppLocked(caller);
6405            if (r == null) {
6406                throw new SecurityException("Unable to find app for caller "
6407                        + caller
6408                        + " when revoking permission to uri " + uri);
6409            }
6410            if (uri == null) {
6411                Slog.w(TAG, "revokeUriPermission: null uri");
6412                return;
6413            }
6414
6415            if (!Intent.isAccessUriMode(modeFlags)) {
6416                return;
6417            }
6418
6419            final IPackageManager pm = AppGlobals.getPackageManager();
6420            final String authority = uri.getAuthority();
6421            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6422            if (pi == null) {
6423                Slog.w(TAG, "No content provider found for permission revoke: "
6424                        + uri.toSafeString());
6425                return;
6426            }
6427
6428            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6429        }
6430    }
6431
6432    /**
6433     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6434     * given package.
6435     *
6436     * @param packageName Package name to match, or {@code null} to apply to all
6437     *            packages.
6438     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6439     *            to all users.
6440     * @param persistable If persistable grants should be removed.
6441     */
6442    private void removeUriPermissionsForPackageLocked(
6443            String packageName, int userHandle, boolean persistable) {
6444        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6445            throw new IllegalArgumentException("Must narrow by either package or user");
6446        }
6447
6448        boolean persistChanged = false;
6449
6450        int N = mGrantedUriPermissions.size();
6451        for (int i = 0; i < N; i++) {
6452            final int targetUid = mGrantedUriPermissions.keyAt(i);
6453            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6454
6455            // Only inspect grants matching user
6456            if (userHandle == UserHandle.USER_ALL
6457                    || userHandle == UserHandle.getUserId(targetUid)) {
6458                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6459                    final UriPermission perm = it.next();
6460
6461                    // Only inspect grants matching package
6462                    if (packageName == null || perm.sourcePkg.equals(packageName)
6463                            || perm.targetPkg.equals(packageName)) {
6464                        persistChanged |= perm.revokeModes(
6465                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6466
6467                        // Only remove when no modes remain; any persisted grants
6468                        // will keep this alive.
6469                        if (perm.modeFlags == 0) {
6470                            it.remove();
6471                        }
6472                    }
6473                }
6474
6475                if (perms.isEmpty()) {
6476                    mGrantedUriPermissions.remove(targetUid);
6477                    N--;
6478                    i--;
6479                }
6480            }
6481        }
6482
6483        if (persistChanged) {
6484            schedulePersistUriGrants();
6485        }
6486    }
6487
6488    @Override
6489    public IBinder newUriPermissionOwner(String name) {
6490        enforceNotIsolatedCaller("newUriPermissionOwner");
6491        synchronized(this) {
6492            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6493            return owner.getExternalTokenLocked();
6494        }
6495    }
6496
6497    @Override
6498    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6499            Uri uri, final int modeFlags) {
6500        synchronized(this) {
6501            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6502            if (owner == null) {
6503                throw new IllegalArgumentException("Unknown owner: " + token);
6504            }
6505            if (fromUid != Binder.getCallingUid()) {
6506                if (Binder.getCallingUid() != Process.myUid()) {
6507                    // Only system code can grant URI permissions on behalf
6508                    // of other users.
6509                    throw new SecurityException("nice try");
6510                }
6511            }
6512            if (targetPkg == null) {
6513                throw new IllegalArgumentException("null target");
6514            }
6515            if (uri == null) {
6516                throw new IllegalArgumentException("null uri");
6517            }
6518
6519            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6520        }
6521    }
6522
6523    @Override
6524    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6525        synchronized(this) {
6526            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6527            if (owner == null) {
6528                throw new IllegalArgumentException("Unknown owner: " + token);
6529            }
6530
6531            if (uri == null) {
6532                owner.removeUriPermissionsLocked(mode);
6533            } else {
6534                owner.removeUriPermissionLocked(uri, mode);
6535            }
6536        }
6537    }
6538
6539    private void schedulePersistUriGrants() {
6540        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6541            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6542                    10 * DateUtils.SECOND_IN_MILLIS);
6543        }
6544    }
6545
6546    private void writeGrantedUriPermissions() {
6547        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6548
6549        // Snapshot permissions so we can persist without lock
6550        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6551        synchronized (this) {
6552            final int size = mGrantedUriPermissions.size();
6553            for (int i = 0; i < size; i++) {
6554                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6555                for (UriPermission perm : perms.values()) {
6556                    if (perm.persistedModeFlags != 0) {
6557                        persist.add(perm.snapshot());
6558                    }
6559                }
6560            }
6561        }
6562
6563        FileOutputStream fos = null;
6564        try {
6565            fos = mGrantFile.startWrite();
6566
6567            XmlSerializer out = new FastXmlSerializer();
6568            out.setOutput(fos, "utf-8");
6569            out.startDocument(null, true);
6570            out.startTag(null, TAG_URI_GRANTS);
6571            for (UriPermission.Snapshot perm : persist) {
6572                out.startTag(null, TAG_URI_GRANT);
6573                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6574                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6575                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6576                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6577                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6578                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6579                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6580                out.endTag(null, TAG_URI_GRANT);
6581            }
6582            out.endTag(null, TAG_URI_GRANTS);
6583            out.endDocument();
6584
6585            mGrantFile.finishWrite(fos);
6586        } catch (IOException e) {
6587            if (fos != null) {
6588                mGrantFile.failWrite(fos);
6589            }
6590        }
6591    }
6592
6593    private void readGrantedUriPermissionsLocked() {
6594        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6595
6596        final long now = System.currentTimeMillis();
6597
6598        FileInputStream fis = null;
6599        try {
6600            fis = mGrantFile.openRead();
6601            final XmlPullParser in = Xml.newPullParser();
6602            in.setInput(fis, null);
6603
6604            int type;
6605            while ((type = in.next()) != END_DOCUMENT) {
6606                final String tag = in.getName();
6607                if (type == START_TAG) {
6608                    if (TAG_URI_GRANT.equals(tag)) {
6609                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6610                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6611                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6612                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6613                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6614                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6615                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6616
6617                        // Sanity check that provider still belongs to source package
6618                        final ProviderInfo pi = getProviderInfoLocked(
6619                                uri.getAuthority(), userHandle);
6620                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6621                            int targetUid = -1;
6622                            try {
6623                                targetUid = AppGlobals.getPackageManager()
6624                                        .getPackageUid(targetPkg, userHandle);
6625                            } catch (RemoteException e) {
6626                            }
6627                            if (targetUid != -1) {
6628                                final UriPermission perm = findOrCreateUriPermissionLocked(
6629                                        sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix));
6630                                perm.initPersistedModes(modeFlags, createdTime);
6631                            }
6632                        } else {
6633                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6634                                    + " but instead found " + pi);
6635                        }
6636                    }
6637                }
6638            }
6639        } catch (FileNotFoundException e) {
6640            // Missing grants is okay
6641        } catch (IOException e) {
6642            Log.wtf(TAG, "Failed reading Uri grants", e);
6643        } catch (XmlPullParserException e) {
6644            Log.wtf(TAG, "Failed reading Uri grants", e);
6645        } finally {
6646            IoUtils.closeQuietly(fis);
6647        }
6648    }
6649
6650    @Override
6651    public void takePersistableUriPermission(Uri uri, final int modeFlags) {
6652        enforceNotIsolatedCaller("takePersistableUriPermission");
6653
6654        Preconditions.checkFlagsArgument(modeFlags,
6655                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6656
6657        synchronized (this) {
6658            final int callingUid = Binder.getCallingUid();
6659            boolean persistChanged = false;
6660
6661            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6662            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6663
6664            final boolean exactValid = (exactPerm != null)
6665                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6666            final boolean prefixValid = (prefixPerm != null)
6667                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6668
6669            if (!(exactValid || prefixValid)) {
6670                throw new SecurityException("No persistable permission grants found for UID "
6671                        + callingUid + " and Uri " + uri.toSafeString());
6672            }
6673
6674            if (exactValid) {
6675                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6676            }
6677            if (prefixValid) {
6678                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6679            }
6680
6681            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6682
6683            if (persistChanged) {
6684                schedulePersistUriGrants();
6685            }
6686        }
6687    }
6688
6689    @Override
6690    public void releasePersistableUriPermission(Uri uri, final int modeFlags) {
6691        enforceNotIsolatedCaller("releasePersistableUriPermission");
6692
6693        Preconditions.checkFlagsArgument(modeFlags,
6694                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6695
6696        synchronized (this) {
6697            final int callingUid = Binder.getCallingUid();
6698            boolean persistChanged = false;
6699
6700            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6701            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6702            if (exactPerm == null && prefixPerm == null) {
6703                throw new SecurityException("No permission grants found for UID " + callingUid
6704                        + " and Uri " + uri.toSafeString());
6705            }
6706
6707            if (exactPerm != null) {
6708                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6709                removeUriPermissionIfNeededLocked(exactPerm);
6710            }
6711            if (prefixPerm != null) {
6712                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6713                removeUriPermissionIfNeededLocked(prefixPerm);
6714            }
6715
6716            if (persistChanged) {
6717                schedulePersistUriGrants();
6718            }
6719        }
6720    }
6721
6722    /**
6723     * Prune any older {@link UriPermission} for the given UID until outstanding
6724     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6725     *
6726     * @return if any mutations occured that require persisting.
6727     */
6728    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6729        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6730        if (perms == null) return false;
6731        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6732
6733        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6734        for (UriPermission perm : perms.values()) {
6735            if (perm.persistedModeFlags != 0) {
6736                persisted.add(perm);
6737            }
6738        }
6739
6740        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6741        if (trimCount <= 0) return false;
6742
6743        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6744        for (int i = 0; i < trimCount; i++) {
6745            final UriPermission perm = persisted.get(i);
6746
6747            if (DEBUG_URI_PERMISSION) {
6748                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6749            }
6750
6751            perm.releasePersistableModes(~0);
6752            removeUriPermissionIfNeededLocked(perm);
6753        }
6754
6755        return true;
6756    }
6757
6758    @Override
6759    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6760            String packageName, boolean incoming) {
6761        enforceNotIsolatedCaller("getPersistedUriPermissions");
6762        Preconditions.checkNotNull(packageName, "packageName");
6763
6764        final int callingUid = Binder.getCallingUid();
6765        final IPackageManager pm = AppGlobals.getPackageManager();
6766        try {
6767            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6768            if (packageUid != callingUid) {
6769                throw new SecurityException(
6770                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6771            }
6772        } catch (RemoteException e) {
6773            throw new SecurityException("Failed to verify package name ownership");
6774        }
6775
6776        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6777        synchronized (this) {
6778            if (incoming) {
6779                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6780                        callingUid);
6781                if (perms == null) {
6782                    Slog.w(TAG, "No permission grants found for " + packageName);
6783                } else {
6784                    for (UriPermission perm : perms.values()) {
6785                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6786                            result.add(perm.buildPersistedPublicApiObject());
6787                        }
6788                    }
6789                }
6790            } else {
6791                final int size = mGrantedUriPermissions.size();
6792                for (int i = 0; i < size; i++) {
6793                    final ArrayMap<GrantUri, UriPermission> perms =
6794                            mGrantedUriPermissions.valueAt(i);
6795                    for (UriPermission perm : perms.values()) {
6796                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6797                            result.add(perm.buildPersistedPublicApiObject());
6798                        }
6799                    }
6800                }
6801            }
6802        }
6803        return new ParceledListSlice<android.content.UriPermission>(result);
6804    }
6805
6806    @Override
6807    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6808        synchronized (this) {
6809            ProcessRecord app =
6810                who != null ? getRecordForAppLocked(who) : null;
6811            if (app == null) return;
6812
6813            Message msg = Message.obtain();
6814            msg.what = WAIT_FOR_DEBUGGER_MSG;
6815            msg.obj = app;
6816            msg.arg1 = waiting ? 1 : 0;
6817            mHandler.sendMessage(msg);
6818        }
6819    }
6820
6821    @Override
6822    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6823        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6824        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6825        outInfo.availMem = Process.getFreeMemory();
6826        outInfo.totalMem = Process.getTotalMemory();
6827        outInfo.threshold = homeAppMem;
6828        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6829        outInfo.hiddenAppThreshold = cachedAppMem;
6830        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6831                ProcessList.SERVICE_ADJ);
6832        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6833                ProcessList.VISIBLE_APP_ADJ);
6834        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6835                ProcessList.FOREGROUND_APP_ADJ);
6836    }
6837
6838    // =========================================================
6839    // TASK MANAGEMENT
6840    // =========================================================
6841
6842    @Override
6843    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6844                         IThumbnailReceiver receiver) {
6845        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6846
6847        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6848        ActivityRecord topRecord = null;
6849
6850        synchronized(this) {
6851            if (localLOGV) Slog.v(
6852                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6853                + ", receiver=" + receiver);
6854
6855            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6856                    != PackageManager.PERMISSION_GRANTED) {
6857                if (receiver != null) {
6858                    // If the caller wants to wait for pending thumbnails,
6859                    // it ain't gonna get them.
6860                    try {
6861                        receiver.finished();
6862                    } catch (RemoteException ex) {
6863                    }
6864                }
6865                String msg = "Permission Denial: getTasks() from pid="
6866                        + Binder.getCallingPid()
6867                        + ", uid=" + Binder.getCallingUid()
6868                        + " requires " + android.Manifest.permission.GET_TASKS;
6869                Slog.w(TAG, msg);
6870                throw new SecurityException(msg);
6871            }
6872
6873            // TODO: Improve with MRU list from all ActivityStacks.
6874            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6875
6876            if (!pending.pendingRecords.isEmpty()) {
6877                mPendingThumbnails.add(pending);
6878            }
6879        }
6880
6881        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6882
6883        if (topRecord != null) {
6884            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6885            try {
6886                IApplicationThread topThumbnail = topRecord.app.thread;
6887                topThumbnail.requestThumbnail(topRecord.appToken);
6888            } catch (Exception e) {
6889                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6890                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6891            }
6892        }
6893
6894        if (pending.pendingRecords.isEmpty() && receiver != null) {
6895            // In this case all thumbnails were available and the client
6896            // is being asked to be told when the remaining ones come in...
6897            // which is unusually, since the top-most currently running
6898            // activity should never have a canned thumbnail!  Oh well.
6899            try {
6900                receiver.finished();
6901            } catch (RemoteException ex) {
6902            }
6903        }
6904
6905        return list;
6906    }
6907
6908    TaskRecord getMostRecentTask() {
6909        return mRecentTasks.get(0);
6910    }
6911
6912    @Override
6913    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6914            int flags, int userId) {
6915        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6916                false, true, "getRecentTasks", null);
6917
6918        synchronized (this) {
6919            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6920                    "getRecentTasks()");
6921            final boolean detailed = checkCallingPermission(
6922                    android.Manifest.permission.GET_DETAILED_TASKS)
6923                    == PackageManager.PERMISSION_GRANTED;
6924
6925            IPackageManager pm = AppGlobals.getPackageManager();
6926
6927            final int N = mRecentTasks.size();
6928            ArrayList<ActivityManager.RecentTaskInfo> res
6929                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6930                            maxNum < N ? maxNum : N);
6931
6932            final Set<Integer> includedUsers;
6933            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
6934                includedUsers = getProfileIdsLocked(userId);
6935            } else {
6936                includedUsers = new HashSet<Integer>();
6937            }
6938            includedUsers.add(Integer.valueOf(userId));
6939            for (int i=0; i<N && maxNum > 0; i++) {
6940                TaskRecord tr = mRecentTasks.get(i);
6941                // Only add calling user or related users recent tasks
6942                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
6943
6944                // Return the entry if desired by the caller.  We always return
6945                // the first entry, because callers always expect this to be the
6946                // foreground app.  We may filter others if the caller has
6947                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6948                // we should exclude the entry.
6949
6950                if (i == 0
6951                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6952                        || (tr.intent == null)
6953                        || ((tr.intent.getFlags()
6954                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6955                    ActivityManager.RecentTaskInfo rti
6956                            = new ActivityManager.RecentTaskInfo();
6957                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6958                    rti.persistentId = tr.taskId;
6959                    rti.baseIntent = new Intent(
6960                            tr.intent != null ? tr.intent : tr.affinityIntent);
6961                    if (!detailed) {
6962                        rti.baseIntent.replaceExtras((Bundle)null);
6963                    }
6964                    rti.origActivity = tr.origActivity;
6965                    rti.description = tr.lastDescription;
6966                    rti.stackId = tr.stack.mStackId;
6967                    rti.userId = tr.userId;
6968
6969                    // Traverse upwards looking for any break between main task activities and
6970                    // utility activities.
6971                    final ArrayList<ActivityRecord> activities = tr.mActivities;
6972                    int activityNdx;
6973                    final int numActivities = activities.size();
6974                    for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
6975                            ++activityNdx) {
6976                        final ActivityRecord r = activities.get(activityNdx);
6977                        if (r.intent != null &&
6978                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
6979                                        != 0) {
6980                            break;
6981                        }
6982                    }
6983                    // Traverse downwards starting below break looking for set label and icon.
6984                    for (--activityNdx; activityNdx >= 0; --activityNdx) {
6985                        final ActivityRecord r = activities.get(activityNdx);
6986                        if (r.activityLabel != null || r.activityIcon != null) {
6987                            rti.activityLabel = r.activityLabel;
6988                            rti.activityIcon = r.activityIcon;
6989                            break;
6990                        }
6991                    }
6992
6993                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6994                        // Check whether this activity is currently available.
6995                        try {
6996                            if (rti.origActivity != null) {
6997                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6998                                        == null) {
6999                                    continue;
7000                                }
7001                            } else if (rti.baseIntent != null) {
7002                                if (pm.queryIntentActivities(rti.baseIntent,
7003                                        null, 0, userId) == null) {
7004                                    continue;
7005                                }
7006                            }
7007                        } catch (RemoteException e) {
7008                            // Will never happen.
7009                        }
7010                    }
7011
7012                    res.add(rti);
7013                    maxNum--;
7014                }
7015            }
7016            return res;
7017        }
7018    }
7019
7020    private TaskRecord recentTaskForIdLocked(int id) {
7021        final int N = mRecentTasks.size();
7022            for (int i=0; i<N; i++) {
7023                TaskRecord tr = mRecentTasks.get(i);
7024                if (tr.taskId == id) {
7025                    return tr;
7026                }
7027            }
7028            return null;
7029    }
7030
7031    @Override
7032    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7033        synchronized (this) {
7034            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7035                    "getTaskThumbnails()");
7036            TaskRecord tr = recentTaskForIdLocked(id);
7037            if (tr != null) {
7038                return tr.getTaskThumbnailsLocked();
7039            }
7040        }
7041        return null;
7042    }
7043
7044    @Override
7045    public Bitmap getTaskTopThumbnail(int id) {
7046        synchronized (this) {
7047            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7048                    "getTaskTopThumbnail()");
7049            TaskRecord tr = recentTaskForIdLocked(id);
7050            if (tr != null) {
7051                return tr.getTaskTopThumbnailLocked();
7052            }
7053        }
7054        return null;
7055    }
7056
7057    @Override
7058    public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel,
7059            Bitmap activityIcon) {
7060        synchronized (this) {
7061            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7062            if (r != null) {
7063                r.activityLabel = activityLabel.toString();
7064                r.activityIcon = activityIcon;
7065            }
7066        }
7067    }
7068
7069    @Override
7070    public boolean removeSubTask(int taskId, int subTaskIndex) {
7071        synchronized (this) {
7072            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7073                    "removeSubTask()");
7074            long ident = Binder.clearCallingIdentity();
7075            try {
7076                TaskRecord tr = recentTaskForIdLocked(taskId);
7077                if (tr != null) {
7078                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7079                }
7080                return false;
7081            } finally {
7082                Binder.restoreCallingIdentity(ident);
7083            }
7084        }
7085    }
7086
7087    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7088        if (!pr.killedByAm) {
7089            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7090            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7091                    pr.processName, pr.setAdj, reason);
7092            pr.killedByAm = true;
7093            Process.killProcessQuiet(pr.pid);
7094        }
7095    }
7096
7097    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7098        tr.disposeThumbnail();
7099        mRecentTasks.remove(tr);
7100        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7101        Intent baseIntent = new Intent(
7102                tr.intent != null ? tr.intent : tr.affinityIntent);
7103        ComponentName component = baseIntent.getComponent();
7104        if (component == null) {
7105            Slog.w(TAG, "Now component for base intent of task: " + tr);
7106            return;
7107        }
7108
7109        // Find any running services associated with this app.
7110        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7111
7112        if (killProcesses) {
7113            // Find any running processes associated with this app.
7114            final String pkg = component.getPackageName();
7115            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7116            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7117            for (int i=0; i<pmap.size(); i++) {
7118                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7119                for (int j=0; j<uids.size(); j++) {
7120                    ProcessRecord proc = uids.valueAt(j);
7121                    if (proc.userId != tr.userId) {
7122                        continue;
7123                    }
7124                    if (!proc.pkgList.containsKey(pkg)) {
7125                        continue;
7126                    }
7127                    procs.add(proc);
7128                }
7129            }
7130
7131            // Kill the running processes.
7132            for (int i=0; i<procs.size(); i++) {
7133                ProcessRecord pr = procs.get(i);
7134                if (pr == mHomeProcess) {
7135                    // Don't kill the home process along with tasks from the same package.
7136                    continue;
7137                }
7138                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7139                    killUnneededProcessLocked(pr, "remove task");
7140                } else {
7141                    pr.waitingToKill = "remove task";
7142                }
7143            }
7144        }
7145    }
7146
7147    @Override
7148    public boolean removeTask(int taskId, int flags) {
7149        synchronized (this) {
7150            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7151                    "removeTask()");
7152            long ident = Binder.clearCallingIdentity();
7153            try {
7154                TaskRecord tr = recentTaskForIdLocked(taskId);
7155                if (tr != null) {
7156                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
7157                    if (r != null) {
7158                        cleanUpRemovedTaskLocked(tr, flags);
7159                        return true;
7160                    }
7161                    if (tr.mActivities.size() == 0) {
7162                        // Caller is just removing a recent task that is
7163                        // not actively running.  That is easy!
7164                        cleanUpRemovedTaskLocked(tr, flags);
7165                        return true;
7166                    }
7167                    Slog.w(TAG, "removeTask: task " + taskId
7168                            + " does not have activities to remove, "
7169                            + " but numActivities=" + tr.numActivities
7170                            + ": " + tr);
7171                }
7172            } finally {
7173                Binder.restoreCallingIdentity(ident);
7174            }
7175        }
7176        return false;
7177    }
7178
7179    /**
7180     * TODO: Add mController hook
7181     */
7182    @Override
7183    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7184        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7185                "moveTaskToFront()");
7186
7187        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7188        synchronized(this) {
7189            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7190                    Binder.getCallingUid(), "Task to front")) {
7191                ActivityOptions.abort(options);
7192                return;
7193            }
7194            final long origId = Binder.clearCallingIdentity();
7195            try {
7196                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7197                if (task == null) {
7198                    return;
7199                }
7200                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7201                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7202                    return;
7203                }
7204                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7205            } finally {
7206                Binder.restoreCallingIdentity(origId);
7207            }
7208            ActivityOptions.abort(options);
7209        }
7210    }
7211
7212    @Override
7213    public void moveTaskToBack(int taskId) {
7214        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7215                "moveTaskToBack()");
7216
7217        synchronized(this) {
7218            TaskRecord tr = recentTaskForIdLocked(taskId);
7219            if (tr != null) {
7220                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7221                ActivityStack stack = tr.stack;
7222                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7223                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7224                            Binder.getCallingUid(), "Task to back")) {
7225                        return;
7226                    }
7227                }
7228                final long origId = Binder.clearCallingIdentity();
7229                try {
7230                    stack.moveTaskToBackLocked(taskId, null);
7231                } finally {
7232                    Binder.restoreCallingIdentity(origId);
7233                }
7234            }
7235        }
7236    }
7237
7238    /**
7239     * Moves an activity, and all of the other activities within the same task, to the bottom
7240     * of the history stack.  The activity's order within the task is unchanged.
7241     *
7242     * @param token A reference to the activity we wish to move
7243     * @param nonRoot If false then this only works if the activity is the root
7244     *                of a task; if true it will work for any activity in a task.
7245     * @return Returns true if the move completed, false if not.
7246     */
7247    @Override
7248    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7249        enforceNotIsolatedCaller("moveActivityTaskToBack");
7250        synchronized(this) {
7251            final long origId = Binder.clearCallingIdentity();
7252            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7253            if (taskId >= 0) {
7254                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7255            }
7256            Binder.restoreCallingIdentity(origId);
7257        }
7258        return false;
7259    }
7260
7261    @Override
7262    public void moveTaskBackwards(int task) {
7263        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7264                "moveTaskBackwards()");
7265
7266        synchronized(this) {
7267            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7268                    Binder.getCallingUid(), "Task backwards")) {
7269                return;
7270            }
7271            final long origId = Binder.clearCallingIdentity();
7272            moveTaskBackwardsLocked(task);
7273            Binder.restoreCallingIdentity(origId);
7274        }
7275    }
7276
7277    private final void moveTaskBackwardsLocked(int task) {
7278        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7279    }
7280
7281    @Override
7282    public IBinder getHomeActivityToken() throws RemoteException {
7283        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7284                "getHomeActivityToken()");
7285        synchronized (this) {
7286            return mStackSupervisor.getHomeActivityToken();
7287        }
7288    }
7289
7290    @Override
7291    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7292            IActivityContainerCallback callback) throws RemoteException {
7293        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7294                "createActivityContainer()");
7295        synchronized (this) {
7296            if (parentActivityToken == null) {
7297                throw new IllegalArgumentException("parent token must not be null");
7298            }
7299            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7300            if (r == null) {
7301                return null;
7302            }
7303            if (callback == null) {
7304                throw new IllegalArgumentException("callback must not be null");
7305            }
7306            return mStackSupervisor.createActivityContainer(r, callback);
7307        }
7308    }
7309
7310    @Override
7311    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7312        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7313                "deleteActivityContainer()");
7314        synchronized (this) {
7315            mStackSupervisor.deleteActivityContainer(container);
7316        }
7317    }
7318
7319    @Override
7320    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7321            throws RemoteException {
7322        synchronized (this) {
7323            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7324            if (stack != null) {
7325                return stack.mActivityContainer;
7326            }
7327            return null;
7328        }
7329    }
7330
7331    @Override
7332    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7333        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7334                "moveTaskToStack()");
7335        if (stackId == HOME_STACK_ID) {
7336            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7337                    new RuntimeException("here").fillInStackTrace());
7338        }
7339        synchronized (this) {
7340            long ident = Binder.clearCallingIdentity();
7341            try {
7342                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7343                        + stackId + " toTop=" + toTop);
7344                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7345            } finally {
7346                Binder.restoreCallingIdentity(ident);
7347            }
7348        }
7349    }
7350
7351    @Override
7352    public void resizeStack(int stackBoxId, Rect bounds) {
7353        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7354                "resizeStackBox()");
7355        long ident = Binder.clearCallingIdentity();
7356        try {
7357            mWindowManager.resizeStack(stackBoxId, bounds);
7358        } finally {
7359            Binder.restoreCallingIdentity(ident);
7360        }
7361    }
7362
7363    @Override
7364    public List<StackInfo> getAllStackInfos() {
7365        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7366                "getAllStackInfos()");
7367        long ident = Binder.clearCallingIdentity();
7368        try {
7369            synchronized (this) {
7370                return mStackSupervisor.getAllStackInfosLocked();
7371            }
7372        } finally {
7373            Binder.restoreCallingIdentity(ident);
7374        }
7375    }
7376
7377    @Override
7378    public StackInfo getStackInfo(int stackId) {
7379        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7380                "getStackInfo()");
7381        long ident = Binder.clearCallingIdentity();
7382        try {
7383            synchronized (this) {
7384                return mStackSupervisor.getStackInfoLocked(stackId);
7385            }
7386        } finally {
7387            Binder.restoreCallingIdentity(ident);
7388        }
7389    }
7390
7391    @Override
7392    public boolean isInHomeStack(int taskId) {
7393        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7394                "getStackInfo()");
7395        long ident = Binder.clearCallingIdentity();
7396        try {
7397            synchronized (this) {
7398                TaskRecord tr = recentTaskForIdLocked(taskId);
7399                if (tr != null) {
7400                    return tr.stack.isHomeStack();
7401                }
7402            }
7403        } finally {
7404            Binder.restoreCallingIdentity(ident);
7405        }
7406        return false;
7407    }
7408
7409    @Override
7410    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7411        synchronized(this) {
7412            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7413        }
7414    }
7415
7416    private boolean isLockTaskAuthorized(ComponentName name) {
7417//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7418//                "startLockTaskMode()");
7419//        DevicePolicyManager dpm = (DevicePolicyManager)
7420//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7421//        return dpm != null && dpm.isLockTaskPermitted(name);
7422        return true;
7423    }
7424
7425    private void startLockTaskMode(TaskRecord task) {
7426        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7427            return;
7428        }
7429        long ident = Binder.clearCallingIdentity();
7430        try {
7431            synchronized (this) {
7432                // Since we lost lock on task, make sure it is still there.
7433                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7434                if (task != null) {
7435                    mStackSupervisor.setLockTaskModeLocked(task);
7436                }
7437            }
7438        } finally {
7439            Binder.restoreCallingIdentity(ident);
7440        }
7441    }
7442
7443    @Override
7444    public void startLockTaskMode(int taskId) {
7445        long ident = Binder.clearCallingIdentity();
7446        try {
7447            final TaskRecord task;
7448            synchronized (this) {
7449                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7450            }
7451            if (task != null) {
7452                startLockTaskMode(task);
7453            }
7454        } finally {
7455            Binder.restoreCallingIdentity(ident);
7456        }
7457    }
7458
7459    @Override
7460    public void startLockTaskMode(IBinder token) {
7461        long ident = Binder.clearCallingIdentity();
7462        try {
7463            final TaskRecord task;
7464            synchronized (this) {
7465                final ActivityRecord r = ActivityRecord.forToken(token);
7466                if (r == null) {
7467                    return;
7468                }
7469                task = r.task;
7470            }
7471            if (task != null) {
7472                startLockTaskMode(task);
7473            }
7474        } finally {
7475            Binder.restoreCallingIdentity(ident);
7476        }
7477    }
7478
7479    @Override
7480    public void stopLockTaskMode() {
7481//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7482//                "stopLockTaskMode()");
7483        synchronized (this) {
7484            mStackSupervisor.setLockTaskModeLocked(null);
7485        }
7486    }
7487
7488    @Override
7489    public boolean isInLockTaskMode() {
7490        synchronized (this) {
7491            return mStackSupervisor.isInLockTaskMode();
7492        }
7493    }
7494
7495    // =========================================================
7496    // THUMBNAILS
7497    // =========================================================
7498
7499    public void reportThumbnail(IBinder token,
7500            Bitmap thumbnail, CharSequence description) {
7501        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7502        final long origId = Binder.clearCallingIdentity();
7503        sendPendingThumbnail(null, token, thumbnail, description, true);
7504        Binder.restoreCallingIdentity(origId);
7505    }
7506
7507    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7508            Bitmap thumbnail, CharSequence description, boolean always) {
7509        TaskRecord task;
7510        ArrayList<PendingThumbnailsRecord> receivers = null;
7511
7512        //System.out.println("Send pending thumbnail: " + r);
7513
7514        synchronized(this) {
7515            if (r == null) {
7516                r = ActivityRecord.isInStackLocked(token);
7517                if (r == null) {
7518                    return;
7519                }
7520            }
7521            if (thumbnail == null && r.thumbHolder != null) {
7522                thumbnail = r.thumbHolder.lastThumbnail;
7523                description = r.thumbHolder.lastDescription;
7524            }
7525            if (thumbnail == null && !always) {
7526                // If there is no thumbnail, and this entry is not actually
7527                // going away, then abort for now and pick up the next
7528                // thumbnail we get.
7529                return;
7530            }
7531            task = r.task;
7532
7533            int N = mPendingThumbnails.size();
7534            int i=0;
7535            while (i<N) {
7536                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7537                //System.out.println("Looking in " + pr.pendingRecords);
7538                if (pr.pendingRecords.remove(r)) {
7539                    if (receivers == null) {
7540                        receivers = new ArrayList<PendingThumbnailsRecord>();
7541                    }
7542                    receivers.add(pr);
7543                    if (pr.pendingRecords.size() == 0) {
7544                        pr.finished = true;
7545                        mPendingThumbnails.remove(i);
7546                        N--;
7547                        continue;
7548                    }
7549                }
7550                i++;
7551            }
7552        }
7553
7554        if (receivers != null) {
7555            final int N = receivers.size();
7556            for (int i=0; i<N; i++) {
7557                try {
7558                    PendingThumbnailsRecord pr = receivers.get(i);
7559                    pr.receiver.newThumbnail(
7560                        task != null ? task.taskId : -1, thumbnail, description);
7561                    if (pr.finished) {
7562                        pr.receiver.finished();
7563                    }
7564                } catch (Exception e) {
7565                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7566                }
7567            }
7568        }
7569    }
7570
7571    // =========================================================
7572    // CONTENT PROVIDERS
7573    // =========================================================
7574
7575    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7576        List<ProviderInfo> providers = null;
7577        try {
7578            providers = AppGlobals.getPackageManager().
7579                queryContentProviders(app.processName, app.uid,
7580                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7581        } catch (RemoteException ex) {
7582        }
7583        if (DEBUG_MU)
7584            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7585        int userId = app.userId;
7586        if (providers != null) {
7587            int N = providers.size();
7588            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7589            for (int i=0; i<N; i++) {
7590                ProviderInfo cpi =
7591                    (ProviderInfo)providers.get(i);
7592                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7593                        cpi.name, cpi.flags);
7594                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7595                    // This is a singleton provider, but a user besides the
7596                    // default user is asking to initialize a process it runs
7597                    // in...  well, no, it doesn't actually run in this process,
7598                    // it runs in the process of the default user.  Get rid of it.
7599                    providers.remove(i);
7600                    N--;
7601                    i--;
7602                    continue;
7603                }
7604
7605                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7606                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7607                if (cpr == null) {
7608                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7609                    mProviderMap.putProviderByClass(comp, cpr);
7610                }
7611                if (DEBUG_MU)
7612                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7613                app.pubProviders.put(cpi.name, cpr);
7614                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7615                    // Don't add this if it is a platform component that is marked
7616                    // to run in multiple processes, because this is actually
7617                    // part of the framework so doesn't make sense to track as a
7618                    // separate apk in the process.
7619                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7620                }
7621                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7622            }
7623        }
7624        return providers;
7625    }
7626
7627    /**
7628     * Check if {@link ProcessRecord} has a possible chance at accessing the
7629     * given {@link ProviderInfo}. Final permission checking is always done
7630     * in {@link ContentProvider}.
7631     */
7632    private final String checkContentProviderPermissionLocked(
7633            ProviderInfo cpi, ProcessRecord r) {
7634        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7635        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7636        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7637                cpi.applicationInfo.uid, cpi.exported)
7638                == PackageManager.PERMISSION_GRANTED) {
7639            return null;
7640        }
7641        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7642                cpi.applicationInfo.uid, cpi.exported)
7643                == PackageManager.PERMISSION_GRANTED) {
7644            return null;
7645        }
7646
7647        PathPermission[] pps = cpi.pathPermissions;
7648        if (pps != null) {
7649            int i = pps.length;
7650            while (i > 0) {
7651                i--;
7652                PathPermission pp = pps[i];
7653                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7654                        cpi.applicationInfo.uid, cpi.exported)
7655                        == PackageManager.PERMISSION_GRANTED) {
7656                    return null;
7657                }
7658                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7659                        cpi.applicationInfo.uid, cpi.exported)
7660                        == PackageManager.PERMISSION_GRANTED) {
7661                    return null;
7662                }
7663            }
7664        }
7665
7666        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7667        if (perms != null) {
7668            for (GrantUri uri : perms.keySet()) {
7669                if (uri.uri.getAuthority().equals(cpi.authority)) {
7670                    return null;
7671                }
7672            }
7673        }
7674
7675        String msg;
7676        if (!cpi.exported) {
7677            msg = "Permission Denial: opening provider " + cpi.name
7678                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7679                    + ", uid=" + callingUid + ") that is not exported from uid "
7680                    + cpi.applicationInfo.uid;
7681        } else {
7682            msg = "Permission Denial: opening provider " + cpi.name
7683                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7684                    + ", uid=" + callingUid + ") requires "
7685                    + cpi.readPermission + " or " + cpi.writePermission;
7686        }
7687        Slog.w(TAG, msg);
7688        return msg;
7689    }
7690
7691    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7692            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7693        if (r != null) {
7694            for (int i=0; i<r.conProviders.size(); i++) {
7695                ContentProviderConnection conn = r.conProviders.get(i);
7696                if (conn.provider == cpr) {
7697                    if (DEBUG_PROVIDER) Slog.v(TAG,
7698                            "Adding provider requested by "
7699                            + r.processName + " from process "
7700                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7701                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7702                    if (stable) {
7703                        conn.stableCount++;
7704                        conn.numStableIncs++;
7705                    } else {
7706                        conn.unstableCount++;
7707                        conn.numUnstableIncs++;
7708                    }
7709                    return conn;
7710                }
7711            }
7712            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7713            if (stable) {
7714                conn.stableCount = 1;
7715                conn.numStableIncs = 1;
7716            } else {
7717                conn.unstableCount = 1;
7718                conn.numUnstableIncs = 1;
7719            }
7720            cpr.connections.add(conn);
7721            r.conProviders.add(conn);
7722            return conn;
7723        }
7724        cpr.addExternalProcessHandleLocked(externalProcessToken);
7725        return null;
7726    }
7727
7728    boolean decProviderCountLocked(ContentProviderConnection conn,
7729            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7730        if (conn != null) {
7731            cpr = conn.provider;
7732            if (DEBUG_PROVIDER) Slog.v(TAG,
7733                    "Removing provider requested by "
7734                    + conn.client.processName + " from process "
7735                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7736                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7737            if (stable) {
7738                conn.stableCount--;
7739            } else {
7740                conn.unstableCount--;
7741            }
7742            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7743                cpr.connections.remove(conn);
7744                conn.client.conProviders.remove(conn);
7745                return true;
7746            }
7747            return false;
7748        }
7749        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7750        return false;
7751    }
7752
7753    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7754            String name, IBinder token, boolean stable, int userId) {
7755        ContentProviderRecord cpr;
7756        ContentProviderConnection conn = null;
7757        ProviderInfo cpi = null;
7758
7759        synchronized(this) {
7760            ProcessRecord r = null;
7761            if (caller != null) {
7762                r = getRecordForAppLocked(caller);
7763                if (r == null) {
7764                    throw new SecurityException(
7765                            "Unable to find app for caller " + caller
7766                          + " (pid=" + Binder.getCallingPid()
7767                          + ") when getting content provider " + name);
7768                }
7769            }
7770
7771            // First check if this content provider has been published...
7772            cpr = mProviderMap.getProviderByName(name, userId);
7773            boolean providerRunning = cpr != null;
7774            if (providerRunning) {
7775                cpi = cpr.info;
7776                String msg;
7777                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7778                    throw new SecurityException(msg);
7779                }
7780
7781                if (r != null && cpr.canRunHere(r)) {
7782                    // This provider has been published or is in the process
7783                    // of being published...  but it is also allowed to run
7784                    // in the caller's process, so don't make a connection
7785                    // and just let the caller instantiate its own instance.
7786                    ContentProviderHolder holder = cpr.newHolder(null);
7787                    // don't give caller the provider object, it needs
7788                    // to make its own.
7789                    holder.provider = null;
7790                    return holder;
7791                }
7792
7793                final long origId = Binder.clearCallingIdentity();
7794
7795                // In this case the provider instance already exists, so we can
7796                // return it right away.
7797                conn = incProviderCountLocked(r, cpr, token, stable);
7798                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7799                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7800                        // If this is a perceptible app accessing the provider,
7801                        // make sure to count it as being accessed and thus
7802                        // back up on the LRU list.  This is good because
7803                        // content providers are often expensive to start.
7804                        updateLruProcessLocked(cpr.proc, false, null);
7805                    }
7806                }
7807
7808                if (cpr.proc != null) {
7809                    if (false) {
7810                        if (cpr.name.flattenToShortString().equals(
7811                                "com.android.providers.calendar/.CalendarProvider2")) {
7812                            Slog.v(TAG, "****************** KILLING "
7813                                + cpr.name.flattenToShortString());
7814                            Process.killProcess(cpr.proc.pid);
7815                        }
7816                    }
7817                    boolean success = updateOomAdjLocked(cpr.proc);
7818                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7819                    // NOTE: there is still a race here where a signal could be
7820                    // pending on the process even though we managed to update its
7821                    // adj level.  Not sure what to do about this, but at least
7822                    // the race is now smaller.
7823                    if (!success) {
7824                        // Uh oh...  it looks like the provider's process
7825                        // has been killed on us.  We need to wait for a new
7826                        // process to be started, and make sure its death
7827                        // doesn't kill our process.
7828                        Slog.i(TAG,
7829                                "Existing provider " + cpr.name.flattenToShortString()
7830                                + " is crashing; detaching " + r);
7831                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7832                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7833                        if (!lastRef) {
7834                            // This wasn't the last ref our process had on
7835                            // the provider...  we have now been killed, bail.
7836                            return null;
7837                        }
7838                        providerRunning = false;
7839                        conn = null;
7840                    }
7841                }
7842
7843                Binder.restoreCallingIdentity(origId);
7844            }
7845
7846            boolean singleton;
7847            if (!providerRunning) {
7848                try {
7849                    cpi = AppGlobals.getPackageManager().
7850                        resolveContentProvider(name,
7851                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7852                } catch (RemoteException ex) {
7853                }
7854                if (cpi == null) {
7855                    return null;
7856                }
7857                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7858                        cpi.name, cpi.flags);
7859                if (singleton) {
7860                    userId = 0;
7861                }
7862                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7863
7864                String msg;
7865                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7866                    throw new SecurityException(msg);
7867                }
7868
7869                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7870                        && !cpi.processName.equals("system")) {
7871                    // If this content provider does not run in the system
7872                    // process, and the system is not yet ready to run other
7873                    // processes, then fail fast instead of hanging.
7874                    throw new IllegalArgumentException(
7875                            "Attempt to launch content provider before system ready");
7876                }
7877
7878                // Make sure that the user who owns this provider is started.  If not,
7879                // we don't want to allow it to run.
7880                if (mStartedUsers.get(userId) == null) {
7881                    Slog.w(TAG, "Unable to launch app "
7882                            + cpi.applicationInfo.packageName + "/"
7883                            + cpi.applicationInfo.uid + " for provider "
7884                            + name + ": user " + userId + " is stopped");
7885                    return null;
7886                }
7887
7888                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7889                cpr = mProviderMap.getProviderByClass(comp, userId);
7890                final boolean firstClass = cpr == null;
7891                if (firstClass) {
7892                    try {
7893                        ApplicationInfo ai =
7894                            AppGlobals.getPackageManager().
7895                                getApplicationInfo(
7896                                        cpi.applicationInfo.packageName,
7897                                        STOCK_PM_FLAGS, userId);
7898                        if (ai == null) {
7899                            Slog.w(TAG, "No package info for content provider "
7900                                    + cpi.name);
7901                            return null;
7902                        }
7903                        ai = getAppInfoForUser(ai, userId);
7904                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7905                    } catch (RemoteException ex) {
7906                        // pm is in same process, this will never happen.
7907                    }
7908                }
7909
7910                if (r != null && cpr.canRunHere(r)) {
7911                    // If this is a multiprocess provider, then just return its
7912                    // info and allow the caller to instantiate it.  Only do
7913                    // this if the provider is the same user as the caller's
7914                    // process, or can run as root (so can be in any process).
7915                    return cpr.newHolder(null);
7916                }
7917
7918                if (DEBUG_PROVIDER) {
7919                    RuntimeException e = new RuntimeException("here");
7920                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7921                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7922                }
7923
7924                // This is single process, and our app is now connecting to it.
7925                // See if we are already in the process of launching this
7926                // provider.
7927                final int N = mLaunchingProviders.size();
7928                int i;
7929                for (i=0; i<N; i++) {
7930                    if (mLaunchingProviders.get(i) == cpr) {
7931                        break;
7932                    }
7933                }
7934
7935                // If the provider is not already being launched, then get it
7936                // started.
7937                if (i >= N) {
7938                    final long origId = Binder.clearCallingIdentity();
7939
7940                    try {
7941                        // Content provider is now in use, its package can't be stopped.
7942                        try {
7943                            AppGlobals.getPackageManager().setPackageStoppedState(
7944                                    cpr.appInfo.packageName, false, userId);
7945                        } catch (RemoteException e) {
7946                        } catch (IllegalArgumentException e) {
7947                            Slog.w(TAG, "Failed trying to unstop package "
7948                                    + cpr.appInfo.packageName + ": " + e);
7949                        }
7950
7951                        // Use existing process if already started
7952                        ProcessRecord proc = getProcessRecordLocked(
7953                                cpi.processName, cpr.appInfo.uid, false);
7954                        if (proc != null && proc.thread != null) {
7955                            if (DEBUG_PROVIDER) {
7956                                Slog.d(TAG, "Installing in existing process " + proc);
7957                            }
7958                            proc.pubProviders.put(cpi.name, cpr);
7959                            try {
7960                                proc.thread.scheduleInstallProvider(cpi);
7961                            } catch (RemoteException e) {
7962                            }
7963                        } else {
7964                            proc = startProcessLocked(cpi.processName,
7965                                    cpr.appInfo, false, 0, "content provider",
7966                                    new ComponentName(cpi.applicationInfo.packageName,
7967                                            cpi.name), false, false, false);
7968                            if (proc == null) {
7969                                Slog.w(TAG, "Unable to launch app "
7970                                        + cpi.applicationInfo.packageName + "/"
7971                                        + cpi.applicationInfo.uid + " for provider "
7972                                        + name + ": process is bad");
7973                                return null;
7974                            }
7975                        }
7976                        cpr.launchingApp = proc;
7977                        mLaunchingProviders.add(cpr);
7978                    } finally {
7979                        Binder.restoreCallingIdentity(origId);
7980                    }
7981                }
7982
7983                // Make sure the provider is published (the same provider class
7984                // may be published under multiple names).
7985                if (firstClass) {
7986                    mProviderMap.putProviderByClass(comp, cpr);
7987                }
7988
7989                mProviderMap.putProviderByName(name, cpr);
7990                conn = incProviderCountLocked(r, cpr, token, stable);
7991                if (conn != null) {
7992                    conn.waiting = true;
7993                }
7994            }
7995        }
7996
7997        // Wait for the provider to be published...
7998        synchronized (cpr) {
7999            while (cpr.provider == null) {
8000                if (cpr.launchingApp == null) {
8001                    Slog.w(TAG, "Unable to launch app "
8002                            + cpi.applicationInfo.packageName + "/"
8003                            + cpi.applicationInfo.uid + " for provider "
8004                            + name + ": launching app became null");
8005                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8006                            UserHandle.getUserId(cpi.applicationInfo.uid),
8007                            cpi.applicationInfo.packageName,
8008                            cpi.applicationInfo.uid, name);
8009                    return null;
8010                }
8011                try {
8012                    if (DEBUG_MU) {
8013                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8014                                + cpr.launchingApp);
8015                    }
8016                    if (conn != null) {
8017                        conn.waiting = true;
8018                    }
8019                    cpr.wait();
8020                } catch (InterruptedException ex) {
8021                } finally {
8022                    if (conn != null) {
8023                        conn.waiting = false;
8024                    }
8025                }
8026            }
8027        }
8028        return cpr != null ? cpr.newHolder(conn) : null;
8029    }
8030
8031    public final ContentProviderHolder getContentProvider(
8032            IApplicationThread caller, String name, int userId, boolean stable) {
8033        enforceNotIsolatedCaller("getContentProvider");
8034        if (caller == null) {
8035            String msg = "null IApplicationThread when getting content provider "
8036                    + name;
8037            Slog.w(TAG, msg);
8038            throw new SecurityException(msg);
8039        }
8040
8041        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8042                false, true, "getContentProvider", null);
8043        return getContentProviderImpl(caller, name, null, stable, userId);
8044    }
8045
8046    public ContentProviderHolder getContentProviderExternal(
8047            String name, int userId, IBinder token) {
8048        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8049            "Do not have permission in call getContentProviderExternal()");
8050        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8051                false, true, "getContentProvider", null);
8052        return getContentProviderExternalUnchecked(name, token, userId);
8053    }
8054
8055    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8056            IBinder token, int userId) {
8057        return getContentProviderImpl(null, name, token, true, userId);
8058    }
8059
8060    /**
8061     * Drop a content provider from a ProcessRecord's bookkeeping
8062     */
8063    public void removeContentProvider(IBinder connection, boolean stable) {
8064        enforceNotIsolatedCaller("removeContentProvider");
8065        long ident = Binder.clearCallingIdentity();
8066        try {
8067            synchronized (this) {
8068                ContentProviderConnection conn;
8069                try {
8070                    conn = (ContentProviderConnection)connection;
8071                } catch (ClassCastException e) {
8072                    String msg ="removeContentProvider: " + connection
8073                            + " not a ContentProviderConnection";
8074                    Slog.w(TAG, msg);
8075                    throw new IllegalArgumentException(msg);
8076                }
8077                if (conn == null) {
8078                    throw new NullPointerException("connection is null");
8079                }
8080                if (decProviderCountLocked(conn, null, null, stable)) {
8081                    updateOomAdjLocked();
8082                }
8083            }
8084        } finally {
8085            Binder.restoreCallingIdentity(ident);
8086        }
8087    }
8088
8089    public void removeContentProviderExternal(String name, IBinder token) {
8090        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8091            "Do not have permission in call removeContentProviderExternal()");
8092        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8093    }
8094
8095    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8096        synchronized (this) {
8097            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8098            if(cpr == null) {
8099                //remove from mProvidersByClass
8100                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8101                return;
8102            }
8103
8104            //update content provider record entry info
8105            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8106            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8107            if (localCpr.hasExternalProcessHandles()) {
8108                if (localCpr.removeExternalProcessHandleLocked(token)) {
8109                    updateOomAdjLocked();
8110                } else {
8111                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8112                            + " with no external reference for token: "
8113                            + token + ".");
8114                }
8115            } else {
8116                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8117                        + " with no external references.");
8118            }
8119        }
8120    }
8121
8122    public final void publishContentProviders(IApplicationThread caller,
8123            List<ContentProviderHolder> providers) {
8124        if (providers == null) {
8125            return;
8126        }
8127
8128        enforceNotIsolatedCaller("publishContentProviders");
8129        synchronized (this) {
8130            final ProcessRecord r = getRecordForAppLocked(caller);
8131            if (DEBUG_MU)
8132                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8133            if (r == null) {
8134                throw new SecurityException(
8135                        "Unable to find app for caller " + caller
8136                      + " (pid=" + Binder.getCallingPid()
8137                      + ") when publishing content providers");
8138            }
8139
8140            final long origId = Binder.clearCallingIdentity();
8141
8142            final int N = providers.size();
8143            for (int i=0; i<N; i++) {
8144                ContentProviderHolder src = providers.get(i);
8145                if (src == null || src.info == null || src.provider == null) {
8146                    continue;
8147                }
8148                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8149                if (DEBUG_MU)
8150                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8151                if (dst != null) {
8152                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8153                    mProviderMap.putProviderByClass(comp, dst);
8154                    String names[] = dst.info.authority.split(";");
8155                    for (int j = 0; j < names.length; j++) {
8156                        mProviderMap.putProviderByName(names[j], dst);
8157                    }
8158
8159                    int NL = mLaunchingProviders.size();
8160                    int j;
8161                    for (j=0; j<NL; j++) {
8162                        if (mLaunchingProviders.get(j) == dst) {
8163                            mLaunchingProviders.remove(j);
8164                            j--;
8165                            NL--;
8166                        }
8167                    }
8168                    synchronized (dst) {
8169                        dst.provider = src.provider;
8170                        dst.proc = r;
8171                        dst.notifyAll();
8172                    }
8173                    updateOomAdjLocked(r);
8174                }
8175            }
8176
8177            Binder.restoreCallingIdentity(origId);
8178        }
8179    }
8180
8181    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8182        ContentProviderConnection conn;
8183        try {
8184            conn = (ContentProviderConnection)connection;
8185        } catch (ClassCastException e) {
8186            String msg ="refContentProvider: " + connection
8187                    + " not a ContentProviderConnection";
8188            Slog.w(TAG, msg);
8189            throw new IllegalArgumentException(msg);
8190        }
8191        if (conn == null) {
8192            throw new NullPointerException("connection is null");
8193        }
8194
8195        synchronized (this) {
8196            if (stable > 0) {
8197                conn.numStableIncs += stable;
8198            }
8199            stable = conn.stableCount + stable;
8200            if (stable < 0) {
8201                throw new IllegalStateException("stableCount < 0: " + stable);
8202            }
8203
8204            if (unstable > 0) {
8205                conn.numUnstableIncs += unstable;
8206            }
8207            unstable = conn.unstableCount + unstable;
8208            if (unstable < 0) {
8209                throw new IllegalStateException("unstableCount < 0: " + unstable);
8210            }
8211
8212            if ((stable+unstable) <= 0) {
8213                throw new IllegalStateException("ref counts can't go to zero here: stable="
8214                        + stable + " unstable=" + unstable);
8215            }
8216            conn.stableCount = stable;
8217            conn.unstableCount = unstable;
8218            return !conn.dead;
8219        }
8220    }
8221
8222    public void unstableProviderDied(IBinder connection) {
8223        ContentProviderConnection conn;
8224        try {
8225            conn = (ContentProviderConnection)connection;
8226        } catch (ClassCastException e) {
8227            String msg ="refContentProvider: " + connection
8228                    + " not a ContentProviderConnection";
8229            Slog.w(TAG, msg);
8230            throw new IllegalArgumentException(msg);
8231        }
8232        if (conn == null) {
8233            throw new NullPointerException("connection is null");
8234        }
8235
8236        // Safely retrieve the content provider associated with the connection.
8237        IContentProvider provider;
8238        synchronized (this) {
8239            provider = conn.provider.provider;
8240        }
8241
8242        if (provider == null) {
8243            // Um, yeah, we're way ahead of you.
8244            return;
8245        }
8246
8247        // Make sure the caller is being honest with us.
8248        if (provider.asBinder().pingBinder()) {
8249            // Er, no, still looks good to us.
8250            synchronized (this) {
8251                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8252                        + " says " + conn + " died, but we don't agree");
8253                return;
8254            }
8255        }
8256
8257        // Well look at that!  It's dead!
8258        synchronized (this) {
8259            if (conn.provider.provider != provider) {
8260                // But something changed...  good enough.
8261                return;
8262            }
8263
8264            ProcessRecord proc = conn.provider.proc;
8265            if (proc == null || proc.thread == null) {
8266                // Seems like the process is already cleaned up.
8267                return;
8268            }
8269
8270            // As far as we're concerned, this is just like receiving a
8271            // death notification...  just a bit prematurely.
8272            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8273                    + ") early provider death");
8274            final long ident = Binder.clearCallingIdentity();
8275            try {
8276                appDiedLocked(proc, proc.pid, proc.thread);
8277            } finally {
8278                Binder.restoreCallingIdentity(ident);
8279            }
8280        }
8281    }
8282
8283    @Override
8284    public void appNotRespondingViaProvider(IBinder connection) {
8285        enforceCallingPermission(
8286                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8287
8288        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8289        if (conn == null) {
8290            Slog.w(TAG, "ContentProviderConnection is null");
8291            return;
8292        }
8293
8294        final ProcessRecord host = conn.provider.proc;
8295        if (host == null) {
8296            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8297            return;
8298        }
8299
8300        final long token = Binder.clearCallingIdentity();
8301        try {
8302            appNotResponding(host, null, null, false, "ContentProvider not responding");
8303        } finally {
8304            Binder.restoreCallingIdentity(token);
8305        }
8306    }
8307
8308    public final void installSystemProviders() {
8309        List<ProviderInfo> providers;
8310        synchronized (this) {
8311            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8312            providers = generateApplicationProvidersLocked(app);
8313            if (providers != null) {
8314                for (int i=providers.size()-1; i>=0; i--) {
8315                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8316                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8317                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8318                                + ": not system .apk");
8319                        providers.remove(i);
8320                    }
8321                }
8322            }
8323        }
8324        if (providers != null) {
8325            mSystemThread.installSystemProviders(providers);
8326        }
8327
8328        mCoreSettingsObserver = new CoreSettingsObserver(this);
8329
8330        mUsageStatsService.monitorPackages();
8331    }
8332
8333    /**
8334     * Allows app to retrieve the MIME type of a URI without having permission
8335     * to access its content provider.
8336     *
8337     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8338     *
8339     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8340     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8341     */
8342    public String getProviderMimeType(Uri uri, int userId) {
8343        enforceNotIsolatedCaller("getProviderMimeType");
8344        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8345                userId, false, true, "getProviderMimeType", null);
8346        final String name = uri.getAuthority();
8347        final long ident = Binder.clearCallingIdentity();
8348        ContentProviderHolder holder = null;
8349
8350        try {
8351            holder = getContentProviderExternalUnchecked(name, null, userId);
8352            if (holder != null) {
8353                return holder.provider.getType(uri);
8354            }
8355        } catch (RemoteException e) {
8356            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8357            return null;
8358        } finally {
8359            if (holder != null) {
8360                removeContentProviderExternalUnchecked(name, null, userId);
8361            }
8362            Binder.restoreCallingIdentity(ident);
8363        }
8364
8365        return null;
8366    }
8367
8368    // =========================================================
8369    // GLOBAL MANAGEMENT
8370    // =========================================================
8371
8372    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8373            boolean isolated) {
8374        String proc = customProcess != null ? customProcess : info.processName;
8375        BatteryStatsImpl.Uid.Proc ps = null;
8376        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8377        int uid = info.uid;
8378        if (isolated) {
8379            int userId = UserHandle.getUserId(uid);
8380            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8381            while (true) {
8382                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8383                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8384                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8385                }
8386                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8387                mNextIsolatedProcessUid++;
8388                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8389                    // No process for this uid, use it.
8390                    break;
8391                }
8392                stepsLeft--;
8393                if (stepsLeft <= 0) {
8394                    return null;
8395                }
8396            }
8397        }
8398        return new ProcessRecord(stats, info, proc, uid);
8399    }
8400
8401    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8402        ProcessRecord app;
8403        if (!isolated) {
8404            app = getProcessRecordLocked(info.processName, info.uid, true);
8405        } else {
8406            app = null;
8407        }
8408
8409        if (app == null) {
8410            app = newProcessRecordLocked(info, null, isolated);
8411            mProcessNames.put(info.processName, app.uid, app);
8412            if (isolated) {
8413                mIsolatedProcesses.put(app.uid, app);
8414            }
8415            updateLruProcessLocked(app, false, null);
8416            updateOomAdjLocked();
8417        }
8418
8419        // This package really, really can not be stopped.
8420        try {
8421            AppGlobals.getPackageManager().setPackageStoppedState(
8422                    info.packageName, false, UserHandle.getUserId(app.uid));
8423        } catch (RemoteException e) {
8424        } catch (IllegalArgumentException e) {
8425            Slog.w(TAG, "Failed trying to unstop package "
8426                    + info.packageName + ": " + e);
8427        }
8428
8429        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8430                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8431            app.persistent = true;
8432            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8433        }
8434        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8435            mPersistentStartingProcesses.add(app);
8436            startProcessLocked(app, "added application", app.processName);
8437        }
8438
8439        return app;
8440    }
8441
8442    public void unhandledBack() {
8443        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8444                "unhandledBack()");
8445
8446        synchronized(this) {
8447            final long origId = Binder.clearCallingIdentity();
8448            try {
8449                getFocusedStack().unhandledBackLocked();
8450            } finally {
8451                Binder.restoreCallingIdentity(origId);
8452            }
8453        }
8454    }
8455
8456    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8457        enforceNotIsolatedCaller("openContentUri");
8458        final int userId = UserHandle.getCallingUserId();
8459        String name = uri.getAuthority();
8460        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8461        ParcelFileDescriptor pfd = null;
8462        if (cph != null) {
8463            // We record the binder invoker's uid in thread-local storage before
8464            // going to the content provider to open the file.  Later, in the code
8465            // that handles all permissions checks, we look for this uid and use
8466            // that rather than the Activity Manager's own uid.  The effect is that
8467            // we do the check against the caller's permissions even though it looks
8468            // to the content provider like the Activity Manager itself is making
8469            // the request.
8470            sCallerIdentity.set(new Identity(
8471                    Binder.getCallingPid(), Binder.getCallingUid()));
8472            try {
8473                pfd = cph.provider.openFile(null, uri, "r", null);
8474            } catch (FileNotFoundException e) {
8475                // do nothing; pfd will be returned null
8476            } finally {
8477                // Ensure that whatever happens, we clean up the identity state
8478                sCallerIdentity.remove();
8479            }
8480
8481            // We've got the fd now, so we're done with the provider.
8482            removeContentProviderExternalUnchecked(name, null, userId);
8483        } else {
8484            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8485        }
8486        return pfd;
8487    }
8488
8489    // Actually is sleeping or shutting down or whatever else in the future
8490    // is an inactive state.
8491    public boolean isSleepingOrShuttingDown() {
8492        return mSleeping || mShuttingDown;
8493    }
8494
8495    void goingToSleep() {
8496        synchronized(this) {
8497            mWentToSleep = true;
8498            updateEventDispatchingLocked();
8499
8500            if (!mSleeping) {
8501                mSleeping = true;
8502                mStackSupervisor.goingToSleepLocked();
8503
8504                // Initialize the wake times of all processes.
8505                checkExcessivePowerUsageLocked(false);
8506                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8507                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8508                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8509            }
8510        }
8511    }
8512
8513    @Override
8514    public boolean shutdown(int timeout) {
8515        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8516                != PackageManager.PERMISSION_GRANTED) {
8517            throw new SecurityException("Requires permission "
8518                    + android.Manifest.permission.SHUTDOWN);
8519        }
8520
8521        boolean timedout = false;
8522
8523        synchronized(this) {
8524            mShuttingDown = true;
8525            updateEventDispatchingLocked();
8526            timedout = mStackSupervisor.shutdownLocked(timeout);
8527        }
8528
8529        mAppOpsService.shutdown();
8530        mUsageStatsService.shutdown();
8531        mBatteryStatsService.shutdown();
8532        synchronized (this) {
8533            mProcessStats.shutdownLocked();
8534        }
8535
8536        return timedout;
8537    }
8538
8539    public final void activitySlept(IBinder token) {
8540        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8541
8542        final long origId = Binder.clearCallingIdentity();
8543
8544        synchronized (this) {
8545            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8546            if (r != null) {
8547                mStackSupervisor.activitySleptLocked(r);
8548            }
8549        }
8550
8551        Binder.restoreCallingIdentity(origId);
8552    }
8553
8554    void logLockScreen(String msg) {
8555        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8556                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8557                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8558                mStackSupervisor.mDismissKeyguardOnNextActivity);
8559    }
8560
8561    private void comeOutOfSleepIfNeededLocked() {
8562        if (!mWentToSleep && !mLockScreenShown) {
8563            if (mSleeping) {
8564                mSleeping = false;
8565                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8566            }
8567        }
8568    }
8569
8570    void wakingUp() {
8571        synchronized(this) {
8572            mWentToSleep = false;
8573            updateEventDispatchingLocked();
8574            comeOutOfSleepIfNeededLocked();
8575        }
8576    }
8577
8578    private void updateEventDispatchingLocked() {
8579        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8580    }
8581
8582    public void setLockScreenShown(boolean shown) {
8583        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8584                != PackageManager.PERMISSION_GRANTED) {
8585            throw new SecurityException("Requires permission "
8586                    + android.Manifest.permission.DEVICE_POWER);
8587        }
8588
8589        synchronized(this) {
8590            long ident = Binder.clearCallingIdentity();
8591            try {
8592                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8593                mLockScreenShown = shown;
8594                comeOutOfSleepIfNeededLocked();
8595            } finally {
8596                Binder.restoreCallingIdentity(ident);
8597            }
8598        }
8599    }
8600
8601    public void stopAppSwitches() {
8602        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8603                != PackageManager.PERMISSION_GRANTED) {
8604            throw new SecurityException("Requires permission "
8605                    + android.Manifest.permission.STOP_APP_SWITCHES);
8606        }
8607
8608        synchronized(this) {
8609            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8610                    + APP_SWITCH_DELAY_TIME;
8611            mDidAppSwitch = false;
8612            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8613            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8614            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8615        }
8616    }
8617
8618    public void resumeAppSwitches() {
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            // Note that we don't execute any pending app switches... we will
8627            // let those wait until either the timeout, or the next start
8628            // activity request.
8629            mAppSwitchesAllowedTime = 0;
8630        }
8631    }
8632
8633    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8634            String name) {
8635        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8636            return true;
8637        }
8638
8639        final int perm = checkComponentPermission(
8640                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8641                callingUid, -1, true);
8642        if (perm == PackageManager.PERMISSION_GRANTED) {
8643            return true;
8644        }
8645
8646        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8647        return false;
8648    }
8649
8650    public void setDebugApp(String packageName, boolean waitForDebugger,
8651            boolean persistent) {
8652        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8653                "setDebugApp()");
8654
8655        long ident = Binder.clearCallingIdentity();
8656        try {
8657            // Note that this is not really thread safe if there are multiple
8658            // callers into it at the same time, but that's not a situation we
8659            // care about.
8660            if (persistent) {
8661                final ContentResolver resolver = mContext.getContentResolver();
8662                Settings.Global.putString(
8663                    resolver, Settings.Global.DEBUG_APP,
8664                    packageName);
8665                Settings.Global.putInt(
8666                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8667                    waitForDebugger ? 1 : 0);
8668            }
8669
8670            synchronized (this) {
8671                if (!persistent) {
8672                    mOrigDebugApp = mDebugApp;
8673                    mOrigWaitForDebugger = mWaitForDebugger;
8674                }
8675                mDebugApp = packageName;
8676                mWaitForDebugger = waitForDebugger;
8677                mDebugTransient = !persistent;
8678                if (packageName != null) {
8679                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8680                            false, UserHandle.USER_ALL, "set debug app");
8681                }
8682            }
8683        } finally {
8684            Binder.restoreCallingIdentity(ident);
8685        }
8686    }
8687
8688    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8689        synchronized (this) {
8690            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8691            if (!isDebuggable) {
8692                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8693                    throw new SecurityException("Process not debuggable: " + app.packageName);
8694                }
8695            }
8696
8697            mOpenGlTraceApp = processName;
8698        }
8699    }
8700
8701    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8702            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8703        synchronized (this) {
8704            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8705            if (!isDebuggable) {
8706                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8707                    throw new SecurityException("Process not debuggable: " + app.packageName);
8708                }
8709            }
8710            mProfileApp = processName;
8711            mProfileFile = profileFile;
8712            if (mProfileFd != null) {
8713                try {
8714                    mProfileFd.close();
8715                } catch (IOException e) {
8716                }
8717                mProfileFd = null;
8718            }
8719            mProfileFd = profileFd;
8720            mProfileType = 0;
8721            mAutoStopProfiler = autoStopProfiler;
8722        }
8723    }
8724
8725    @Override
8726    public void setAlwaysFinish(boolean enabled) {
8727        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8728                "setAlwaysFinish()");
8729
8730        Settings.Global.putInt(
8731                mContext.getContentResolver(),
8732                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8733
8734        synchronized (this) {
8735            mAlwaysFinishActivities = enabled;
8736        }
8737    }
8738
8739    @Override
8740    public void setActivityController(IActivityController controller) {
8741        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8742                "setActivityController()");
8743        synchronized (this) {
8744            mController = controller;
8745            Watchdog.getInstance().setActivityController(controller);
8746        }
8747    }
8748
8749    @Override
8750    public void setUserIsMonkey(boolean userIsMonkey) {
8751        synchronized (this) {
8752            synchronized (mPidsSelfLocked) {
8753                final int callingPid = Binder.getCallingPid();
8754                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8755                if (precessRecord == null) {
8756                    throw new SecurityException("Unknown process: " + callingPid);
8757                }
8758                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8759                    throw new SecurityException("Only an instrumentation process "
8760                            + "with a UiAutomation can call setUserIsMonkey");
8761                }
8762            }
8763            mUserIsMonkey = userIsMonkey;
8764        }
8765    }
8766
8767    @Override
8768    public boolean isUserAMonkey() {
8769        synchronized (this) {
8770            // If there is a controller also implies the user is a monkey.
8771            return (mUserIsMonkey || mController != null);
8772        }
8773    }
8774
8775    public void requestBugReport() {
8776        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8777        SystemProperties.set("ctl.start", "bugreport");
8778    }
8779
8780    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8781        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8782    }
8783
8784    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8785        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8786            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8787        }
8788        return KEY_DISPATCHING_TIMEOUT;
8789    }
8790
8791    @Override
8792    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8793        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8794                != PackageManager.PERMISSION_GRANTED) {
8795            throw new SecurityException("Requires permission "
8796                    + android.Manifest.permission.FILTER_EVENTS);
8797        }
8798        ProcessRecord proc;
8799        long timeout;
8800        synchronized (this) {
8801            synchronized (mPidsSelfLocked) {
8802                proc = mPidsSelfLocked.get(pid);
8803            }
8804            timeout = getInputDispatchingTimeoutLocked(proc);
8805        }
8806
8807        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8808            return -1;
8809        }
8810
8811        return timeout;
8812    }
8813
8814    /**
8815     * Handle input dispatching timeouts.
8816     * Returns whether input dispatching should be aborted or not.
8817     */
8818    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8819            final ActivityRecord activity, final ActivityRecord parent,
8820            final boolean aboveSystem, String reason) {
8821        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8822                != PackageManager.PERMISSION_GRANTED) {
8823            throw new SecurityException("Requires permission "
8824                    + android.Manifest.permission.FILTER_EVENTS);
8825        }
8826
8827        final String annotation;
8828        if (reason == null) {
8829            annotation = "Input dispatching timed out";
8830        } else {
8831            annotation = "Input dispatching timed out (" + reason + ")";
8832        }
8833
8834        if (proc != null) {
8835            synchronized (this) {
8836                if (proc.debugging) {
8837                    return false;
8838                }
8839
8840                if (mDidDexOpt) {
8841                    // Give more time since we were dexopting.
8842                    mDidDexOpt = false;
8843                    return false;
8844                }
8845
8846                if (proc.instrumentationClass != null) {
8847                    Bundle info = new Bundle();
8848                    info.putString("shortMsg", "keyDispatchingTimedOut");
8849                    info.putString("longMsg", annotation);
8850                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8851                    return true;
8852                }
8853            }
8854            mHandler.post(new Runnable() {
8855                @Override
8856                public void run() {
8857                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8858                }
8859            });
8860        }
8861
8862        return true;
8863    }
8864
8865    public Bundle getAssistContextExtras(int requestType) {
8866        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8867                "getAssistContextExtras()");
8868        PendingAssistExtras pae;
8869        Bundle extras = new Bundle();
8870        synchronized (this) {
8871            ActivityRecord activity = getFocusedStack().mResumedActivity;
8872            if (activity == null) {
8873                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8874                return null;
8875            }
8876            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8877            if (activity.app == null || activity.app.thread == null) {
8878                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8879                return extras;
8880            }
8881            if (activity.app.pid == Binder.getCallingPid()) {
8882                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8883                return extras;
8884            }
8885            pae = new PendingAssistExtras(activity);
8886            try {
8887                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8888                        requestType);
8889                mPendingAssistExtras.add(pae);
8890                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8891            } catch (RemoteException e) {
8892                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8893                return extras;
8894            }
8895        }
8896        synchronized (pae) {
8897            while (!pae.haveResult) {
8898                try {
8899                    pae.wait();
8900                } catch (InterruptedException e) {
8901                }
8902            }
8903            if (pae.result != null) {
8904                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8905            }
8906        }
8907        synchronized (this) {
8908            mPendingAssistExtras.remove(pae);
8909            mHandler.removeCallbacks(pae);
8910        }
8911        return extras;
8912    }
8913
8914    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8915        PendingAssistExtras pae = (PendingAssistExtras)token;
8916        synchronized (pae) {
8917            pae.result = extras;
8918            pae.haveResult = true;
8919            pae.notifyAll();
8920        }
8921    }
8922
8923    public void registerProcessObserver(IProcessObserver observer) {
8924        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8925                "registerProcessObserver()");
8926        synchronized (this) {
8927            mProcessObservers.register(observer);
8928        }
8929    }
8930
8931    @Override
8932    public void unregisterProcessObserver(IProcessObserver observer) {
8933        synchronized (this) {
8934            mProcessObservers.unregister(observer);
8935        }
8936    }
8937
8938    @Override
8939    public boolean convertFromTranslucent(IBinder token) {
8940        final long origId = Binder.clearCallingIdentity();
8941        try {
8942            synchronized (this) {
8943                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8944                if (r == null) {
8945                    return false;
8946                }
8947                if (r.changeWindowTranslucency(true)) {
8948                    mWindowManager.setAppFullscreen(token, true);
8949                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8950                    return true;
8951                }
8952                return false;
8953            }
8954        } finally {
8955            Binder.restoreCallingIdentity(origId);
8956        }
8957    }
8958
8959    @Override
8960    public boolean convertToTranslucent(IBinder token) {
8961        final long origId = Binder.clearCallingIdentity();
8962        try {
8963            synchronized (this) {
8964                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8965                if (r == null) {
8966                    return false;
8967                }
8968                if (r.changeWindowTranslucency(false)) {
8969                    r.task.stack.convertToTranslucent(r);
8970                    mWindowManager.setAppFullscreen(token, false);
8971                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8972                    return true;
8973                }
8974                return false;
8975            }
8976        } finally {
8977            Binder.restoreCallingIdentity(origId);
8978        }
8979    }
8980
8981    @Override
8982    public void setImmersive(IBinder token, boolean immersive) {
8983        synchronized(this) {
8984            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8985            if (r == null) {
8986                throw new IllegalArgumentException();
8987            }
8988            r.immersive = immersive;
8989
8990            // update associated state if we're frontmost
8991            if (r == mFocusedActivity) {
8992                if (DEBUG_IMMERSIVE) {
8993                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8994                }
8995                applyUpdateLockStateLocked(r);
8996            }
8997        }
8998    }
8999
9000    @Override
9001    public boolean isImmersive(IBinder token) {
9002        synchronized (this) {
9003            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9004            if (r == null) {
9005                throw new IllegalArgumentException();
9006            }
9007            return r.immersive;
9008        }
9009    }
9010
9011    public boolean isTopActivityImmersive() {
9012        enforceNotIsolatedCaller("startActivity");
9013        synchronized (this) {
9014            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9015            return (r != null) ? r.immersive : false;
9016        }
9017    }
9018
9019    public final void enterSafeMode() {
9020        synchronized(this) {
9021            // It only makes sense to do this before the system is ready
9022            // and started launching other packages.
9023            if (!mSystemReady) {
9024                try {
9025                    AppGlobals.getPackageManager().enterSafeMode();
9026                } catch (RemoteException e) {
9027                }
9028            }
9029
9030            mSafeMode = true;
9031        }
9032    }
9033
9034    public final void showSafeModeOverlay() {
9035        View v = LayoutInflater.from(mContext).inflate(
9036                com.android.internal.R.layout.safe_mode, null);
9037        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9038        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9039        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9040        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9041        lp.gravity = Gravity.BOTTOM | Gravity.START;
9042        lp.format = v.getBackground().getOpacity();
9043        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9044                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9045        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9046        ((WindowManager)mContext.getSystemService(
9047                Context.WINDOW_SERVICE)).addView(v, lp);
9048    }
9049
9050    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9051        if (!(sender instanceof PendingIntentRecord)) {
9052            return;
9053        }
9054        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9055        synchronized (stats) {
9056            if (mBatteryStatsService.isOnBattery()) {
9057                mBatteryStatsService.enforceCallingPermission();
9058                PendingIntentRecord rec = (PendingIntentRecord)sender;
9059                int MY_UID = Binder.getCallingUid();
9060                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9061                BatteryStatsImpl.Uid.Pkg pkg =
9062                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9063                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9064                pkg.incWakeupsLocked();
9065            }
9066        }
9067    }
9068
9069    public boolean killPids(int[] pids, String pReason, boolean secure) {
9070        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9071            throw new SecurityException("killPids only available to the system");
9072        }
9073        String reason = (pReason == null) ? "Unknown" : pReason;
9074        // XXX Note: don't acquire main activity lock here, because the window
9075        // manager calls in with its locks held.
9076
9077        boolean killed = false;
9078        synchronized (mPidsSelfLocked) {
9079            int[] types = new int[pids.length];
9080            int worstType = 0;
9081            for (int i=0; i<pids.length; i++) {
9082                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9083                if (proc != null) {
9084                    int type = proc.setAdj;
9085                    types[i] = type;
9086                    if (type > worstType) {
9087                        worstType = type;
9088                    }
9089                }
9090            }
9091
9092            // If the worst oom_adj is somewhere in the cached proc LRU range,
9093            // then constrain it so we will kill all cached procs.
9094            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9095                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9096                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9097            }
9098
9099            // If this is not a secure call, don't let it kill processes that
9100            // are important.
9101            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9102                worstType = ProcessList.SERVICE_ADJ;
9103            }
9104
9105            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9106            for (int i=0; i<pids.length; i++) {
9107                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9108                if (proc == null) {
9109                    continue;
9110                }
9111                int adj = proc.setAdj;
9112                if (adj >= worstType && !proc.killedByAm) {
9113                    killUnneededProcessLocked(proc, reason);
9114                    killed = true;
9115                }
9116            }
9117        }
9118        return killed;
9119    }
9120
9121    @Override
9122    public void killUid(int uid, String reason) {
9123        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9124            throw new SecurityException("killUid only available to the system");
9125        }
9126        synchronized (this) {
9127            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9128                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9129                    reason != null ? reason : "kill uid");
9130        }
9131    }
9132
9133    @Override
9134    public boolean killProcessesBelowForeground(String reason) {
9135        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9136            throw new SecurityException("killProcessesBelowForeground() only available to system");
9137        }
9138
9139        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9140    }
9141
9142    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9143        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9144            throw new SecurityException("killProcessesBelowAdj() only available to system");
9145        }
9146
9147        boolean killed = false;
9148        synchronized (mPidsSelfLocked) {
9149            final int size = mPidsSelfLocked.size();
9150            for (int i = 0; i < size; i++) {
9151                final int pid = mPidsSelfLocked.keyAt(i);
9152                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9153                if (proc == null) continue;
9154
9155                final int adj = proc.setAdj;
9156                if (adj > belowAdj && !proc.killedByAm) {
9157                    killUnneededProcessLocked(proc, reason);
9158                    killed = true;
9159                }
9160            }
9161        }
9162        return killed;
9163    }
9164
9165    @Override
9166    public void hang(final IBinder who, boolean allowRestart) {
9167        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9168                != PackageManager.PERMISSION_GRANTED) {
9169            throw new SecurityException("Requires permission "
9170                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9171        }
9172
9173        final IBinder.DeathRecipient death = new DeathRecipient() {
9174            @Override
9175            public void binderDied() {
9176                synchronized (this) {
9177                    notifyAll();
9178                }
9179            }
9180        };
9181
9182        try {
9183            who.linkToDeath(death, 0);
9184        } catch (RemoteException e) {
9185            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9186            return;
9187        }
9188
9189        synchronized (this) {
9190            Watchdog.getInstance().setAllowRestart(allowRestart);
9191            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9192            synchronized (death) {
9193                while (who.isBinderAlive()) {
9194                    try {
9195                        death.wait();
9196                    } catch (InterruptedException e) {
9197                    }
9198                }
9199            }
9200            Watchdog.getInstance().setAllowRestart(true);
9201        }
9202    }
9203
9204    @Override
9205    public void restart() {
9206        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9207                != PackageManager.PERMISSION_GRANTED) {
9208            throw new SecurityException("Requires permission "
9209                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9210        }
9211
9212        Log.i(TAG, "Sending shutdown broadcast...");
9213
9214        BroadcastReceiver br = new BroadcastReceiver() {
9215            @Override public void onReceive(Context context, Intent intent) {
9216                // Now the broadcast is done, finish up the low-level shutdown.
9217                Log.i(TAG, "Shutting down activity manager...");
9218                shutdown(10000);
9219                Log.i(TAG, "Shutdown complete, restarting!");
9220                Process.killProcess(Process.myPid());
9221                System.exit(10);
9222            }
9223        };
9224
9225        // First send the high-level shut down broadcast.
9226        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9227        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9228        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9229        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9230        mContext.sendOrderedBroadcastAsUser(intent,
9231                UserHandle.ALL, null, br, mHandler, 0, null, null);
9232        */
9233        br.onReceive(mContext, intent);
9234    }
9235
9236    private long getLowRamTimeSinceIdle(long now) {
9237        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9238    }
9239
9240    @Override
9241    public void performIdleMaintenance() {
9242        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9243                != PackageManager.PERMISSION_GRANTED) {
9244            throw new SecurityException("Requires permission "
9245                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9246        }
9247
9248        synchronized (this) {
9249            final long now = SystemClock.uptimeMillis();
9250            final long timeSinceLastIdle = now - mLastIdleTime;
9251            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9252            mLastIdleTime = now;
9253            mLowRamTimeSinceLastIdle = 0;
9254            if (mLowRamStartTime != 0) {
9255                mLowRamStartTime = now;
9256            }
9257
9258            StringBuilder sb = new StringBuilder(128);
9259            sb.append("Idle maintenance over ");
9260            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9261            sb.append(" low RAM for ");
9262            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9263            Slog.i(TAG, sb.toString());
9264
9265            // If at least 1/3 of our time since the last idle period has been spent
9266            // with RAM low, then we want to kill processes.
9267            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9268
9269            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9270                ProcessRecord proc = mLruProcesses.get(i);
9271                if (proc.notCachedSinceIdle) {
9272                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9273                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9274                        if (doKilling && proc.initialIdlePss != 0
9275                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9276                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9277                                    + " from " + proc.initialIdlePss + ")");
9278                        }
9279                    }
9280                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9281                    proc.notCachedSinceIdle = true;
9282                    proc.initialIdlePss = 0;
9283                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9284                            mSleeping, now);
9285                }
9286            }
9287
9288            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9289            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9290        }
9291    }
9292
9293    private void retrieveSettings() {
9294        final ContentResolver resolver = mContext.getContentResolver();
9295        String debugApp = Settings.Global.getString(
9296            resolver, Settings.Global.DEBUG_APP);
9297        boolean waitForDebugger = Settings.Global.getInt(
9298            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9299        boolean alwaysFinishActivities = Settings.Global.getInt(
9300            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9301        boolean forceRtl = Settings.Global.getInt(
9302                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9303        // Transfer any global setting for forcing RTL layout, into a System Property
9304        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9305
9306        Configuration configuration = new Configuration();
9307        Settings.System.getConfiguration(resolver, configuration);
9308        if (forceRtl) {
9309            // This will take care of setting the correct layout direction flags
9310            configuration.setLayoutDirection(configuration.locale);
9311        }
9312
9313        synchronized (this) {
9314            mDebugApp = mOrigDebugApp = debugApp;
9315            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9316            mAlwaysFinishActivities = alwaysFinishActivities;
9317            // This happens before any activities are started, so we can
9318            // change mConfiguration in-place.
9319            updateConfigurationLocked(configuration, null, false, true);
9320            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9321        }
9322    }
9323
9324    public boolean testIsSystemReady() {
9325        // no need to synchronize(this) just to read & return the value
9326        return mSystemReady;
9327    }
9328
9329    private static File getCalledPreBootReceiversFile() {
9330        File dataDir = Environment.getDataDirectory();
9331        File systemDir = new File(dataDir, "system");
9332        File fname = new File(systemDir, "called_pre_boots.dat");
9333        return fname;
9334    }
9335
9336    static final int LAST_DONE_VERSION = 10000;
9337
9338    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9339        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9340        File file = getCalledPreBootReceiversFile();
9341        FileInputStream fis = null;
9342        try {
9343            fis = new FileInputStream(file);
9344            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9345            int fvers = dis.readInt();
9346            if (fvers == LAST_DONE_VERSION) {
9347                String vers = dis.readUTF();
9348                String codename = dis.readUTF();
9349                String build = dis.readUTF();
9350                if (android.os.Build.VERSION.RELEASE.equals(vers)
9351                        && android.os.Build.VERSION.CODENAME.equals(codename)
9352                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9353                    int num = dis.readInt();
9354                    while (num > 0) {
9355                        num--;
9356                        String pkg = dis.readUTF();
9357                        String cls = dis.readUTF();
9358                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9359                    }
9360                }
9361            }
9362        } catch (FileNotFoundException e) {
9363        } catch (IOException e) {
9364            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9365        } finally {
9366            if (fis != null) {
9367                try {
9368                    fis.close();
9369                } catch (IOException e) {
9370                }
9371            }
9372        }
9373        return lastDoneReceivers;
9374    }
9375
9376    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9377        File file = getCalledPreBootReceiversFile();
9378        FileOutputStream fos = null;
9379        DataOutputStream dos = null;
9380        try {
9381            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9382            fos = new FileOutputStream(file);
9383            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9384            dos.writeInt(LAST_DONE_VERSION);
9385            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9386            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9387            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9388            dos.writeInt(list.size());
9389            for (int i=0; i<list.size(); i++) {
9390                dos.writeUTF(list.get(i).getPackageName());
9391                dos.writeUTF(list.get(i).getClassName());
9392            }
9393        } catch (IOException e) {
9394            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9395            file.delete();
9396        } finally {
9397            FileUtils.sync(fos);
9398            if (dos != null) {
9399                try {
9400                    dos.close();
9401                } catch (IOException e) {
9402                    // TODO Auto-generated catch block
9403                    e.printStackTrace();
9404                }
9405            }
9406        }
9407    }
9408
9409    public void systemReady(final Runnable goingCallback) {
9410        synchronized(this) {
9411            if (mSystemReady) {
9412                if (goingCallback != null) goingCallback.run();
9413                return;
9414            }
9415
9416            // Check to see if there are any update receivers to run.
9417            if (!mDidUpdate) {
9418                if (mWaitingUpdate) {
9419                    return;
9420                }
9421                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9422                List<ResolveInfo> ris = null;
9423                try {
9424                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9425                            intent, null, 0, 0);
9426                } catch (RemoteException e) {
9427                }
9428                if (ris != null) {
9429                    for (int i=ris.size()-1; i>=0; i--) {
9430                        if ((ris.get(i).activityInfo.applicationInfo.flags
9431                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9432                            ris.remove(i);
9433                        }
9434                    }
9435                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9436
9437                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9438
9439                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9440                    for (int i=0; i<ris.size(); i++) {
9441                        ActivityInfo ai = ris.get(i).activityInfo;
9442                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9443                        if (lastDoneReceivers.contains(comp)) {
9444                            // We already did the pre boot receiver for this app with the current
9445                            // platform version, so don't do it again...
9446                            ris.remove(i);
9447                            i--;
9448                            // ...however, do keep it as one that has been done, so we don't
9449                            // forget about it when rewriting the file of last done receivers.
9450                            doneReceivers.add(comp);
9451                        }
9452                    }
9453
9454                    final int[] users = getUsersLocked();
9455                    for (int i=0; i<ris.size(); i++) {
9456                        ActivityInfo ai = ris.get(i).activityInfo;
9457                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9458                        doneReceivers.add(comp);
9459                        intent.setComponent(comp);
9460                        for (int j=0; j<users.length; j++) {
9461                            IIntentReceiver finisher = null;
9462                            if (i == ris.size()-1 && j == users.length-1) {
9463                                finisher = new IIntentReceiver.Stub() {
9464                                    public void performReceive(Intent intent, int resultCode,
9465                                            String data, Bundle extras, boolean ordered,
9466                                            boolean sticky, int sendingUser) {
9467                                        // The raw IIntentReceiver interface is called
9468                                        // with the AM lock held, so redispatch to
9469                                        // execute our code without the lock.
9470                                        mHandler.post(new Runnable() {
9471                                            public void run() {
9472                                                synchronized (ActivityManagerService.this) {
9473                                                    mDidUpdate = true;
9474                                                }
9475                                                writeLastDonePreBootReceivers(doneReceivers);
9476                                                showBootMessage(mContext.getText(
9477                                                        R.string.android_upgrading_complete),
9478                                                        false);
9479                                                systemReady(goingCallback);
9480                                            }
9481                                        });
9482                                    }
9483                                };
9484                            }
9485                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9486                                    + " for user " + users[j]);
9487                            broadcastIntentLocked(null, null, intent, null, finisher,
9488                                    0, null, null, null, AppOpsManager.OP_NONE,
9489                                    true, false, MY_PID, Process.SYSTEM_UID,
9490                                    users[j]);
9491                            if (finisher != null) {
9492                                mWaitingUpdate = true;
9493                            }
9494                        }
9495                    }
9496                }
9497                if (mWaitingUpdate) {
9498                    return;
9499                }
9500                mDidUpdate = true;
9501            }
9502
9503            mAppOpsService.systemReady();
9504            mSystemReady = true;
9505        }
9506
9507        ArrayList<ProcessRecord> procsToKill = null;
9508        synchronized(mPidsSelfLocked) {
9509            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9510                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9511                if (!isAllowedWhileBooting(proc.info)){
9512                    if (procsToKill == null) {
9513                        procsToKill = new ArrayList<ProcessRecord>();
9514                    }
9515                    procsToKill.add(proc);
9516                }
9517            }
9518        }
9519
9520        synchronized(this) {
9521            if (procsToKill != null) {
9522                for (int i=procsToKill.size()-1; i>=0; i--) {
9523                    ProcessRecord proc = procsToKill.get(i);
9524                    Slog.i(TAG, "Removing system update proc: " + proc);
9525                    removeProcessLocked(proc, true, false, "system update done");
9526                }
9527            }
9528
9529            // Now that we have cleaned up any update processes, we
9530            // are ready to start launching real processes and know that
9531            // we won't trample on them any more.
9532            mProcessesReady = true;
9533        }
9534
9535        Slog.i(TAG, "System now ready");
9536        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9537            SystemClock.uptimeMillis());
9538
9539        synchronized(this) {
9540            // Make sure we have no pre-ready processes sitting around.
9541
9542            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9543                ResolveInfo ri = mContext.getPackageManager()
9544                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9545                                STOCK_PM_FLAGS);
9546                CharSequence errorMsg = null;
9547                if (ri != null) {
9548                    ActivityInfo ai = ri.activityInfo;
9549                    ApplicationInfo app = ai.applicationInfo;
9550                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9551                        mTopAction = Intent.ACTION_FACTORY_TEST;
9552                        mTopData = null;
9553                        mTopComponent = new ComponentName(app.packageName,
9554                                ai.name);
9555                    } else {
9556                        errorMsg = mContext.getResources().getText(
9557                                com.android.internal.R.string.factorytest_not_system);
9558                    }
9559                } else {
9560                    errorMsg = mContext.getResources().getText(
9561                            com.android.internal.R.string.factorytest_no_action);
9562                }
9563                if (errorMsg != null) {
9564                    mTopAction = null;
9565                    mTopData = null;
9566                    mTopComponent = null;
9567                    Message msg = Message.obtain();
9568                    msg.what = SHOW_FACTORY_ERROR_MSG;
9569                    msg.getData().putCharSequence("msg", errorMsg);
9570                    mHandler.sendMessage(msg);
9571                }
9572            }
9573        }
9574
9575        retrieveSettings();
9576
9577        synchronized (this) {
9578            readGrantedUriPermissionsLocked();
9579        }
9580
9581        if (goingCallback != null) goingCallback.run();
9582
9583        synchronized (this) {
9584            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9585                try {
9586                    List apps = AppGlobals.getPackageManager().
9587                        getPersistentApplications(STOCK_PM_FLAGS);
9588                    if (apps != null) {
9589                        int N = apps.size();
9590                        int i;
9591                        for (i=0; i<N; i++) {
9592                            ApplicationInfo info
9593                                = (ApplicationInfo)apps.get(i);
9594                            if (info != null &&
9595                                    !info.packageName.equals("android")) {
9596                                addAppLocked(info, false);
9597                            }
9598                        }
9599                    }
9600                } catch (RemoteException ex) {
9601                    // pm is in same process, this will never happen.
9602                }
9603            }
9604
9605            // Start up initial activity.
9606            mBooting = true;
9607
9608            try {
9609                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9610                    Message msg = Message.obtain();
9611                    msg.what = SHOW_UID_ERROR_MSG;
9612                    mHandler.sendMessage(msg);
9613                }
9614            } catch (RemoteException e) {
9615            }
9616
9617            long ident = Binder.clearCallingIdentity();
9618            try {
9619                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9620                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9621                        | Intent.FLAG_RECEIVER_FOREGROUND);
9622                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9623                broadcastIntentLocked(null, null, intent,
9624                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9625                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9626                intent = new Intent(Intent.ACTION_USER_STARTING);
9627                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9628                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9629                broadcastIntentLocked(null, null, intent,
9630                        null, new IIntentReceiver.Stub() {
9631                            @Override
9632                            public void performReceive(Intent intent, int resultCode, String data,
9633                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9634                                    throws RemoteException {
9635                            }
9636                        }, 0, null, null,
9637                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9638                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9639            } finally {
9640                Binder.restoreCallingIdentity(ident);
9641            }
9642            mStackSupervisor.resumeTopActivitiesLocked();
9643            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9644        }
9645    }
9646
9647    private boolean makeAppCrashingLocked(ProcessRecord app,
9648            String shortMsg, String longMsg, String stackTrace) {
9649        app.crashing = true;
9650        app.crashingReport = generateProcessError(app,
9651                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9652        startAppProblemLocked(app);
9653        app.stopFreezingAllLocked();
9654        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9655    }
9656
9657    private void makeAppNotRespondingLocked(ProcessRecord app,
9658            String activity, String shortMsg, String longMsg) {
9659        app.notResponding = true;
9660        app.notRespondingReport = generateProcessError(app,
9661                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9662                activity, shortMsg, longMsg, null);
9663        startAppProblemLocked(app);
9664        app.stopFreezingAllLocked();
9665    }
9666
9667    /**
9668     * Generate a process error record, suitable for attachment to a ProcessRecord.
9669     *
9670     * @param app The ProcessRecord in which the error occurred.
9671     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9672     *                      ActivityManager.AppErrorStateInfo
9673     * @param activity The activity associated with the crash, if known.
9674     * @param shortMsg Short message describing the crash.
9675     * @param longMsg Long message describing the crash.
9676     * @param stackTrace Full crash stack trace, may be null.
9677     *
9678     * @return Returns a fully-formed AppErrorStateInfo record.
9679     */
9680    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9681            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9682        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9683
9684        report.condition = condition;
9685        report.processName = app.processName;
9686        report.pid = app.pid;
9687        report.uid = app.info.uid;
9688        report.tag = activity;
9689        report.shortMsg = shortMsg;
9690        report.longMsg = longMsg;
9691        report.stackTrace = stackTrace;
9692
9693        return report;
9694    }
9695
9696    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9697        synchronized (this) {
9698            app.crashing = false;
9699            app.crashingReport = null;
9700            app.notResponding = false;
9701            app.notRespondingReport = null;
9702            if (app.anrDialog == fromDialog) {
9703                app.anrDialog = null;
9704            }
9705            if (app.waitDialog == fromDialog) {
9706                app.waitDialog = null;
9707            }
9708            if (app.pid > 0 && app.pid != MY_PID) {
9709                handleAppCrashLocked(app, null, null, null);
9710                killUnneededProcessLocked(app, "user request after error");
9711            }
9712        }
9713    }
9714
9715    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9716            String stackTrace) {
9717        long now = SystemClock.uptimeMillis();
9718
9719        Long crashTime;
9720        if (!app.isolated) {
9721            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9722        } else {
9723            crashTime = null;
9724        }
9725        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9726            // This process loses!
9727            Slog.w(TAG, "Process " + app.info.processName
9728                    + " has crashed too many times: killing!");
9729            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9730                    app.userId, app.info.processName, app.uid);
9731            mStackSupervisor.handleAppCrashLocked(app);
9732            if (!app.persistent) {
9733                // We don't want to start this process again until the user
9734                // explicitly does so...  but for persistent process, we really
9735                // need to keep it running.  If a persistent process is actually
9736                // repeatedly crashing, then badness for everyone.
9737                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9738                        app.info.processName);
9739                if (!app.isolated) {
9740                    // XXX We don't have a way to mark isolated processes
9741                    // as bad, since they don't have a peristent identity.
9742                    mBadProcesses.put(app.info.processName, app.uid,
9743                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9744                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9745                }
9746                app.bad = true;
9747                app.removed = true;
9748                // Don't let services in this process be restarted and potentially
9749                // annoy the user repeatedly.  Unless it is persistent, since those
9750                // processes run critical code.
9751                removeProcessLocked(app, false, false, "crash");
9752                mStackSupervisor.resumeTopActivitiesLocked();
9753                return false;
9754            }
9755            mStackSupervisor.resumeTopActivitiesLocked();
9756        } else {
9757            mStackSupervisor.finishTopRunningActivityLocked(app);
9758        }
9759
9760        // Bump up the crash count of any services currently running in the proc.
9761        for (int i=app.services.size()-1; i>=0; i--) {
9762            // Any services running in the application need to be placed
9763            // back in the pending list.
9764            ServiceRecord sr = app.services.valueAt(i);
9765            sr.crashCount++;
9766        }
9767
9768        // If the crashing process is what we consider to be the "home process" and it has been
9769        // replaced by a third-party app, clear the package preferred activities from packages
9770        // with a home activity running in the process to prevent a repeatedly crashing app
9771        // from blocking the user to manually clear the list.
9772        final ArrayList<ActivityRecord> activities = app.activities;
9773        if (app == mHomeProcess && activities.size() > 0
9774                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9775            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9776                final ActivityRecord r = activities.get(activityNdx);
9777                if (r.isHomeActivity()) {
9778                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9779                    try {
9780                        ActivityThread.getPackageManager()
9781                                .clearPackagePreferredActivities(r.packageName);
9782                    } catch (RemoteException c) {
9783                        // pm is in same process, this will never happen.
9784                    }
9785                }
9786            }
9787        }
9788
9789        if (!app.isolated) {
9790            // XXX Can't keep track of crash times for isolated processes,
9791            // because they don't have a perisistent identity.
9792            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9793        }
9794
9795        return true;
9796    }
9797
9798    void startAppProblemLocked(ProcessRecord app) {
9799        if (app.userId == mCurrentUserId) {
9800            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9801                    mContext, app.info.packageName, app.info.flags);
9802        } else {
9803            // If this app is not running under the current user, then we
9804            // can't give it a report button because that would require
9805            // launching the report UI under a different user.
9806            app.errorReportReceiver = null;
9807        }
9808        skipCurrentReceiverLocked(app);
9809    }
9810
9811    void skipCurrentReceiverLocked(ProcessRecord app) {
9812        for (BroadcastQueue queue : mBroadcastQueues) {
9813            queue.skipCurrentReceiverLocked(app);
9814        }
9815    }
9816
9817    /**
9818     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9819     * The application process will exit immediately after this call returns.
9820     * @param app object of the crashing app, null for the system server
9821     * @param crashInfo describing the exception
9822     */
9823    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9824        ProcessRecord r = findAppProcess(app, "Crash");
9825        final String processName = app == null ? "system_server"
9826                : (r == null ? "unknown" : r.processName);
9827
9828        handleApplicationCrashInner("crash", r, processName, crashInfo);
9829    }
9830
9831    /* Native crash reporting uses this inner version because it needs to be somewhat
9832     * decoupled from the AM-managed cleanup lifecycle
9833     */
9834    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9835            ApplicationErrorReport.CrashInfo crashInfo) {
9836        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9837                UserHandle.getUserId(Binder.getCallingUid()), processName,
9838                r == null ? -1 : r.info.flags,
9839                crashInfo.exceptionClassName,
9840                crashInfo.exceptionMessage,
9841                crashInfo.throwFileName,
9842                crashInfo.throwLineNumber);
9843
9844        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9845
9846        crashApplication(r, crashInfo);
9847    }
9848
9849    public void handleApplicationStrictModeViolation(
9850            IBinder app,
9851            int violationMask,
9852            StrictMode.ViolationInfo info) {
9853        ProcessRecord r = findAppProcess(app, "StrictMode");
9854        if (r == null) {
9855            return;
9856        }
9857
9858        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9859            Integer stackFingerprint = info.hashCode();
9860            boolean logIt = true;
9861            synchronized (mAlreadyLoggedViolatedStacks) {
9862                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9863                    logIt = false;
9864                    // TODO: sub-sample into EventLog for these, with
9865                    // the info.durationMillis?  Then we'd get
9866                    // the relative pain numbers, without logging all
9867                    // the stack traces repeatedly.  We'd want to do
9868                    // likewise in the client code, which also does
9869                    // dup suppression, before the Binder call.
9870                } else {
9871                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9872                        mAlreadyLoggedViolatedStacks.clear();
9873                    }
9874                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9875                }
9876            }
9877            if (logIt) {
9878                logStrictModeViolationToDropBox(r, info);
9879            }
9880        }
9881
9882        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9883            AppErrorResult result = new AppErrorResult();
9884            synchronized (this) {
9885                final long origId = Binder.clearCallingIdentity();
9886
9887                Message msg = Message.obtain();
9888                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9889                HashMap<String, Object> data = new HashMap<String, Object>();
9890                data.put("result", result);
9891                data.put("app", r);
9892                data.put("violationMask", violationMask);
9893                data.put("info", info);
9894                msg.obj = data;
9895                mHandler.sendMessage(msg);
9896
9897                Binder.restoreCallingIdentity(origId);
9898            }
9899            int res = result.get();
9900            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9901        }
9902    }
9903
9904    // Depending on the policy in effect, there could be a bunch of
9905    // these in quick succession so we try to batch these together to
9906    // minimize disk writes, number of dropbox entries, and maximize
9907    // compression, by having more fewer, larger records.
9908    private void logStrictModeViolationToDropBox(
9909            ProcessRecord process,
9910            StrictMode.ViolationInfo info) {
9911        if (info == null) {
9912            return;
9913        }
9914        final boolean isSystemApp = process == null ||
9915                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9916                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9917        final String processName = process == null ? "unknown" : process.processName;
9918        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9919        final DropBoxManager dbox = (DropBoxManager)
9920                mContext.getSystemService(Context.DROPBOX_SERVICE);
9921
9922        // Exit early if the dropbox isn't configured to accept this report type.
9923        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9924
9925        boolean bufferWasEmpty;
9926        boolean needsFlush;
9927        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9928        synchronized (sb) {
9929            bufferWasEmpty = sb.length() == 0;
9930            appendDropBoxProcessHeaders(process, processName, sb);
9931            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9932            sb.append("System-App: ").append(isSystemApp).append("\n");
9933            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9934            if (info.violationNumThisLoop != 0) {
9935                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9936            }
9937            if (info.numAnimationsRunning != 0) {
9938                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9939            }
9940            if (info.broadcastIntentAction != null) {
9941                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9942            }
9943            if (info.durationMillis != -1) {
9944                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9945            }
9946            if (info.numInstances != -1) {
9947                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9948            }
9949            if (info.tags != null) {
9950                for (String tag : info.tags) {
9951                    sb.append("Span-Tag: ").append(tag).append("\n");
9952                }
9953            }
9954            sb.append("\n");
9955            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9956                sb.append(info.crashInfo.stackTrace);
9957            }
9958            sb.append("\n");
9959
9960            // Only buffer up to ~64k.  Various logging bits truncate
9961            // things at 128k.
9962            needsFlush = (sb.length() > 64 * 1024);
9963        }
9964
9965        // Flush immediately if the buffer's grown too large, or this
9966        // is a non-system app.  Non-system apps are isolated with a
9967        // different tag & policy and not batched.
9968        //
9969        // Batching is useful during internal testing with
9970        // StrictMode settings turned up high.  Without batching,
9971        // thousands of separate files could be created on boot.
9972        if (!isSystemApp || needsFlush) {
9973            new Thread("Error dump: " + dropboxTag) {
9974                @Override
9975                public void run() {
9976                    String report;
9977                    synchronized (sb) {
9978                        report = sb.toString();
9979                        sb.delete(0, sb.length());
9980                        sb.trimToSize();
9981                    }
9982                    if (report.length() != 0) {
9983                        dbox.addText(dropboxTag, report);
9984                    }
9985                }
9986            }.start();
9987            return;
9988        }
9989
9990        // System app batching:
9991        if (!bufferWasEmpty) {
9992            // An existing dropbox-writing thread is outstanding, so
9993            // we don't need to start it up.  The existing thread will
9994            // catch the buffer appends we just did.
9995            return;
9996        }
9997
9998        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9999        // (After this point, we shouldn't access AMS internal data structures.)
10000        new Thread("Error dump: " + dropboxTag) {
10001            @Override
10002            public void run() {
10003                // 5 second sleep to let stacks arrive and be batched together
10004                try {
10005                    Thread.sleep(5000);  // 5 seconds
10006                } catch (InterruptedException e) {}
10007
10008                String errorReport;
10009                synchronized (mStrictModeBuffer) {
10010                    errorReport = mStrictModeBuffer.toString();
10011                    if (errorReport.length() == 0) {
10012                        return;
10013                    }
10014                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10015                    mStrictModeBuffer.trimToSize();
10016                }
10017                dbox.addText(dropboxTag, errorReport);
10018            }
10019        }.start();
10020    }
10021
10022    /**
10023     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10024     * @param app object of the crashing app, null for the system server
10025     * @param tag reported by the caller
10026     * @param crashInfo describing the context of the error
10027     * @return true if the process should exit immediately (WTF is fatal)
10028     */
10029    public boolean handleApplicationWtf(IBinder app, String tag,
10030            ApplicationErrorReport.CrashInfo crashInfo) {
10031        ProcessRecord r = findAppProcess(app, "WTF");
10032        final String processName = app == null ? "system_server"
10033                : (r == null ? "unknown" : r.processName);
10034
10035        EventLog.writeEvent(EventLogTags.AM_WTF,
10036                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10037                processName,
10038                r == null ? -1 : r.info.flags,
10039                tag, crashInfo.exceptionMessage);
10040
10041        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10042
10043        if (r != null && r.pid != Process.myPid() &&
10044                Settings.Global.getInt(mContext.getContentResolver(),
10045                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10046            crashApplication(r, crashInfo);
10047            return true;
10048        } else {
10049            return false;
10050        }
10051    }
10052
10053    /**
10054     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10055     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10056     */
10057    private ProcessRecord findAppProcess(IBinder app, String reason) {
10058        if (app == null) {
10059            return null;
10060        }
10061
10062        synchronized (this) {
10063            final int NP = mProcessNames.getMap().size();
10064            for (int ip=0; ip<NP; ip++) {
10065                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10066                final int NA = apps.size();
10067                for (int ia=0; ia<NA; ia++) {
10068                    ProcessRecord p = apps.valueAt(ia);
10069                    if (p.thread != null && p.thread.asBinder() == app) {
10070                        return p;
10071                    }
10072                }
10073            }
10074
10075            Slog.w(TAG, "Can't find mystery application for " + reason
10076                    + " from pid=" + Binder.getCallingPid()
10077                    + " uid=" + Binder.getCallingUid() + ": " + app);
10078            return null;
10079        }
10080    }
10081
10082    /**
10083     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10084     * to append various headers to the dropbox log text.
10085     */
10086    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10087            StringBuilder sb) {
10088        // Watchdog thread ends up invoking this function (with
10089        // a null ProcessRecord) to add the stack file to dropbox.
10090        // Do not acquire a lock on this (am) in such cases, as it
10091        // could cause a potential deadlock, if and when watchdog
10092        // is invoked due to unavailability of lock on am and it
10093        // would prevent watchdog from killing system_server.
10094        if (process == null) {
10095            sb.append("Process: ").append(processName).append("\n");
10096            return;
10097        }
10098        // Note: ProcessRecord 'process' is guarded by the service
10099        // instance.  (notably process.pkgList, which could otherwise change
10100        // concurrently during execution of this method)
10101        synchronized (this) {
10102            sb.append("Process: ").append(processName).append("\n");
10103            int flags = process.info.flags;
10104            IPackageManager pm = AppGlobals.getPackageManager();
10105            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10106            for (int ip=0; ip<process.pkgList.size(); ip++) {
10107                String pkg = process.pkgList.keyAt(ip);
10108                sb.append("Package: ").append(pkg);
10109                try {
10110                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10111                    if (pi != null) {
10112                        sb.append(" v").append(pi.versionCode);
10113                        if (pi.versionName != null) {
10114                            sb.append(" (").append(pi.versionName).append(")");
10115                        }
10116                    }
10117                } catch (RemoteException e) {
10118                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10119                }
10120                sb.append("\n");
10121            }
10122        }
10123    }
10124
10125    private static String processClass(ProcessRecord process) {
10126        if (process == null || process.pid == MY_PID) {
10127            return "system_server";
10128        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10129            return "system_app";
10130        } else {
10131            return "data_app";
10132        }
10133    }
10134
10135    /**
10136     * Write a description of an error (crash, WTF, ANR) to the drop box.
10137     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10138     * @param process which caused the error, null means the system server
10139     * @param activity which triggered the error, null if unknown
10140     * @param parent activity related to the error, null if unknown
10141     * @param subject line related to the error, null if absent
10142     * @param report in long form describing the error, null if absent
10143     * @param logFile to include in the report, null if none
10144     * @param crashInfo giving an application stack trace, null if absent
10145     */
10146    public void addErrorToDropBox(String eventType,
10147            ProcessRecord process, String processName, ActivityRecord activity,
10148            ActivityRecord parent, String subject,
10149            final String report, final File logFile,
10150            final ApplicationErrorReport.CrashInfo crashInfo) {
10151        // NOTE -- this must never acquire the ActivityManagerService lock,
10152        // otherwise the watchdog may be prevented from resetting the system.
10153
10154        final String dropboxTag = processClass(process) + "_" + eventType;
10155        final DropBoxManager dbox = (DropBoxManager)
10156                mContext.getSystemService(Context.DROPBOX_SERVICE);
10157
10158        // Exit early if the dropbox isn't configured to accept this report type.
10159        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10160
10161        final StringBuilder sb = new StringBuilder(1024);
10162        appendDropBoxProcessHeaders(process, processName, sb);
10163        if (activity != null) {
10164            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10165        }
10166        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10167            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10168        }
10169        if (parent != null && parent != activity) {
10170            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10171        }
10172        if (subject != null) {
10173            sb.append("Subject: ").append(subject).append("\n");
10174        }
10175        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10176        if (Debug.isDebuggerConnected()) {
10177            sb.append("Debugger: Connected\n");
10178        }
10179        sb.append("\n");
10180
10181        // Do the rest in a worker thread to avoid blocking the caller on I/O
10182        // (After this point, we shouldn't access AMS internal data structures.)
10183        Thread worker = new Thread("Error dump: " + dropboxTag) {
10184            @Override
10185            public void run() {
10186                if (report != null) {
10187                    sb.append(report);
10188                }
10189                if (logFile != null) {
10190                    try {
10191                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10192                                    "\n\n[[TRUNCATED]]"));
10193                    } catch (IOException e) {
10194                        Slog.e(TAG, "Error reading " + logFile, e);
10195                    }
10196                }
10197                if (crashInfo != null && crashInfo.stackTrace != null) {
10198                    sb.append(crashInfo.stackTrace);
10199                }
10200
10201                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10202                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10203                if (lines > 0) {
10204                    sb.append("\n");
10205
10206                    // Merge several logcat streams, and take the last N lines
10207                    InputStreamReader input = null;
10208                    try {
10209                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10210                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10211                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10212
10213                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10214                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10215                        input = new InputStreamReader(logcat.getInputStream());
10216
10217                        int num;
10218                        char[] buf = new char[8192];
10219                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10220                    } catch (IOException e) {
10221                        Slog.e(TAG, "Error running logcat", e);
10222                    } finally {
10223                        if (input != null) try { input.close(); } catch (IOException e) {}
10224                    }
10225                }
10226
10227                dbox.addText(dropboxTag, sb.toString());
10228            }
10229        };
10230
10231        if (process == null) {
10232            // If process is null, we are being called from some internal code
10233            // and may be about to die -- run this synchronously.
10234            worker.run();
10235        } else {
10236            worker.start();
10237        }
10238    }
10239
10240    /**
10241     * Bring up the "unexpected error" dialog box for a crashing app.
10242     * Deal with edge cases (intercepts from instrumented applications,
10243     * ActivityController, error intent receivers, that sort of thing).
10244     * @param r the application crashing
10245     * @param crashInfo describing the failure
10246     */
10247    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10248        long timeMillis = System.currentTimeMillis();
10249        String shortMsg = crashInfo.exceptionClassName;
10250        String longMsg = crashInfo.exceptionMessage;
10251        String stackTrace = crashInfo.stackTrace;
10252        if (shortMsg != null && longMsg != null) {
10253            longMsg = shortMsg + ": " + longMsg;
10254        } else if (shortMsg != null) {
10255            longMsg = shortMsg;
10256        }
10257
10258        AppErrorResult result = new AppErrorResult();
10259        synchronized (this) {
10260            if (mController != null) {
10261                try {
10262                    String name = r != null ? r.processName : null;
10263                    int pid = r != null ? r.pid : Binder.getCallingPid();
10264                    if (!mController.appCrashed(name, pid,
10265                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10266                        Slog.w(TAG, "Force-killing crashed app " + name
10267                                + " at watcher's request");
10268                        Process.killProcess(pid);
10269                        return;
10270                    }
10271                } catch (RemoteException e) {
10272                    mController = null;
10273                    Watchdog.getInstance().setActivityController(null);
10274                }
10275            }
10276
10277            final long origId = Binder.clearCallingIdentity();
10278
10279            // If this process is running instrumentation, finish it.
10280            if (r != null && r.instrumentationClass != null) {
10281                Slog.w(TAG, "Error in app " + r.processName
10282                      + " running instrumentation " + r.instrumentationClass + ":");
10283                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10284                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10285                Bundle info = new Bundle();
10286                info.putString("shortMsg", shortMsg);
10287                info.putString("longMsg", longMsg);
10288                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10289                Binder.restoreCallingIdentity(origId);
10290                return;
10291            }
10292
10293            // If we can't identify the process or it's already exceeded its crash quota,
10294            // quit right away without showing a crash dialog.
10295            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10296                Binder.restoreCallingIdentity(origId);
10297                return;
10298            }
10299
10300            Message msg = Message.obtain();
10301            msg.what = SHOW_ERROR_MSG;
10302            HashMap data = new HashMap();
10303            data.put("result", result);
10304            data.put("app", r);
10305            msg.obj = data;
10306            mHandler.sendMessage(msg);
10307
10308            Binder.restoreCallingIdentity(origId);
10309        }
10310
10311        int res = result.get();
10312
10313        Intent appErrorIntent = null;
10314        synchronized (this) {
10315            if (r != null && !r.isolated) {
10316                // XXX Can't keep track of crash time for isolated processes,
10317                // since they don't have a persistent identity.
10318                mProcessCrashTimes.put(r.info.processName, r.uid,
10319                        SystemClock.uptimeMillis());
10320            }
10321            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10322                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10323            }
10324        }
10325
10326        if (appErrorIntent != null) {
10327            try {
10328                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10329            } catch (ActivityNotFoundException e) {
10330                Slog.w(TAG, "bug report receiver dissappeared", e);
10331            }
10332        }
10333    }
10334
10335    Intent createAppErrorIntentLocked(ProcessRecord r,
10336            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10337        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10338        if (report == null) {
10339            return null;
10340        }
10341        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10342        result.setComponent(r.errorReportReceiver);
10343        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10344        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10345        return result;
10346    }
10347
10348    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10349            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10350        if (r.errorReportReceiver == null) {
10351            return null;
10352        }
10353
10354        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10355            return null;
10356        }
10357
10358        ApplicationErrorReport report = new ApplicationErrorReport();
10359        report.packageName = r.info.packageName;
10360        report.installerPackageName = r.errorReportReceiver.getPackageName();
10361        report.processName = r.processName;
10362        report.time = timeMillis;
10363        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10364
10365        if (r.crashing || r.forceCrashReport) {
10366            report.type = ApplicationErrorReport.TYPE_CRASH;
10367            report.crashInfo = crashInfo;
10368        } else if (r.notResponding) {
10369            report.type = ApplicationErrorReport.TYPE_ANR;
10370            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10371
10372            report.anrInfo.activity = r.notRespondingReport.tag;
10373            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10374            report.anrInfo.info = r.notRespondingReport.longMsg;
10375        }
10376
10377        return report;
10378    }
10379
10380    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10381        enforceNotIsolatedCaller("getProcessesInErrorState");
10382        // assume our apps are happy - lazy create the list
10383        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10384
10385        final boolean allUsers = ActivityManager.checkUidPermission(
10386                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10387                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10388        int userId = UserHandle.getUserId(Binder.getCallingUid());
10389
10390        synchronized (this) {
10391
10392            // iterate across all processes
10393            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10394                ProcessRecord app = mLruProcesses.get(i);
10395                if (!allUsers && app.userId != userId) {
10396                    continue;
10397                }
10398                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10399                    // This one's in trouble, so we'll generate a report for it
10400                    // crashes are higher priority (in case there's a crash *and* an anr)
10401                    ActivityManager.ProcessErrorStateInfo report = null;
10402                    if (app.crashing) {
10403                        report = app.crashingReport;
10404                    } else if (app.notResponding) {
10405                        report = app.notRespondingReport;
10406                    }
10407
10408                    if (report != null) {
10409                        if (errList == null) {
10410                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10411                        }
10412                        errList.add(report);
10413                    } else {
10414                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10415                                " crashing = " + app.crashing +
10416                                " notResponding = " + app.notResponding);
10417                    }
10418                }
10419            }
10420        }
10421
10422        return errList;
10423    }
10424
10425    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10426        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10427            if (currApp != null) {
10428                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10429            }
10430            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10431        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10432            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10433        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10434            if (currApp != null) {
10435                currApp.lru = 0;
10436            }
10437            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10438        } else if (adj >= ProcessList.SERVICE_ADJ) {
10439            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10440        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10441            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10442        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10443            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10444        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10445            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10446        } else {
10447            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10448        }
10449    }
10450
10451    private void fillInProcMemInfo(ProcessRecord app,
10452            ActivityManager.RunningAppProcessInfo outInfo) {
10453        outInfo.pid = app.pid;
10454        outInfo.uid = app.info.uid;
10455        if (mHeavyWeightProcess == app) {
10456            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10457        }
10458        if (app.persistent) {
10459            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10460        }
10461        if (app.activities.size() > 0) {
10462            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10463        }
10464        outInfo.lastTrimLevel = app.trimMemoryLevel;
10465        int adj = app.curAdj;
10466        outInfo.importance = oomAdjToImportance(adj, outInfo);
10467        outInfo.importanceReasonCode = app.adjTypeCode;
10468    }
10469
10470    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10471        enforceNotIsolatedCaller("getRunningAppProcesses");
10472        // Lazy instantiation of list
10473        List<ActivityManager.RunningAppProcessInfo> runList = null;
10474        final boolean allUsers = ActivityManager.checkUidPermission(
10475                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10476                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10477        int userId = UserHandle.getUserId(Binder.getCallingUid());
10478        synchronized (this) {
10479            // Iterate across all processes
10480            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10481                ProcessRecord app = mLruProcesses.get(i);
10482                if (!allUsers && app.userId != userId) {
10483                    continue;
10484                }
10485                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10486                    // Generate process state info for running application
10487                    ActivityManager.RunningAppProcessInfo currApp =
10488                        new ActivityManager.RunningAppProcessInfo(app.processName,
10489                                app.pid, app.getPackageList());
10490                    fillInProcMemInfo(app, currApp);
10491                    if (app.adjSource instanceof ProcessRecord) {
10492                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10493                        currApp.importanceReasonImportance = oomAdjToImportance(
10494                                app.adjSourceOom, null);
10495                    } else if (app.adjSource instanceof ActivityRecord) {
10496                        ActivityRecord r = (ActivityRecord)app.adjSource;
10497                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10498                    }
10499                    if (app.adjTarget instanceof ComponentName) {
10500                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10501                    }
10502                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10503                    //        + " lru=" + currApp.lru);
10504                    if (runList == null) {
10505                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10506                    }
10507                    runList.add(currApp);
10508                }
10509            }
10510        }
10511        return runList;
10512    }
10513
10514    public List<ApplicationInfo> getRunningExternalApplications() {
10515        enforceNotIsolatedCaller("getRunningExternalApplications");
10516        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10517        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10518        if (runningApps != null && runningApps.size() > 0) {
10519            Set<String> extList = new HashSet<String>();
10520            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10521                if (app.pkgList != null) {
10522                    for (String pkg : app.pkgList) {
10523                        extList.add(pkg);
10524                    }
10525                }
10526            }
10527            IPackageManager pm = AppGlobals.getPackageManager();
10528            for (String pkg : extList) {
10529                try {
10530                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10531                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10532                        retList.add(info);
10533                    }
10534                } catch (RemoteException e) {
10535                }
10536            }
10537        }
10538        return retList;
10539    }
10540
10541    @Override
10542    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10543        enforceNotIsolatedCaller("getMyMemoryState");
10544        synchronized (this) {
10545            ProcessRecord proc;
10546            synchronized (mPidsSelfLocked) {
10547                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10548            }
10549            fillInProcMemInfo(proc, outInfo);
10550        }
10551    }
10552
10553    @Override
10554    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10555        if (checkCallingPermission(android.Manifest.permission.DUMP)
10556                != PackageManager.PERMISSION_GRANTED) {
10557            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10558                    + Binder.getCallingPid()
10559                    + ", uid=" + Binder.getCallingUid()
10560                    + " without permission "
10561                    + android.Manifest.permission.DUMP);
10562            return;
10563        }
10564
10565        boolean dumpAll = false;
10566        boolean dumpClient = false;
10567        String dumpPackage = null;
10568
10569        int opti = 0;
10570        while (opti < args.length) {
10571            String opt = args[opti];
10572            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10573                break;
10574            }
10575            opti++;
10576            if ("-a".equals(opt)) {
10577                dumpAll = true;
10578            } else if ("-c".equals(opt)) {
10579                dumpClient = true;
10580            } else if ("-h".equals(opt)) {
10581                pw.println("Activity manager dump options:");
10582                pw.println("  [-a] [-c] [-h] [cmd] ...");
10583                pw.println("  cmd may be one of:");
10584                pw.println("    a[ctivities]: activity stack state");
10585                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10586                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10587                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10588                pw.println("    o[om]: out of memory management");
10589                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10590                pw.println("    provider [COMP_SPEC]: provider client-side state");
10591                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10592                pw.println("    service [COMP_SPEC]: service client-side state");
10593                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10594                pw.println("    all: dump all activities");
10595                pw.println("    top: dump the top activity");
10596                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10597                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10598                pw.println("    a partial substring in a component name, a");
10599                pw.println("    hex object identifier.");
10600                pw.println("  -a: include all available server state.");
10601                pw.println("  -c: include client state.");
10602                return;
10603            } else {
10604                pw.println("Unknown argument: " + opt + "; use -h for help");
10605            }
10606        }
10607
10608        long origId = Binder.clearCallingIdentity();
10609        boolean more = false;
10610        // Is the caller requesting to dump a particular piece of data?
10611        if (opti < args.length) {
10612            String cmd = args[opti];
10613            opti++;
10614            if ("activities".equals(cmd) || "a".equals(cmd)) {
10615                synchronized (this) {
10616                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10617                }
10618            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10619                String[] newArgs;
10620                String name;
10621                if (opti >= args.length) {
10622                    name = null;
10623                    newArgs = EMPTY_STRING_ARRAY;
10624                } else {
10625                    name = args[opti];
10626                    opti++;
10627                    newArgs = new String[args.length - opti];
10628                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10629                            args.length - opti);
10630                }
10631                synchronized (this) {
10632                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10633                }
10634            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10635                String[] newArgs;
10636                String name;
10637                if (opti >= args.length) {
10638                    name = null;
10639                    newArgs = EMPTY_STRING_ARRAY;
10640                } else {
10641                    name = args[opti];
10642                    opti++;
10643                    newArgs = new String[args.length - opti];
10644                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10645                            args.length - opti);
10646                }
10647                synchronized (this) {
10648                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10649                }
10650            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10651                String[] newArgs;
10652                String name;
10653                if (opti >= args.length) {
10654                    name = null;
10655                    newArgs = EMPTY_STRING_ARRAY;
10656                } else {
10657                    name = args[opti];
10658                    opti++;
10659                    newArgs = new String[args.length - opti];
10660                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10661                            args.length - opti);
10662                }
10663                synchronized (this) {
10664                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10665                }
10666            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10667                synchronized (this) {
10668                    dumpOomLocked(fd, pw, args, opti, true);
10669                }
10670            } else if ("provider".equals(cmd)) {
10671                String[] newArgs;
10672                String name;
10673                if (opti >= args.length) {
10674                    name = null;
10675                    newArgs = EMPTY_STRING_ARRAY;
10676                } else {
10677                    name = args[opti];
10678                    opti++;
10679                    newArgs = new String[args.length - opti];
10680                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10681                }
10682                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10683                    pw.println("No providers match: " + name);
10684                    pw.println("Use -h for help.");
10685                }
10686            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10687                synchronized (this) {
10688                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10689                }
10690            } else if ("service".equals(cmd)) {
10691                String[] newArgs;
10692                String name;
10693                if (opti >= args.length) {
10694                    name = null;
10695                    newArgs = EMPTY_STRING_ARRAY;
10696                } else {
10697                    name = args[opti];
10698                    opti++;
10699                    newArgs = new String[args.length - opti];
10700                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10701                            args.length - opti);
10702                }
10703                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10704                    pw.println("No services match: " + name);
10705                    pw.println("Use -h for help.");
10706                }
10707            } else if ("package".equals(cmd)) {
10708                String[] newArgs;
10709                if (opti >= args.length) {
10710                    pw.println("package: no package name specified");
10711                    pw.println("Use -h for help.");
10712                } else {
10713                    dumpPackage = args[opti];
10714                    opti++;
10715                    newArgs = new String[args.length - opti];
10716                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10717                            args.length - opti);
10718                    args = newArgs;
10719                    opti = 0;
10720                    more = true;
10721                }
10722            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10723                synchronized (this) {
10724                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10725                }
10726            } else {
10727                // Dumping a single activity?
10728                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10729                    pw.println("Bad activity command, or no activities match: " + cmd);
10730                    pw.println("Use -h for help.");
10731                }
10732            }
10733            if (!more) {
10734                Binder.restoreCallingIdentity(origId);
10735                return;
10736            }
10737        }
10738
10739        // No piece of data specified, dump everything.
10740        synchronized (this) {
10741            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10742            pw.println();
10743            if (dumpAll) {
10744                pw.println("-------------------------------------------------------------------------------");
10745            }
10746            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10747            pw.println();
10748            if (dumpAll) {
10749                pw.println("-------------------------------------------------------------------------------");
10750            }
10751            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10752            pw.println();
10753            if (dumpAll) {
10754                pw.println("-------------------------------------------------------------------------------");
10755            }
10756            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10757            pw.println();
10758            if (dumpAll) {
10759                pw.println("-------------------------------------------------------------------------------");
10760            }
10761            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10762            pw.println();
10763            if (dumpAll) {
10764                pw.println("-------------------------------------------------------------------------------");
10765            }
10766            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10767        }
10768        Binder.restoreCallingIdentity(origId);
10769    }
10770
10771    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10772            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10773        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10774
10775        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10776                dumpPackage);
10777        boolean needSep = printedAnything;
10778
10779        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10780                dumpPackage, needSep, "  mFocusedActivity: ");
10781        if (printed) {
10782            printedAnything = true;
10783            needSep = false;
10784        }
10785
10786        if (dumpPackage == null) {
10787            if (needSep) {
10788                pw.println();
10789            }
10790            needSep = true;
10791            printedAnything = true;
10792            mStackSupervisor.dump(pw, "  ");
10793        }
10794
10795        if (mRecentTasks.size() > 0) {
10796            boolean printedHeader = false;
10797
10798            final int N = mRecentTasks.size();
10799            for (int i=0; i<N; i++) {
10800                TaskRecord tr = mRecentTasks.get(i);
10801                if (dumpPackage != null) {
10802                    if (tr.realActivity == null ||
10803                            !dumpPackage.equals(tr.realActivity)) {
10804                        continue;
10805                    }
10806                }
10807                if (!printedHeader) {
10808                    if (needSep) {
10809                        pw.println();
10810                    }
10811                    pw.println("  Recent tasks:");
10812                    printedHeader = true;
10813                    printedAnything = true;
10814                }
10815                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10816                        pw.println(tr);
10817                if (dumpAll) {
10818                    mRecentTasks.get(i).dump(pw, "    ");
10819                }
10820            }
10821        }
10822
10823        if (!printedAnything) {
10824            pw.println("  (nothing)");
10825        }
10826    }
10827
10828    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10829            int opti, boolean dumpAll, String dumpPackage) {
10830        boolean needSep = false;
10831        boolean printedAnything = false;
10832        int numPers = 0;
10833
10834        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10835
10836        if (dumpAll) {
10837            final int NP = mProcessNames.getMap().size();
10838            for (int ip=0; ip<NP; ip++) {
10839                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10840                final int NA = procs.size();
10841                for (int ia=0; ia<NA; ia++) {
10842                    ProcessRecord r = procs.valueAt(ia);
10843                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10844                        continue;
10845                    }
10846                    if (!needSep) {
10847                        pw.println("  All known processes:");
10848                        needSep = true;
10849                        printedAnything = true;
10850                    }
10851                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10852                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10853                        pw.print(" "); pw.println(r);
10854                    r.dump(pw, "    ");
10855                    if (r.persistent) {
10856                        numPers++;
10857                    }
10858                }
10859            }
10860        }
10861
10862        if (mIsolatedProcesses.size() > 0) {
10863            boolean printed = false;
10864            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10865                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10866                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10867                    continue;
10868                }
10869                if (!printed) {
10870                    if (needSep) {
10871                        pw.println();
10872                    }
10873                    pw.println("  Isolated process list (sorted by uid):");
10874                    printedAnything = true;
10875                    printed = true;
10876                    needSep = true;
10877                }
10878                pw.println(String.format("%sIsolated #%2d: %s",
10879                        "    ", i, r.toString()));
10880            }
10881        }
10882
10883        if (mLruProcesses.size() > 0) {
10884            if (needSep) {
10885                pw.println();
10886            }
10887            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10888                    pw.print(" total, non-act at ");
10889                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10890                    pw.print(", non-svc at ");
10891                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10892                    pw.println("):");
10893            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10894            needSep = true;
10895            printedAnything = true;
10896        }
10897
10898        if (dumpAll || dumpPackage != null) {
10899            synchronized (mPidsSelfLocked) {
10900                boolean printed = false;
10901                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10902                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10903                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10904                        continue;
10905                    }
10906                    if (!printed) {
10907                        if (needSep) pw.println();
10908                        needSep = true;
10909                        pw.println("  PID mappings:");
10910                        printed = true;
10911                        printedAnything = true;
10912                    }
10913                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10914                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10915                }
10916            }
10917        }
10918
10919        if (mForegroundProcesses.size() > 0) {
10920            synchronized (mPidsSelfLocked) {
10921                boolean printed = false;
10922                for (int i=0; i<mForegroundProcesses.size(); i++) {
10923                    ProcessRecord r = mPidsSelfLocked.get(
10924                            mForegroundProcesses.valueAt(i).pid);
10925                    if (dumpPackage != null && (r == null
10926                            || !r.pkgList.containsKey(dumpPackage))) {
10927                        continue;
10928                    }
10929                    if (!printed) {
10930                        if (needSep) pw.println();
10931                        needSep = true;
10932                        pw.println("  Foreground Processes:");
10933                        printed = true;
10934                        printedAnything = true;
10935                    }
10936                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10937                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10938                }
10939            }
10940        }
10941
10942        if (mPersistentStartingProcesses.size() > 0) {
10943            if (needSep) pw.println();
10944            needSep = true;
10945            printedAnything = true;
10946            pw.println("  Persisent processes that are starting:");
10947            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10948                    "Starting Norm", "Restarting PERS", dumpPackage);
10949        }
10950
10951        if (mRemovedProcesses.size() > 0) {
10952            if (needSep) pw.println();
10953            needSep = true;
10954            printedAnything = true;
10955            pw.println("  Processes that are being removed:");
10956            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10957                    "Removed Norm", "Removed PERS", dumpPackage);
10958        }
10959
10960        if (mProcessesOnHold.size() > 0) {
10961            if (needSep) pw.println();
10962            needSep = true;
10963            printedAnything = true;
10964            pw.println("  Processes that are on old until the system is ready:");
10965            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10966                    "OnHold Norm", "OnHold PERS", dumpPackage);
10967        }
10968
10969        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10970
10971        if (mProcessCrashTimes.getMap().size() > 0) {
10972            boolean printed = false;
10973            long now = SystemClock.uptimeMillis();
10974            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10975            final int NP = pmap.size();
10976            for (int ip=0; ip<NP; ip++) {
10977                String pname = pmap.keyAt(ip);
10978                SparseArray<Long> uids = pmap.valueAt(ip);
10979                final int N = uids.size();
10980                for (int i=0; i<N; i++) {
10981                    int puid = uids.keyAt(i);
10982                    ProcessRecord r = mProcessNames.get(pname, puid);
10983                    if (dumpPackage != null && (r == null
10984                            || !r.pkgList.containsKey(dumpPackage))) {
10985                        continue;
10986                    }
10987                    if (!printed) {
10988                        if (needSep) pw.println();
10989                        needSep = true;
10990                        pw.println("  Time since processes crashed:");
10991                        printed = true;
10992                        printedAnything = true;
10993                    }
10994                    pw.print("    Process "); pw.print(pname);
10995                            pw.print(" uid "); pw.print(puid);
10996                            pw.print(": last crashed ");
10997                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10998                            pw.println(" ago");
10999                }
11000            }
11001        }
11002
11003        if (mBadProcesses.getMap().size() > 0) {
11004            boolean printed = false;
11005            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11006            final int NP = pmap.size();
11007            for (int ip=0; ip<NP; ip++) {
11008                String pname = pmap.keyAt(ip);
11009                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11010                final int N = uids.size();
11011                for (int i=0; i<N; i++) {
11012                    int puid = uids.keyAt(i);
11013                    ProcessRecord r = mProcessNames.get(pname, puid);
11014                    if (dumpPackage != null && (r == null
11015                            || !r.pkgList.containsKey(dumpPackage))) {
11016                        continue;
11017                    }
11018                    if (!printed) {
11019                        if (needSep) pw.println();
11020                        needSep = true;
11021                        pw.println("  Bad processes:");
11022                        printedAnything = true;
11023                    }
11024                    BadProcessInfo info = uids.valueAt(i);
11025                    pw.print("    Bad process "); pw.print(pname);
11026                            pw.print(" uid "); pw.print(puid);
11027                            pw.print(": crashed at time "); pw.println(info.time);
11028                    if (info.shortMsg != null) {
11029                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11030                    }
11031                    if (info.longMsg != null) {
11032                        pw.print("      Long msg: "); pw.println(info.longMsg);
11033                    }
11034                    if (info.stack != null) {
11035                        pw.println("      Stack:");
11036                        int lastPos = 0;
11037                        for (int pos=0; pos<info.stack.length(); pos++) {
11038                            if (info.stack.charAt(pos) == '\n') {
11039                                pw.print("        ");
11040                                pw.write(info.stack, lastPos, pos-lastPos);
11041                                pw.println();
11042                                lastPos = pos+1;
11043                            }
11044                        }
11045                        if (lastPos < info.stack.length()) {
11046                            pw.print("        ");
11047                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11048                            pw.println();
11049                        }
11050                    }
11051                }
11052            }
11053        }
11054
11055        if (dumpPackage == null) {
11056            pw.println();
11057            needSep = false;
11058            pw.println("  mStartedUsers:");
11059            for (int i=0; i<mStartedUsers.size(); i++) {
11060                UserStartedState uss = mStartedUsers.valueAt(i);
11061                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11062                        pw.print(": "); uss.dump("", pw);
11063            }
11064            pw.print("  mStartedUserArray: [");
11065            for (int i=0; i<mStartedUserArray.length; i++) {
11066                if (i > 0) pw.print(", ");
11067                pw.print(mStartedUserArray[i]);
11068            }
11069            pw.println("]");
11070            pw.print("  mUserLru: [");
11071            for (int i=0; i<mUserLru.size(); i++) {
11072                if (i > 0) pw.print(", ");
11073                pw.print(mUserLru.get(i));
11074            }
11075            pw.println("]");
11076            if (dumpAll) {
11077                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11078            }
11079        }
11080        if (mHomeProcess != null && (dumpPackage == null
11081                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11082            if (needSep) {
11083                pw.println();
11084                needSep = false;
11085            }
11086            pw.println("  mHomeProcess: " + mHomeProcess);
11087        }
11088        if (mPreviousProcess != null && (dumpPackage == null
11089                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11090            if (needSep) {
11091                pw.println();
11092                needSep = false;
11093            }
11094            pw.println("  mPreviousProcess: " + mPreviousProcess);
11095        }
11096        if (dumpAll) {
11097            StringBuilder sb = new StringBuilder(128);
11098            sb.append("  mPreviousProcessVisibleTime: ");
11099            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11100            pw.println(sb);
11101        }
11102        if (mHeavyWeightProcess != null && (dumpPackage == null
11103                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11104            if (needSep) {
11105                pw.println();
11106                needSep = false;
11107            }
11108            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11109        }
11110        if (dumpPackage == null) {
11111            pw.println("  mConfiguration: " + mConfiguration);
11112        }
11113        if (dumpAll) {
11114            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11115            if (mCompatModePackages.getPackages().size() > 0) {
11116                boolean printed = false;
11117                for (Map.Entry<String, Integer> entry
11118                        : mCompatModePackages.getPackages().entrySet()) {
11119                    String pkg = entry.getKey();
11120                    int mode = entry.getValue();
11121                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11122                        continue;
11123                    }
11124                    if (!printed) {
11125                        pw.println("  mScreenCompatPackages:");
11126                        printed = true;
11127                    }
11128                    pw.print("    "); pw.print(pkg); pw.print(": ");
11129                            pw.print(mode); pw.println();
11130                }
11131            }
11132        }
11133        if (dumpPackage == null) {
11134            if (mSleeping || mWentToSleep || mLockScreenShown) {
11135                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11136                        + " mLockScreenShown " + mLockScreenShown);
11137            }
11138            if (mShuttingDown) {
11139                pw.println("  mShuttingDown=" + mShuttingDown);
11140            }
11141        }
11142        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11143                || mOrigWaitForDebugger) {
11144            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11145                    || dumpPackage.equals(mOrigDebugApp)) {
11146                if (needSep) {
11147                    pw.println();
11148                    needSep = false;
11149                }
11150                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11151                        + " mDebugTransient=" + mDebugTransient
11152                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11153            }
11154        }
11155        if (mOpenGlTraceApp != null) {
11156            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11157                if (needSep) {
11158                    pw.println();
11159                    needSep = false;
11160                }
11161                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11162            }
11163        }
11164        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11165                || mProfileFd != null) {
11166            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11167                if (needSep) {
11168                    pw.println();
11169                    needSep = false;
11170                }
11171                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11172                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11173                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11174                        + mAutoStopProfiler);
11175            }
11176        }
11177        if (dumpPackage == null) {
11178            if (mAlwaysFinishActivities || mController != null) {
11179                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11180                        + " mController=" + mController);
11181            }
11182            if (dumpAll) {
11183                pw.println("  Total persistent processes: " + numPers);
11184                pw.println("  mProcessesReady=" + mProcessesReady
11185                        + " mSystemReady=" + mSystemReady);
11186                pw.println("  mBooting=" + mBooting
11187                        + " mBooted=" + mBooted
11188                        + " mFactoryTest=" + mFactoryTest);
11189                pw.print("  mLastPowerCheckRealtime=");
11190                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11191                        pw.println("");
11192                pw.print("  mLastPowerCheckUptime=");
11193                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11194                        pw.println("");
11195                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11196                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11197                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11198                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11199                        + " (" + mLruProcesses.size() + " total)"
11200                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11201                        + " mNumServiceProcs=" + mNumServiceProcs
11202                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11203                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11204                        + " mLastMemoryLevel" + mLastMemoryLevel
11205                        + " mLastNumProcesses" + mLastNumProcesses);
11206                long now = SystemClock.uptimeMillis();
11207                pw.print("  mLastIdleTime=");
11208                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11209                        pw.print(" mLowRamSinceLastIdle=");
11210                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11211                        pw.println();
11212            }
11213        }
11214
11215        if (!printedAnything) {
11216            pw.println("  (nothing)");
11217        }
11218    }
11219
11220    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11221            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11222        if (mProcessesToGc.size() > 0) {
11223            boolean printed = false;
11224            long now = SystemClock.uptimeMillis();
11225            for (int i=0; i<mProcessesToGc.size(); i++) {
11226                ProcessRecord proc = mProcessesToGc.get(i);
11227                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11228                    continue;
11229                }
11230                if (!printed) {
11231                    if (needSep) pw.println();
11232                    needSep = true;
11233                    pw.println("  Processes that are waiting to GC:");
11234                    printed = true;
11235                }
11236                pw.print("    Process "); pw.println(proc);
11237                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11238                        pw.print(", last gced=");
11239                        pw.print(now-proc.lastRequestedGc);
11240                        pw.print(" ms ago, last lowMem=");
11241                        pw.print(now-proc.lastLowMemory);
11242                        pw.println(" ms ago");
11243
11244            }
11245        }
11246        return needSep;
11247    }
11248
11249    void printOomLevel(PrintWriter pw, String name, int adj) {
11250        pw.print("    ");
11251        if (adj >= 0) {
11252            pw.print(' ');
11253            if (adj < 10) pw.print(' ');
11254        } else {
11255            if (adj > -10) pw.print(' ');
11256        }
11257        pw.print(adj);
11258        pw.print(": ");
11259        pw.print(name);
11260        pw.print(" (");
11261        pw.print(mProcessList.getMemLevel(adj)/1024);
11262        pw.println(" kB)");
11263    }
11264
11265    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11266            int opti, boolean dumpAll) {
11267        boolean needSep = false;
11268
11269        if (mLruProcesses.size() > 0) {
11270            if (needSep) pw.println();
11271            needSep = true;
11272            pw.println("  OOM levels:");
11273            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11274            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11275            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11276            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11277            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11278            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11279            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11280            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11281            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11282            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11283            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11284            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11285            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11286
11287            if (needSep) pw.println();
11288            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11289                    pw.print(" total, non-act at ");
11290                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11291                    pw.print(", non-svc at ");
11292                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11293                    pw.println("):");
11294            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11295            needSep = true;
11296        }
11297
11298        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11299
11300        pw.println();
11301        pw.println("  mHomeProcess: " + mHomeProcess);
11302        pw.println("  mPreviousProcess: " + mPreviousProcess);
11303        if (mHeavyWeightProcess != null) {
11304            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11305        }
11306
11307        return true;
11308    }
11309
11310    /**
11311     * There are three ways to call this:
11312     *  - no provider specified: dump all the providers
11313     *  - a flattened component name that matched an existing provider was specified as the
11314     *    first arg: dump that one provider
11315     *  - the first arg isn't the flattened component name of an existing provider:
11316     *    dump all providers whose component contains the first arg as a substring
11317     */
11318    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11319            int opti, boolean dumpAll) {
11320        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11321    }
11322
11323    static class ItemMatcher {
11324        ArrayList<ComponentName> components;
11325        ArrayList<String> strings;
11326        ArrayList<Integer> objects;
11327        boolean all;
11328
11329        ItemMatcher() {
11330            all = true;
11331        }
11332
11333        void build(String name) {
11334            ComponentName componentName = ComponentName.unflattenFromString(name);
11335            if (componentName != null) {
11336                if (components == null) {
11337                    components = new ArrayList<ComponentName>();
11338                }
11339                components.add(componentName);
11340                all = false;
11341            } else {
11342                int objectId = 0;
11343                // Not a '/' separated full component name; maybe an object ID?
11344                try {
11345                    objectId = Integer.parseInt(name, 16);
11346                    if (objects == null) {
11347                        objects = new ArrayList<Integer>();
11348                    }
11349                    objects.add(objectId);
11350                    all = false;
11351                } catch (RuntimeException e) {
11352                    // Not an integer; just do string match.
11353                    if (strings == null) {
11354                        strings = new ArrayList<String>();
11355                    }
11356                    strings.add(name);
11357                    all = false;
11358                }
11359            }
11360        }
11361
11362        int build(String[] args, int opti) {
11363            for (; opti<args.length; opti++) {
11364                String name = args[opti];
11365                if ("--".equals(name)) {
11366                    return opti+1;
11367                }
11368                build(name);
11369            }
11370            return opti;
11371        }
11372
11373        boolean match(Object object, ComponentName comp) {
11374            if (all) {
11375                return true;
11376            }
11377            if (components != null) {
11378                for (int i=0; i<components.size(); i++) {
11379                    if (components.get(i).equals(comp)) {
11380                        return true;
11381                    }
11382                }
11383            }
11384            if (objects != null) {
11385                for (int i=0; i<objects.size(); i++) {
11386                    if (System.identityHashCode(object) == objects.get(i)) {
11387                        return true;
11388                    }
11389                }
11390            }
11391            if (strings != null) {
11392                String flat = comp.flattenToString();
11393                for (int i=0; i<strings.size(); i++) {
11394                    if (flat.contains(strings.get(i))) {
11395                        return true;
11396                    }
11397                }
11398            }
11399            return false;
11400        }
11401    }
11402
11403    /**
11404     * There are three things that cmd can be:
11405     *  - a flattened component name that matches an existing activity
11406     *  - the cmd arg isn't the flattened component name of an existing activity:
11407     *    dump all activity whose component contains the cmd as a substring
11408     *  - A hex number of the ActivityRecord object instance.
11409     */
11410    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11411            int opti, boolean dumpAll) {
11412        ArrayList<ActivityRecord> activities;
11413
11414        synchronized (this) {
11415            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11416        }
11417
11418        if (activities.size() <= 0) {
11419            return false;
11420        }
11421
11422        String[] newArgs = new String[args.length - opti];
11423        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11424
11425        TaskRecord lastTask = null;
11426        boolean needSep = false;
11427        for (int i=activities.size()-1; i>=0; i--) {
11428            ActivityRecord r = activities.get(i);
11429            if (needSep) {
11430                pw.println();
11431            }
11432            needSep = true;
11433            synchronized (this) {
11434                if (lastTask != r.task) {
11435                    lastTask = r.task;
11436                    pw.print("TASK "); pw.print(lastTask.affinity);
11437                            pw.print(" id="); pw.println(lastTask.taskId);
11438                    if (dumpAll) {
11439                        lastTask.dump(pw, "  ");
11440                    }
11441                }
11442            }
11443            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11444        }
11445        return true;
11446    }
11447
11448    /**
11449     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11450     * there is a thread associated with the activity.
11451     */
11452    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11453            final ActivityRecord r, String[] args, boolean dumpAll) {
11454        String innerPrefix = prefix + "  ";
11455        synchronized (this) {
11456            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11457                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11458                    pw.print(" pid=");
11459                    if (r.app != null) pw.println(r.app.pid);
11460                    else pw.println("(not running)");
11461            if (dumpAll) {
11462                r.dump(pw, innerPrefix);
11463            }
11464        }
11465        if (r.app != null && r.app.thread != null) {
11466            // flush anything that is already in the PrintWriter since the thread is going
11467            // to write to the file descriptor directly
11468            pw.flush();
11469            try {
11470                TransferPipe tp = new TransferPipe();
11471                try {
11472                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11473                            r.appToken, innerPrefix, args);
11474                    tp.go(fd);
11475                } finally {
11476                    tp.kill();
11477                }
11478            } catch (IOException e) {
11479                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11480            } catch (RemoteException e) {
11481                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11482            }
11483        }
11484    }
11485
11486    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11487            int opti, boolean dumpAll, String dumpPackage) {
11488        boolean needSep = false;
11489        boolean onlyHistory = false;
11490        boolean printedAnything = false;
11491
11492        if ("history".equals(dumpPackage)) {
11493            if (opti < args.length && "-s".equals(args[opti])) {
11494                dumpAll = false;
11495            }
11496            onlyHistory = true;
11497            dumpPackage = null;
11498        }
11499
11500        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11501        if (!onlyHistory && dumpAll) {
11502            if (mRegisteredReceivers.size() > 0) {
11503                boolean printed = false;
11504                Iterator it = mRegisteredReceivers.values().iterator();
11505                while (it.hasNext()) {
11506                    ReceiverList r = (ReceiverList)it.next();
11507                    if (dumpPackage != null && (r.app == null ||
11508                            !dumpPackage.equals(r.app.info.packageName))) {
11509                        continue;
11510                    }
11511                    if (!printed) {
11512                        pw.println("  Registered Receivers:");
11513                        needSep = true;
11514                        printed = true;
11515                        printedAnything = true;
11516                    }
11517                    pw.print("  * "); pw.println(r);
11518                    r.dump(pw, "    ");
11519                }
11520            }
11521
11522            if (mReceiverResolver.dump(pw, needSep ?
11523                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11524                    "    ", dumpPackage, false)) {
11525                needSep = true;
11526                printedAnything = true;
11527            }
11528        }
11529
11530        for (BroadcastQueue q : mBroadcastQueues) {
11531            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11532            printedAnything |= needSep;
11533        }
11534
11535        needSep = true;
11536
11537        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11538            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11539                if (needSep) {
11540                    pw.println();
11541                }
11542                needSep = true;
11543                printedAnything = true;
11544                pw.print("  Sticky broadcasts for user ");
11545                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11546                StringBuilder sb = new StringBuilder(128);
11547                for (Map.Entry<String, ArrayList<Intent>> ent
11548                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11549                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11550                    if (dumpAll) {
11551                        pw.println(":");
11552                        ArrayList<Intent> intents = ent.getValue();
11553                        final int N = intents.size();
11554                        for (int i=0; i<N; i++) {
11555                            sb.setLength(0);
11556                            sb.append("    Intent: ");
11557                            intents.get(i).toShortString(sb, false, true, false, false);
11558                            pw.println(sb.toString());
11559                            Bundle bundle = intents.get(i).getExtras();
11560                            if (bundle != null) {
11561                                pw.print("      ");
11562                                pw.println(bundle.toString());
11563                            }
11564                        }
11565                    } else {
11566                        pw.println("");
11567                    }
11568                }
11569            }
11570        }
11571
11572        if (!onlyHistory && dumpAll) {
11573            pw.println();
11574            for (BroadcastQueue queue : mBroadcastQueues) {
11575                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11576                        + queue.mBroadcastsScheduled);
11577            }
11578            pw.println("  mHandler:");
11579            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11580            needSep = true;
11581            printedAnything = true;
11582        }
11583
11584        if (!printedAnything) {
11585            pw.println("  (nothing)");
11586        }
11587    }
11588
11589    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11590            int opti, boolean dumpAll, String dumpPackage) {
11591        boolean needSep;
11592        boolean printedAnything = false;
11593
11594        ItemMatcher matcher = new ItemMatcher();
11595        matcher.build(args, opti);
11596
11597        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11598
11599        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11600        printedAnything |= needSep;
11601
11602        if (mLaunchingProviders.size() > 0) {
11603            boolean printed = false;
11604            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11605                ContentProviderRecord r = mLaunchingProviders.get(i);
11606                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11607                    continue;
11608                }
11609                if (!printed) {
11610                    if (needSep) pw.println();
11611                    needSep = true;
11612                    pw.println("  Launching content providers:");
11613                    printed = true;
11614                    printedAnything = true;
11615                }
11616                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11617                        pw.println(r);
11618            }
11619        }
11620
11621        if (mGrantedUriPermissions.size() > 0) {
11622            boolean printed = false;
11623            int dumpUid = -2;
11624            if (dumpPackage != null) {
11625                try {
11626                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11627                } catch (NameNotFoundException e) {
11628                    dumpUid = -1;
11629                }
11630            }
11631            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11632                int uid = mGrantedUriPermissions.keyAt(i);
11633                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11634                    continue;
11635                }
11636                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11637                if (!printed) {
11638                    if (needSep) pw.println();
11639                    needSep = true;
11640                    pw.println("  Granted Uri Permissions:");
11641                    printed = true;
11642                    printedAnything = true;
11643                }
11644                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11645                for (UriPermission perm : perms.values()) {
11646                    pw.print("    "); pw.println(perm);
11647                    if (dumpAll) {
11648                        perm.dump(pw, "      ");
11649                    }
11650                }
11651            }
11652        }
11653
11654        if (!printedAnything) {
11655            pw.println("  (nothing)");
11656        }
11657    }
11658
11659    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11660            int opti, boolean dumpAll, String dumpPackage) {
11661        boolean printed = false;
11662
11663        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11664
11665        if (mIntentSenderRecords.size() > 0) {
11666            Iterator<WeakReference<PendingIntentRecord>> it
11667                    = mIntentSenderRecords.values().iterator();
11668            while (it.hasNext()) {
11669                WeakReference<PendingIntentRecord> ref = it.next();
11670                PendingIntentRecord rec = ref != null ? ref.get(): null;
11671                if (dumpPackage != null && (rec == null
11672                        || !dumpPackage.equals(rec.key.packageName))) {
11673                    continue;
11674                }
11675                printed = true;
11676                if (rec != null) {
11677                    pw.print("  * "); pw.println(rec);
11678                    if (dumpAll) {
11679                        rec.dump(pw, "    ");
11680                    }
11681                } else {
11682                    pw.print("  * "); pw.println(ref);
11683                }
11684            }
11685        }
11686
11687        if (!printed) {
11688            pw.println("  (nothing)");
11689        }
11690    }
11691
11692    private static final int dumpProcessList(PrintWriter pw,
11693            ActivityManagerService service, List list,
11694            String prefix, String normalLabel, String persistentLabel,
11695            String dumpPackage) {
11696        int numPers = 0;
11697        final int N = list.size()-1;
11698        for (int i=N; i>=0; i--) {
11699            ProcessRecord r = (ProcessRecord)list.get(i);
11700            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11701                continue;
11702            }
11703            pw.println(String.format("%s%s #%2d: %s",
11704                    prefix, (r.persistent ? persistentLabel : normalLabel),
11705                    i, r.toString()));
11706            if (r.persistent) {
11707                numPers++;
11708            }
11709        }
11710        return numPers;
11711    }
11712
11713    private static final boolean dumpProcessOomList(PrintWriter pw,
11714            ActivityManagerService service, List<ProcessRecord> origList,
11715            String prefix, String normalLabel, String persistentLabel,
11716            boolean inclDetails, String dumpPackage) {
11717
11718        ArrayList<Pair<ProcessRecord, Integer>> list
11719                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11720        for (int i=0; i<origList.size(); i++) {
11721            ProcessRecord r = origList.get(i);
11722            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11723                continue;
11724            }
11725            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11726        }
11727
11728        if (list.size() <= 0) {
11729            return false;
11730        }
11731
11732        Comparator<Pair<ProcessRecord, Integer>> comparator
11733                = new Comparator<Pair<ProcessRecord, Integer>>() {
11734            @Override
11735            public int compare(Pair<ProcessRecord, Integer> object1,
11736                    Pair<ProcessRecord, Integer> object2) {
11737                if (object1.first.setAdj != object2.first.setAdj) {
11738                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11739                }
11740                if (object1.second.intValue() != object2.second.intValue()) {
11741                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11742                }
11743                return 0;
11744            }
11745        };
11746
11747        Collections.sort(list, comparator);
11748
11749        final long curRealtime = SystemClock.elapsedRealtime();
11750        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11751        final long curUptime = SystemClock.uptimeMillis();
11752        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11753
11754        for (int i=list.size()-1; i>=0; i--) {
11755            ProcessRecord r = list.get(i).first;
11756            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11757            char schedGroup;
11758            switch (r.setSchedGroup) {
11759                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11760                    schedGroup = 'B';
11761                    break;
11762                case Process.THREAD_GROUP_DEFAULT:
11763                    schedGroup = 'F';
11764                    break;
11765                default:
11766                    schedGroup = '?';
11767                    break;
11768            }
11769            char foreground;
11770            if (r.foregroundActivities) {
11771                foreground = 'A';
11772            } else if (r.foregroundServices) {
11773                foreground = 'S';
11774            } else {
11775                foreground = ' ';
11776            }
11777            String procState = ProcessList.makeProcStateString(r.curProcState);
11778            pw.print(prefix);
11779            pw.print(r.persistent ? persistentLabel : normalLabel);
11780            pw.print(" #");
11781            int num = (origList.size()-1)-list.get(i).second;
11782            if (num < 10) pw.print(' ');
11783            pw.print(num);
11784            pw.print(": ");
11785            pw.print(oomAdj);
11786            pw.print(' ');
11787            pw.print(schedGroup);
11788            pw.print('/');
11789            pw.print(foreground);
11790            pw.print('/');
11791            pw.print(procState);
11792            pw.print(" trm:");
11793            if (r.trimMemoryLevel < 10) pw.print(' ');
11794            pw.print(r.trimMemoryLevel);
11795            pw.print(' ');
11796            pw.print(r.toShortString());
11797            pw.print(" (");
11798            pw.print(r.adjType);
11799            pw.println(')');
11800            if (r.adjSource != null || r.adjTarget != null) {
11801                pw.print(prefix);
11802                pw.print("    ");
11803                if (r.adjTarget instanceof ComponentName) {
11804                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11805                } else if (r.adjTarget != null) {
11806                    pw.print(r.adjTarget.toString());
11807                } else {
11808                    pw.print("{null}");
11809                }
11810                pw.print("<=");
11811                if (r.adjSource instanceof ProcessRecord) {
11812                    pw.print("Proc{");
11813                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11814                    pw.println("}");
11815                } else if (r.adjSource != null) {
11816                    pw.println(r.adjSource.toString());
11817                } else {
11818                    pw.println("{null}");
11819                }
11820            }
11821            if (inclDetails) {
11822                pw.print(prefix);
11823                pw.print("    ");
11824                pw.print("oom: max="); pw.print(r.maxAdj);
11825                pw.print(" curRaw="); pw.print(r.curRawAdj);
11826                pw.print(" setRaw="); pw.print(r.setRawAdj);
11827                pw.print(" cur="); pw.print(r.curAdj);
11828                pw.print(" set="); pw.println(r.setAdj);
11829                pw.print(prefix);
11830                pw.print("    ");
11831                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11832                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11833                pw.print(" lastPss="); pw.print(r.lastPss);
11834                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11835                pw.print(prefix);
11836                pw.print("    ");
11837                pw.print("keeping="); pw.print(r.keeping);
11838                pw.print(" cached="); pw.print(r.cached);
11839                pw.print(" empty="); pw.print(r.empty);
11840                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11841
11842                if (!r.keeping) {
11843                    if (r.lastWakeTime != 0) {
11844                        long wtime;
11845                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11846                        synchronized (stats) {
11847                            wtime = stats.getProcessWakeTime(r.info.uid,
11848                                    r.pid, curRealtime);
11849                        }
11850                        long timeUsed = wtime - r.lastWakeTime;
11851                        pw.print(prefix);
11852                        pw.print("    ");
11853                        pw.print("keep awake over ");
11854                        TimeUtils.formatDuration(realtimeSince, pw);
11855                        pw.print(" used ");
11856                        TimeUtils.formatDuration(timeUsed, pw);
11857                        pw.print(" (");
11858                        pw.print((timeUsed*100)/realtimeSince);
11859                        pw.println("%)");
11860                    }
11861                    if (r.lastCpuTime != 0) {
11862                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11863                        pw.print(prefix);
11864                        pw.print("    ");
11865                        pw.print("run cpu over ");
11866                        TimeUtils.formatDuration(uptimeSince, pw);
11867                        pw.print(" used ");
11868                        TimeUtils.formatDuration(timeUsed, pw);
11869                        pw.print(" (");
11870                        pw.print((timeUsed*100)/uptimeSince);
11871                        pw.println("%)");
11872                    }
11873                }
11874            }
11875        }
11876        return true;
11877    }
11878
11879    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11880        ArrayList<ProcessRecord> procs;
11881        synchronized (this) {
11882            if (args != null && args.length > start
11883                    && args[start].charAt(0) != '-') {
11884                procs = new ArrayList<ProcessRecord>();
11885                int pid = -1;
11886                try {
11887                    pid = Integer.parseInt(args[start]);
11888                } catch (NumberFormatException e) {
11889                }
11890                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11891                    ProcessRecord proc = mLruProcesses.get(i);
11892                    if (proc.pid == pid) {
11893                        procs.add(proc);
11894                    } else if (proc.processName.equals(args[start])) {
11895                        procs.add(proc);
11896                    }
11897                }
11898                if (procs.size() <= 0) {
11899                    return null;
11900                }
11901            } else {
11902                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11903            }
11904        }
11905        return procs;
11906    }
11907
11908    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11909            PrintWriter pw, String[] args) {
11910        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11911        if (procs == null) {
11912            pw.println("No process found for: " + args[0]);
11913            return;
11914        }
11915
11916        long uptime = SystemClock.uptimeMillis();
11917        long realtime = SystemClock.elapsedRealtime();
11918        pw.println("Applications Graphics Acceleration Info:");
11919        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11920
11921        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11922            ProcessRecord r = procs.get(i);
11923            if (r.thread != null) {
11924                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11925                pw.flush();
11926                try {
11927                    TransferPipe tp = new TransferPipe();
11928                    try {
11929                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11930                        tp.go(fd);
11931                    } finally {
11932                        tp.kill();
11933                    }
11934                } catch (IOException e) {
11935                    pw.println("Failure while dumping the app: " + r);
11936                    pw.flush();
11937                } catch (RemoteException e) {
11938                    pw.println("Got a RemoteException while dumping the app " + r);
11939                    pw.flush();
11940                }
11941            }
11942        }
11943    }
11944
11945    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11946        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11947        if (procs == null) {
11948            pw.println("No process found for: " + args[0]);
11949            return;
11950        }
11951
11952        pw.println("Applications Database Info:");
11953
11954        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11955            ProcessRecord r = procs.get(i);
11956            if (r.thread != null) {
11957                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11958                pw.flush();
11959                try {
11960                    TransferPipe tp = new TransferPipe();
11961                    try {
11962                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11963                        tp.go(fd);
11964                    } finally {
11965                        tp.kill();
11966                    }
11967                } catch (IOException e) {
11968                    pw.println("Failure while dumping the app: " + r);
11969                    pw.flush();
11970                } catch (RemoteException e) {
11971                    pw.println("Got a RemoteException while dumping the app " + r);
11972                    pw.flush();
11973                }
11974            }
11975        }
11976    }
11977
11978    final static class MemItem {
11979        final boolean isProc;
11980        final String label;
11981        final String shortLabel;
11982        final long pss;
11983        final int id;
11984        final boolean hasActivities;
11985        ArrayList<MemItem> subitems;
11986
11987        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11988                boolean _hasActivities) {
11989            isProc = true;
11990            label = _label;
11991            shortLabel = _shortLabel;
11992            pss = _pss;
11993            id = _id;
11994            hasActivities = _hasActivities;
11995        }
11996
11997        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11998            isProc = false;
11999            label = _label;
12000            shortLabel = _shortLabel;
12001            pss = _pss;
12002            id = _id;
12003            hasActivities = false;
12004        }
12005    }
12006
12007    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12008            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12009        if (sort && !isCompact) {
12010            Collections.sort(items, new Comparator<MemItem>() {
12011                @Override
12012                public int compare(MemItem lhs, MemItem rhs) {
12013                    if (lhs.pss < rhs.pss) {
12014                        return 1;
12015                    } else if (lhs.pss > rhs.pss) {
12016                        return -1;
12017                    }
12018                    return 0;
12019                }
12020            });
12021        }
12022
12023        for (int i=0; i<items.size(); i++) {
12024            MemItem mi = items.get(i);
12025            if (!isCompact) {
12026                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12027            } else if (mi.isProc) {
12028                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12029                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12030                pw.println(mi.hasActivities ? ",a" : ",e");
12031            } else {
12032                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12033                pw.println(mi.pss);
12034            }
12035            if (mi.subitems != null) {
12036                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12037                        true, isCompact);
12038            }
12039        }
12040    }
12041
12042    // These are in KB.
12043    static final long[] DUMP_MEM_BUCKETS = new long[] {
12044        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12045        120*1024, 160*1024, 200*1024,
12046        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12047        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12048    };
12049
12050    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12051            boolean stackLike) {
12052        int start = label.lastIndexOf('.');
12053        if (start >= 0) start++;
12054        else start = 0;
12055        int end = label.length();
12056        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12057            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12058                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12059                out.append(bucket);
12060                out.append(stackLike ? "MB." : "MB ");
12061                out.append(label, start, end);
12062                return;
12063            }
12064        }
12065        out.append(memKB/1024);
12066        out.append(stackLike ? "MB." : "MB ");
12067        out.append(label, start, end);
12068    }
12069
12070    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12071            ProcessList.NATIVE_ADJ,
12072            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12073            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12074            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12075            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12076            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12077    };
12078    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12079            "Native",
12080            "System", "Persistent", "Foreground",
12081            "Visible", "Perceptible",
12082            "Heavy Weight", "Backup",
12083            "A Services", "Home",
12084            "Previous", "B Services", "Cached"
12085    };
12086    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12087            "native",
12088            "sys", "pers", "fore",
12089            "vis", "percept",
12090            "heavy", "backup",
12091            "servicea", "home",
12092            "prev", "serviceb", "cached"
12093    };
12094
12095    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12096            long realtime, boolean isCheckinRequest, boolean isCompact) {
12097        if (isCheckinRequest || isCompact) {
12098            // short checkin version
12099            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12100        } else {
12101            pw.println("Applications Memory Usage (kB):");
12102            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12103        }
12104    }
12105
12106    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12107            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12108        boolean dumpDetails = false;
12109        boolean dumpFullDetails = false;
12110        boolean dumpDalvik = false;
12111        boolean oomOnly = false;
12112        boolean isCompact = false;
12113        boolean localOnly = false;
12114
12115        int opti = 0;
12116        while (opti < args.length) {
12117            String opt = args[opti];
12118            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12119                break;
12120            }
12121            opti++;
12122            if ("-a".equals(opt)) {
12123                dumpDetails = true;
12124                dumpFullDetails = true;
12125                dumpDalvik = true;
12126            } else if ("-d".equals(opt)) {
12127                dumpDalvik = true;
12128            } else if ("-c".equals(opt)) {
12129                isCompact = true;
12130            } else if ("--oom".equals(opt)) {
12131                oomOnly = true;
12132            } else if ("--local".equals(opt)) {
12133                localOnly = true;
12134            } else if ("-h".equals(opt)) {
12135                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12136                pw.println("  -a: include all available information for each process.");
12137                pw.println("  -d: include dalvik details when dumping process details.");
12138                pw.println("  -c: dump in a compact machine-parseable representation.");
12139                pw.println("  --oom: only show processes organized by oom adj.");
12140                pw.println("  --local: only collect details locally, don't call process.");
12141                pw.println("If [process] is specified it can be the name or ");
12142                pw.println("pid of a specific process to dump.");
12143                return;
12144            } else {
12145                pw.println("Unknown argument: " + opt + "; use -h for help");
12146            }
12147        }
12148
12149        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12150        long uptime = SystemClock.uptimeMillis();
12151        long realtime = SystemClock.elapsedRealtime();
12152        final long[] tmpLong = new long[1];
12153
12154        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12155        if (procs == null) {
12156            // No Java processes.  Maybe they want to print a native process.
12157            if (args != null && args.length > opti
12158                    && args[opti].charAt(0) != '-') {
12159                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12160                        = new ArrayList<ProcessCpuTracker.Stats>();
12161                updateCpuStatsNow();
12162                int findPid = -1;
12163                try {
12164                    findPid = Integer.parseInt(args[opti]);
12165                } catch (NumberFormatException e) {
12166                }
12167                synchronized (mProcessCpuThread) {
12168                    final int N = mProcessCpuTracker.countStats();
12169                    for (int i=0; i<N; i++) {
12170                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12171                        if (st.pid == findPid || (st.baseName != null
12172                                && st.baseName.equals(args[opti]))) {
12173                            nativeProcs.add(st);
12174                        }
12175                    }
12176                }
12177                if (nativeProcs.size() > 0) {
12178                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12179                            isCompact);
12180                    Debug.MemoryInfo mi = null;
12181                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12182                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12183                        final int pid = r.pid;
12184                        if (!isCheckinRequest && dumpDetails) {
12185                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12186                        }
12187                        if (mi == null) {
12188                            mi = new Debug.MemoryInfo();
12189                        }
12190                        if (dumpDetails || (!brief && !oomOnly)) {
12191                            Debug.getMemoryInfo(pid, mi);
12192                        } else {
12193                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12194                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12195                        }
12196                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12197                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12198                        if (isCheckinRequest) {
12199                            pw.println();
12200                        }
12201                    }
12202                    return;
12203                }
12204            }
12205            pw.println("No process found for: " + args[opti]);
12206            return;
12207        }
12208
12209        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12210            dumpDetails = true;
12211        }
12212
12213        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12214
12215        String[] innerArgs = new String[args.length-opti];
12216        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12217
12218        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12219        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12220        long nativePss=0, dalvikPss=0, otherPss=0;
12221        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12222
12223        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12224        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12225                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12226
12227        long totalPss = 0;
12228        long cachedPss = 0;
12229
12230        Debug.MemoryInfo mi = null;
12231        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12232            final ProcessRecord r = procs.get(i);
12233            final IApplicationThread thread;
12234            final int pid;
12235            final int oomAdj;
12236            final boolean hasActivities;
12237            synchronized (this) {
12238                thread = r.thread;
12239                pid = r.pid;
12240                oomAdj = r.getSetAdjWithServices();
12241                hasActivities = r.activities.size() > 0;
12242            }
12243            if (thread != null) {
12244                if (!isCheckinRequest && dumpDetails) {
12245                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12246                }
12247                if (mi == null) {
12248                    mi = new Debug.MemoryInfo();
12249                }
12250                if (dumpDetails || (!brief && !oomOnly)) {
12251                    Debug.getMemoryInfo(pid, mi);
12252                } else {
12253                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12254                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12255                }
12256                if (dumpDetails) {
12257                    if (localOnly) {
12258                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12259                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12260                        if (isCheckinRequest) {
12261                            pw.println();
12262                        }
12263                    } else {
12264                        try {
12265                            pw.flush();
12266                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12267                                    dumpDalvik, innerArgs);
12268                        } catch (RemoteException e) {
12269                            if (!isCheckinRequest) {
12270                                pw.println("Got RemoteException!");
12271                                pw.flush();
12272                            }
12273                        }
12274                    }
12275                }
12276
12277                final long myTotalPss = mi.getTotalPss();
12278                final long myTotalUss = mi.getTotalUss();
12279
12280                synchronized (this) {
12281                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12282                        // Record this for posterity if the process has been stable.
12283                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12284                    }
12285                }
12286
12287                if (!isCheckinRequest && mi != null) {
12288                    totalPss += myTotalPss;
12289                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12290                            (hasActivities ? " / activities)" : ")"),
12291                            r.processName, myTotalPss, pid, hasActivities);
12292                    procMems.add(pssItem);
12293                    procMemsMap.put(pid, pssItem);
12294
12295                    nativePss += mi.nativePss;
12296                    dalvikPss += mi.dalvikPss;
12297                    otherPss += mi.otherPss;
12298                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12299                        long mem = mi.getOtherPss(j);
12300                        miscPss[j] += mem;
12301                        otherPss -= mem;
12302                    }
12303
12304                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12305                        cachedPss += myTotalPss;
12306                    }
12307
12308                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12309                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12310                                || oomIndex == (oomPss.length-1)) {
12311                            oomPss[oomIndex] += myTotalPss;
12312                            if (oomProcs[oomIndex] == null) {
12313                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12314                            }
12315                            oomProcs[oomIndex].add(pssItem);
12316                            break;
12317                        }
12318                    }
12319                }
12320            }
12321        }
12322
12323        if (!isCheckinRequest && procs.size() > 1) {
12324            // If we are showing aggregations, also look for native processes to
12325            // include so that our aggregations are more accurate.
12326            updateCpuStatsNow();
12327            synchronized (mProcessCpuThread) {
12328                final int N = mProcessCpuTracker.countStats();
12329                for (int i=0; i<N; i++) {
12330                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12331                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12332                        if (mi == null) {
12333                            mi = new Debug.MemoryInfo();
12334                        }
12335                        if (!brief && !oomOnly) {
12336                            Debug.getMemoryInfo(st.pid, mi);
12337                        } else {
12338                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12339                            mi.nativePrivateDirty = (int)tmpLong[0];
12340                        }
12341
12342                        final long myTotalPss = mi.getTotalPss();
12343                        totalPss += myTotalPss;
12344
12345                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12346                                st.name, myTotalPss, st.pid, false);
12347                        procMems.add(pssItem);
12348
12349                        nativePss += mi.nativePss;
12350                        dalvikPss += mi.dalvikPss;
12351                        otherPss += mi.otherPss;
12352                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12353                            long mem = mi.getOtherPss(j);
12354                            miscPss[j] += mem;
12355                            otherPss -= mem;
12356                        }
12357                        oomPss[0] += myTotalPss;
12358                        if (oomProcs[0] == null) {
12359                            oomProcs[0] = new ArrayList<MemItem>();
12360                        }
12361                        oomProcs[0].add(pssItem);
12362                    }
12363                }
12364            }
12365
12366            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12367
12368            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12369            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12370            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12371            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12372                String label = Debug.MemoryInfo.getOtherLabel(j);
12373                catMems.add(new MemItem(label, label, miscPss[j], j));
12374            }
12375
12376            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12377            for (int j=0; j<oomPss.length; j++) {
12378                if (oomPss[j] != 0) {
12379                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12380                            : DUMP_MEM_OOM_LABEL[j];
12381                    MemItem item = new MemItem(label, label, oomPss[j],
12382                            DUMP_MEM_OOM_ADJ[j]);
12383                    item.subitems = oomProcs[j];
12384                    oomMems.add(item);
12385                }
12386            }
12387
12388            if (!brief && !oomOnly && !isCompact) {
12389                pw.println();
12390                pw.println("Total PSS by process:");
12391                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12392                pw.println();
12393            }
12394            if (!isCompact) {
12395                pw.println("Total PSS by OOM adjustment:");
12396            }
12397            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12398            if (!brief && !oomOnly) {
12399                PrintWriter out = categoryPw != null ? categoryPw : pw;
12400                if (!isCompact) {
12401                    out.println();
12402                    out.println("Total PSS by category:");
12403                }
12404                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12405            }
12406            if (!isCompact) {
12407                pw.println();
12408            }
12409            MemInfoReader memInfo = new MemInfoReader();
12410            memInfo.readMemInfo();
12411            if (!brief) {
12412                if (!isCompact) {
12413                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12414                    pw.print(" kB (status ");
12415                    switch (mLastMemoryLevel) {
12416                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12417                            pw.println("normal)");
12418                            break;
12419                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12420                            pw.println("moderate)");
12421                            break;
12422                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12423                            pw.println("low)");
12424                            break;
12425                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12426                            pw.println("critical)");
12427                            break;
12428                        default:
12429                            pw.print(mLastMemoryLevel);
12430                            pw.println(")");
12431                            break;
12432                    }
12433                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12434                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12435                            pw.print(cachedPss); pw.print(" cached pss + ");
12436                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12437                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12438                } else {
12439                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12440                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12441                            + memInfo.getFreeSizeKb()); pw.print(",");
12442                    pw.println(totalPss - cachedPss);
12443                }
12444            }
12445            if (!isCompact) {
12446                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12447                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12448                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12449                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12450                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12451                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12452                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12453                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12454                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12455                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12456                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12457            }
12458            if (!brief) {
12459                if (memInfo.getZramTotalSizeKb() != 0) {
12460                    if (!isCompact) {
12461                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12462                                pw.print(" kB physical used for ");
12463                                pw.print(memInfo.getSwapTotalSizeKb()
12464                                        - memInfo.getSwapFreeSizeKb());
12465                                pw.print(" kB in swap (");
12466                                pw.print(memInfo.getSwapTotalSizeKb());
12467                                pw.println(" kB total swap)");
12468                    } else {
12469                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12470                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12471                                pw.println(memInfo.getSwapFreeSizeKb());
12472                    }
12473                }
12474                final int[] SINGLE_LONG_FORMAT = new int[] {
12475                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12476                };
12477                long[] longOut = new long[1];
12478                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12479                        SINGLE_LONG_FORMAT, null, longOut, null);
12480                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12481                longOut[0] = 0;
12482                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12483                        SINGLE_LONG_FORMAT, null, longOut, null);
12484                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12485                longOut[0] = 0;
12486                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12487                        SINGLE_LONG_FORMAT, null, longOut, null);
12488                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12489                longOut[0] = 0;
12490                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12491                        SINGLE_LONG_FORMAT, null, longOut, null);
12492                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12493                if (!isCompact) {
12494                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12495                        pw.print("      KSM: "); pw.print(sharing);
12496                                pw.print(" kB saved from shared ");
12497                                pw.print(shared); pw.println(" kB");
12498                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12499                                pw.print(voltile); pw.println(" kB volatile");
12500                    }
12501                    pw.print("   Tuning: ");
12502                    pw.print(ActivityManager.staticGetMemoryClass());
12503                    pw.print(" (large ");
12504                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12505                    pw.print("), oom ");
12506                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12507                    pw.print(" kB");
12508                    pw.print(", restore limit ");
12509                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12510                    pw.print(" kB");
12511                    if (ActivityManager.isLowRamDeviceStatic()) {
12512                        pw.print(" (low-ram)");
12513                    }
12514                    if (ActivityManager.isHighEndGfx()) {
12515                        pw.print(" (high-end-gfx)");
12516                    }
12517                    pw.println();
12518                } else {
12519                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12520                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12521                    pw.println(voltile);
12522                    pw.print("tuning,");
12523                    pw.print(ActivityManager.staticGetMemoryClass());
12524                    pw.print(',');
12525                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12526                    pw.print(',');
12527                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
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                }
12536            }
12537        }
12538    }
12539
12540    /**
12541     * Searches array of arguments for the specified string
12542     * @param args array of argument strings
12543     * @param value value to search for
12544     * @return true if the value is contained in the array
12545     */
12546    private static boolean scanArgs(String[] args, String value) {
12547        if (args != null) {
12548            for (String arg : args) {
12549                if (value.equals(arg)) {
12550                    return true;
12551                }
12552            }
12553        }
12554        return false;
12555    }
12556
12557    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12558            ContentProviderRecord cpr, boolean always) {
12559        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12560
12561        if (!inLaunching || always) {
12562            synchronized (cpr) {
12563                cpr.launchingApp = null;
12564                cpr.notifyAll();
12565            }
12566            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12567            String names[] = cpr.info.authority.split(";");
12568            for (int j = 0; j < names.length; j++) {
12569                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12570            }
12571        }
12572
12573        for (int i=0; i<cpr.connections.size(); i++) {
12574            ContentProviderConnection conn = cpr.connections.get(i);
12575            if (conn.waiting) {
12576                // If this connection is waiting for the provider, then we don't
12577                // need to mess with its process unless we are always removing
12578                // or for some reason the provider is not currently launching.
12579                if (inLaunching && !always) {
12580                    continue;
12581                }
12582            }
12583            ProcessRecord capp = conn.client;
12584            conn.dead = true;
12585            if (conn.stableCount > 0) {
12586                if (!capp.persistent && capp.thread != null
12587                        && capp.pid != 0
12588                        && capp.pid != MY_PID) {
12589                    killUnneededProcessLocked(capp, "depends on provider "
12590                            + cpr.name.flattenToShortString()
12591                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12592                }
12593            } else if (capp.thread != null && conn.provider.provider != null) {
12594                try {
12595                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12596                } catch (RemoteException e) {
12597                }
12598                // In the protocol here, we don't expect the client to correctly
12599                // clean up this connection, we'll just remove it.
12600                cpr.connections.remove(i);
12601                conn.client.conProviders.remove(conn);
12602            }
12603        }
12604
12605        if (inLaunching && always) {
12606            mLaunchingProviders.remove(cpr);
12607        }
12608        return inLaunching;
12609    }
12610
12611    /**
12612     * Main code for cleaning up a process when it has gone away.  This is
12613     * called both as a result of the process dying, or directly when stopping
12614     * a process when running in single process mode.
12615     */
12616    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12617            boolean restarting, boolean allowRestart, int index) {
12618        if (index >= 0) {
12619            removeLruProcessLocked(app);
12620            ProcessList.remove(app.pid);
12621        }
12622
12623        mProcessesToGc.remove(app);
12624        mPendingPssProcesses.remove(app);
12625
12626        // Dismiss any open dialogs.
12627        if (app.crashDialog != null && !app.forceCrashReport) {
12628            app.crashDialog.dismiss();
12629            app.crashDialog = null;
12630        }
12631        if (app.anrDialog != null) {
12632            app.anrDialog.dismiss();
12633            app.anrDialog = null;
12634        }
12635        if (app.waitDialog != null) {
12636            app.waitDialog.dismiss();
12637            app.waitDialog = null;
12638        }
12639
12640        app.crashing = false;
12641        app.notResponding = false;
12642
12643        app.resetPackageList(mProcessStats);
12644        app.unlinkDeathRecipient();
12645        app.makeInactive(mProcessStats);
12646        app.forcingToForeground = null;
12647        updateProcessForegroundLocked(app, false, false);
12648        app.foregroundActivities = false;
12649        app.hasShownUi = false;
12650        app.treatLikeActivity = false;
12651        app.hasAboveClient = false;
12652        app.hasClientActivities = false;
12653
12654        mServices.killServicesLocked(app, allowRestart);
12655
12656        boolean restart = false;
12657
12658        // Remove published content providers.
12659        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12660            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12661            final boolean always = app.bad || !allowRestart;
12662            if (removeDyingProviderLocked(app, cpr, always) || always) {
12663                // We left the provider in the launching list, need to
12664                // restart it.
12665                restart = true;
12666            }
12667
12668            cpr.provider = null;
12669            cpr.proc = null;
12670        }
12671        app.pubProviders.clear();
12672
12673        // Take care of any launching providers waiting for this process.
12674        if (checkAppInLaunchingProvidersLocked(app, false)) {
12675            restart = true;
12676        }
12677
12678        // Unregister from connected content providers.
12679        if (!app.conProviders.isEmpty()) {
12680            for (int i=0; i<app.conProviders.size(); i++) {
12681                ContentProviderConnection conn = app.conProviders.get(i);
12682                conn.provider.connections.remove(conn);
12683            }
12684            app.conProviders.clear();
12685        }
12686
12687        // At this point there may be remaining entries in mLaunchingProviders
12688        // where we were the only one waiting, so they are no longer of use.
12689        // Look for these and clean up if found.
12690        // XXX Commented out for now.  Trying to figure out a way to reproduce
12691        // the actual situation to identify what is actually going on.
12692        if (false) {
12693            for (int i=0; i<mLaunchingProviders.size(); i++) {
12694                ContentProviderRecord cpr = (ContentProviderRecord)
12695                        mLaunchingProviders.get(i);
12696                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12697                    synchronized (cpr) {
12698                        cpr.launchingApp = null;
12699                        cpr.notifyAll();
12700                    }
12701                }
12702            }
12703        }
12704
12705        skipCurrentReceiverLocked(app);
12706
12707        // Unregister any receivers.
12708        for (int i=app.receivers.size()-1; i>=0; i--) {
12709            removeReceiverLocked(app.receivers.valueAt(i));
12710        }
12711        app.receivers.clear();
12712
12713        // If the app is undergoing backup, tell the backup manager about it
12714        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12715            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12716                    + mBackupTarget.appInfo + " died during backup");
12717            try {
12718                IBackupManager bm = IBackupManager.Stub.asInterface(
12719                        ServiceManager.getService(Context.BACKUP_SERVICE));
12720                bm.agentDisconnected(app.info.packageName);
12721            } catch (RemoteException e) {
12722                // can't happen; backup manager is local
12723            }
12724        }
12725
12726        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12727            ProcessChangeItem item = mPendingProcessChanges.get(i);
12728            if (item.pid == app.pid) {
12729                mPendingProcessChanges.remove(i);
12730                mAvailProcessChanges.add(item);
12731            }
12732        }
12733        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12734
12735        // If the caller is restarting this app, then leave it in its
12736        // current lists and let the caller take care of it.
12737        if (restarting) {
12738            return;
12739        }
12740
12741        if (!app.persistent || app.isolated) {
12742            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12743                    "Removing non-persistent process during cleanup: " + app);
12744            mProcessNames.remove(app.processName, app.uid);
12745            mIsolatedProcesses.remove(app.uid);
12746            if (mHeavyWeightProcess == app) {
12747                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12748                        mHeavyWeightProcess.userId, 0));
12749                mHeavyWeightProcess = null;
12750            }
12751        } else if (!app.removed) {
12752            // This app is persistent, so we need to keep its record around.
12753            // If it is not already on the pending app list, add it there
12754            // and start a new process for it.
12755            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12756                mPersistentStartingProcesses.add(app);
12757                restart = true;
12758            }
12759        }
12760        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12761                "Clean-up removing on hold: " + app);
12762        mProcessesOnHold.remove(app);
12763
12764        if (app == mHomeProcess) {
12765            mHomeProcess = null;
12766        }
12767        if (app == mPreviousProcess) {
12768            mPreviousProcess = null;
12769        }
12770
12771        if (restart && !app.isolated) {
12772            // We have components that still need to be running in the
12773            // process, so re-launch it.
12774            mProcessNames.put(app.processName, app.uid, app);
12775            startProcessLocked(app, "restart", app.processName);
12776        } else if (app.pid > 0 && app.pid != MY_PID) {
12777            // Goodbye!
12778            boolean removed;
12779            synchronized (mPidsSelfLocked) {
12780                mPidsSelfLocked.remove(app.pid);
12781                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12782            }
12783            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12784                    app.processName, app.info.uid);
12785            if (app.isolated) {
12786                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12787            }
12788            app.setPid(0);
12789        }
12790    }
12791
12792    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12793        // Look through the content providers we are waiting to have launched,
12794        // and if any run in this process then either schedule a restart of
12795        // the process or kill the client waiting for it if this process has
12796        // gone bad.
12797        int NL = mLaunchingProviders.size();
12798        boolean restart = false;
12799        for (int i=0; i<NL; i++) {
12800            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12801            if (cpr.launchingApp == app) {
12802                if (!alwaysBad && !app.bad) {
12803                    restart = true;
12804                } else {
12805                    removeDyingProviderLocked(app, cpr, true);
12806                    // cpr should have been removed from mLaunchingProviders
12807                    NL = mLaunchingProviders.size();
12808                    i--;
12809                }
12810            }
12811        }
12812        return restart;
12813    }
12814
12815    // =========================================================
12816    // SERVICES
12817    // =========================================================
12818
12819    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12820            int flags) {
12821        enforceNotIsolatedCaller("getServices");
12822        synchronized (this) {
12823            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12824        }
12825    }
12826
12827    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12828        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12829        synchronized (this) {
12830            return mServices.getRunningServiceControlPanelLocked(name);
12831        }
12832    }
12833
12834    public ComponentName startService(IApplicationThread caller, Intent service,
12835            String resolvedType, int userId) {
12836        enforceNotIsolatedCaller("startService");
12837        // Refuse possible leaked file descriptors
12838        if (service != null && service.hasFileDescriptors() == true) {
12839            throw new IllegalArgumentException("File descriptors passed in Intent");
12840        }
12841
12842        if (DEBUG_SERVICE)
12843            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12844        synchronized(this) {
12845            final int callingPid = Binder.getCallingPid();
12846            final int callingUid = Binder.getCallingUid();
12847            final long origId = Binder.clearCallingIdentity();
12848            ComponentName res = mServices.startServiceLocked(caller, service,
12849                    resolvedType, callingPid, callingUid, userId);
12850            Binder.restoreCallingIdentity(origId);
12851            return res;
12852        }
12853    }
12854
12855    ComponentName startServiceInPackage(int uid,
12856            Intent service, String resolvedType, int userId) {
12857        synchronized(this) {
12858            if (DEBUG_SERVICE)
12859                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12860            final long origId = Binder.clearCallingIdentity();
12861            ComponentName res = mServices.startServiceLocked(null, service,
12862                    resolvedType, -1, uid, userId);
12863            Binder.restoreCallingIdentity(origId);
12864            return res;
12865        }
12866    }
12867
12868    public int stopService(IApplicationThread caller, Intent service,
12869            String resolvedType, int userId) {
12870        enforceNotIsolatedCaller("stopService");
12871        // Refuse possible leaked file descriptors
12872        if (service != null && service.hasFileDescriptors() == true) {
12873            throw new IllegalArgumentException("File descriptors passed in Intent");
12874        }
12875
12876        synchronized(this) {
12877            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12878        }
12879    }
12880
12881    public IBinder peekService(Intent service, String resolvedType) {
12882        enforceNotIsolatedCaller("peekService");
12883        // Refuse possible leaked file descriptors
12884        if (service != null && service.hasFileDescriptors() == true) {
12885            throw new IllegalArgumentException("File descriptors passed in Intent");
12886        }
12887        synchronized(this) {
12888            return mServices.peekServiceLocked(service, resolvedType);
12889        }
12890    }
12891
12892    public boolean stopServiceToken(ComponentName className, IBinder token,
12893            int startId) {
12894        synchronized(this) {
12895            return mServices.stopServiceTokenLocked(className, token, startId);
12896        }
12897    }
12898
12899    public void setServiceForeground(ComponentName className, IBinder token,
12900            int id, Notification notification, boolean removeNotification) {
12901        synchronized(this) {
12902            mServices.setServiceForegroundLocked(className, token, id, notification,
12903                    removeNotification);
12904        }
12905    }
12906
12907    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12908            boolean requireFull, String name, String callerPackage) {
12909        final int callingUserId = UserHandle.getUserId(callingUid);
12910        if (callingUserId != userId) {
12911            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12912                if ((requireFull || checkComponentPermission(
12913                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12914                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12915                        && checkComponentPermission(
12916                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12917                                callingPid, callingUid, -1, true)
12918                                != PackageManager.PERMISSION_GRANTED) {
12919                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12920                        // In this case, they would like to just execute as their
12921                        // owner user instead of failing.
12922                        userId = callingUserId;
12923                    } else {
12924                        StringBuilder builder = new StringBuilder(128);
12925                        builder.append("Permission Denial: ");
12926                        builder.append(name);
12927                        if (callerPackage != null) {
12928                            builder.append(" from ");
12929                            builder.append(callerPackage);
12930                        }
12931                        builder.append(" asks to run as user ");
12932                        builder.append(userId);
12933                        builder.append(" but is calling from user ");
12934                        builder.append(UserHandle.getUserId(callingUid));
12935                        builder.append("; this requires ");
12936                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12937                        if (!requireFull) {
12938                            builder.append(" or ");
12939                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12940                        }
12941                        String msg = builder.toString();
12942                        Slog.w(TAG, msg);
12943                        throw new SecurityException(msg);
12944                    }
12945                }
12946            }
12947            if (userId == UserHandle.USER_CURRENT
12948                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12949                // Note that we may be accessing this outside of a lock...
12950                // shouldn't be a big deal, if this is being called outside
12951                // of a locked context there is intrinsically a race with
12952                // the value the caller will receive and someone else changing it.
12953                userId = mCurrentUserId;
12954            }
12955            if (!allowAll && userId < 0) {
12956                throw new IllegalArgumentException(
12957                        "Call does not support special user #" + userId);
12958            }
12959        }
12960        return userId;
12961    }
12962
12963    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12964            String className, int flags) {
12965        boolean result = false;
12966        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12967            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12968                if (ActivityManager.checkUidPermission(
12969                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12970                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12971                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12972                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12973                            + " requests FLAG_SINGLE_USER, but app does not hold "
12974                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12975                    Slog.w(TAG, msg);
12976                    throw new SecurityException(msg);
12977                }
12978                result = true;
12979            }
12980        } else if (componentProcessName == aInfo.packageName) {
12981            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12982        } else if ("system".equals(componentProcessName)) {
12983            result = true;
12984        }
12985        if (DEBUG_MU) {
12986            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12987                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12988        }
12989        return result;
12990    }
12991
12992    public int bindService(IApplicationThread caller, IBinder token,
12993            Intent service, String resolvedType,
12994            IServiceConnection connection, int flags, int userId) {
12995        enforceNotIsolatedCaller("bindService");
12996        // Refuse possible leaked file descriptors
12997        if (service != null && service.hasFileDescriptors() == true) {
12998            throw new IllegalArgumentException("File descriptors passed in Intent");
12999        }
13000
13001        synchronized(this) {
13002            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13003                    connection, flags, userId);
13004        }
13005    }
13006
13007    public boolean unbindService(IServiceConnection connection) {
13008        synchronized (this) {
13009            return mServices.unbindServiceLocked(connection);
13010        }
13011    }
13012
13013    public void publishService(IBinder token, Intent intent, IBinder service) {
13014        // Refuse possible leaked file descriptors
13015        if (intent != null && intent.hasFileDescriptors() == true) {
13016            throw new IllegalArgumentException("File descriptors passed in Intent");
13017        }
13018
13019        synchronized(this) {
13020            if (!(token instanceof ServiceRecord)) {
13021                throw new IllegalArgumentException("Invalid service token");
13022            }
13023            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13024        }
13025    }
13026
13027    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13028        // Refuse possible leaked file descriptors
13029        if (intent != null && intent.hasFileDescriptors() == true) {
13030            throw new IllegalArgumentException("File descriptors passed in Intent");
13031        }
13032
13033        synchronized(this) {
13034            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13035        }
13036    }
13037
13038    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13039        synchronized(this) {
13040            if (!(token instanceof ServiceRecord)) {
13041                throw new IllegalArgumentException("Invalid service token");
13042            }
13043            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13044        }
13045    }
13046
13047    // =========================================================
13048    // BACKUP AND RESTORE
13049    // =========================================================
13050
13051    // Cause the target app to be launched if necessary and its backup agent
13052    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13053    // activity manager to announce its creation.
13054    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13055        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13056        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13057
13058        synchronized(this) {
13059            // !!! TODO: currently no check here that we're already bound
13060            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13061            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13062            synchronized (stats) {
13063                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13064            }
13065
13066            // Backup agent is now in use, its package can't be stopped.
13067            try {
13068                AppGlobals.getPackageManager().setPackageStoppedState(
13069                        app.packageName, false, UserHandle.getUserId(app.uid));
13070            } catch (RemoteException e) {
13071            } catch (IllegalArgumentException e) {
13072                Slog.w(TAG, "Failed trying to unstop package "
13073                        + app.packageName + ": " + e);
13074            }
13075
13076            BackupRecord r = new BackupRecord(ss, app, backupMode);
13077            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13078                    ? new ComponentName(app.packageName, app.backupAgentName)
13079                    : new ComponentName("android", "FullBackupAgent");
13080            // startProcessLocked() returns existing proc's record if it's already running
13081            ProcessRecord proc = startProcessLocked(app.processName, app,
13082                    false, 0, "backup", hostingName, false, false, false);
13083            if (proc == null) {
13084                Slog.e(TAG, "Unable to start backup agent process " + r);
13085                return false;
13086            }
13087
13088            r.app = proc;
13089            mBackupTarget = r;
13090            mBackupAppName = app.packageName;
13091
13092            // Try not to kill the process during backup
13093            updateOomAdjLocked(proc);
13094
13095            // If the process is already attached, schedule the creation of the backup agent now.
13096            // If it is not yet live, this will be done when it attaches to the framework.
13097            if (proc.thread != null) {
13098                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13099                try {
13100                    proc.thread.scheduleCreateBackupAgent(app,
13101                            compatibilityInfoForPackageLocked(app), backupMode);
13102                } catch (RemoteException e) {
13103                    // Will time out on the backup manager side
13104                }
13105            } else {
13106                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13107            }
13108            // Invariants: at this point, the target app process exists and the application
13109            // is either already running or in the process of coming up.  mBackupTarget and
13110            // mBackupAppName describe the app, so that when it binds back to the AM we
13111            // know that it's scheduled for a backup-agent operation.
13112        }
13113
13114        return true;
13115    }
13116
13117    @Override
13118    public void clearPendingBackup() {
13119        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13120        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13121
13122        synchronized (this) {
13123            mBackupTarget = null;
13124            mBackupAppName = null;
13125        }
13126    }
13127
13128    // A backup agent has just come up
13129    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13130        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13131                + " = " + agent);
13132
13133        synchronized(this) {
13134            if (!agentPackageName.equals(mBackupAppName)) {
13135                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13136                return;
13137            }
13138        }
13139
13140        long oldIdent = Binder.clearCallingIdentity();
13141        try {
13142            IBackupManager bm = IBackupManager.Stub.asInterface(
13143                    ServiceManager.getService(Context.BACKUP_SERVICE));
13144            bm.agentConnected(agentPackageName, agent);
13145        } catch (RemoteException e) {
13146            // can't happen; the backup manager service is local
13147        } catch (Exception e) {
13148            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13149            e.printStackTrace();
13150        } finally {
13151            Binder.restoreCallingIdentity(oldIdent);
13152        }
13153    }
13154
13155    // done with this agent
13156    public void unbindBackupAgent(ApplicationInfo appInfo) {
13157        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13158        if (appInfo == null) {
13159            Slog.w(TAG, "unbind backup agent for null app");
13160            return;
13161        }
13162
13163        synchronized(this) {
13164            try {
13165                if (mBackupAppName == null) {
13166                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13167                    return;
13168                }
13169
13170                if (!mBackupAppName.equals(appInfo.packageName)) {
13171                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13172                    return;
13173                }
13174
13175                // Not backing this app up any more; reset its OOM adjustment
13176                final ProcessRecord proc = mBackupTarget.app;
13177                updateOomAdjLocked(proc);
13178
13179                // If the app crashed during backup, 'thread' will be null here
13180                if (proc.thread != null) {
13181                    try {
13182                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13183                                compatibilityInfoForPackageLocked(appInfo));
13184                    } catch (Exception e) {
13185                        Slog.e(TAG, "Exception when unbinding backup agent:");
13186                        e.printStackTrace();
13187                    }
13188                }
13189            } finally {
13190                mBackupTarget = null;
13191                mBackupAppName = null;
13192            }
13193        }
13194    }
13195    // =========================================================
13196    // BROADCASTS
13197    // =========================================================
13198
13199    private final List getStickiesLocked(String action, IntentFilter filter,
13200            List cur, int userId) {
13201        final ContentResolver resolver = mContext.getContentResolver();
13202        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13203        if (stickies == null) {
13204            return cur;
13205        }
13206        final ArrayList<Intent> list = stickies.get(action);
13207        if (list == null) {
13208            return cur;
13209        }
13210        int N = list.size();
13211        for (int i=0; i<N; i++) {
13212            Intent intent = list.get(i);
13213            if (filter.match(resolver, intent, true, TAG) >= 0) {
13214                if (cur == null) {
13215                    cur = new ArrayList<Intent>();
13216                }
13217                cur.add(intent);
13218            }
13219        }
13220        return cur;
13221    }
13222
13223    boolean isPendingBroadcastProcessLocked(int pid) {
13224        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13225                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13226    }
13227
13228    void skipPendingBroadcastLocked(int pid) {
13229            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13230            for (BroadcastQueue queue : mBroadcastQueues) {
13231                queue.skipPendingBroadcastLocked(pid);
13232            }
13233    }
13234
13235    // The app just attached; send any pending broadcasts that it should receive
13236    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13237        boolean didSomething = false;
13238        for (BroadcastQueue queue : mBroadcastQueues) {
13239            didSomething |= queue.sendPendingBroadcastsLocked(app);
13240        }
13241        return didSomething;
13242    }
13243
13244    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13245            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13246        enforceNotIsolatedCaller("registerReceiver");
13247        int callingUid;
13248        int callingPid;
13249        synchronized(this) {
13250            ProcessRecord callerApp = null;
13251            if (caller != null) {
13252                callerApp = getRecordForAppLocked(caller);
13253                if (callerApp == null) {
13254                    throw new SecurityException(
13255                            "Unable to find app for caller " + caller
13256                            + " (pid=" + Binder.getCallingPid()
13257                            + ") when registering receiver " + receiver);
13258                }
13259                if (callerApp.info.uid != Process.SYSTEM_UID &&
13260                        !callerApp.pkgList.containsKey(callerPackage) &&
13261                        !"android".equals(callerPackage)) {
13262                    throw new SecurityException("Given caller package " + callerPackage
13263                            + " is not running in process " + callerApp);
13264                }
13265                callingUid = callerApp.info.uid;
13266                callingPid = callerApp.pid;
13267            } else {
13268                callerPackage = null;
13269                callingUid = Binder.getCallingUid();
13270                callingPid = Binder.getCallingPid();
13271            }
13272
13273            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13274                    true, true, "registerReceiver", callerPackage);
13275
13276            List allSticky = null;
13277
13278            // Look for any matching sticky broadcasts...
13279            Iterator actions = filter.actionsIterator();
13280            if (actions != null) {
13281                while (actions.hasNext()) {
13282                    String action = (String)actions.next();
13283                    allSticky = getStickiesLocked(action, filter, allSticky,
13284                            UserHandle.USER_ALL);
13285                    allSticky = getStickiesLocked(action, filter, allSticky,
13286                            UserHandle.getUserId(callingUid));
13287                }
13288            } else {
13289                allSticky = getStickiesLocked(null, filter, allSticky,
13290                        UserHandle.USER_ALL);
13291                allSticky = getStickiesLocked(null, filter, allSticky,
13292                        UserHandle.getUserId(callingUid));
13293            }
13294
13295            // The first sticky in the list is returned directly back to
13296            // the client.
13297            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13298
13299            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13300                    + ": " + sticky);
13301
13302            if (receiver == null) {
13303                return sticky;
13304            }
13305
13306            ReceiverList rl
13307                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13308            if (rl == null) {
13309                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13310                        userId, receiver);
13311                if (rl.app != null) {
13312                    rl.app.receivers.add(rl);
13313                } else {
13314                    try {
13315                        receiver.asBinder().linkToDeath(rl, 0);
13316                    } catch (RemoteException e) {
13317                        return sticky;
13318                    }
13319                    rl.linkedToDeath = true;
13320                }
13321                mRegisteredReceivers.put(receiver.asBinder(), rl);
13322            } else if (rl.uid != callingUid) {
13323                throw new IllegalArgumentException(
13324                        "Receiver requested to register for uid " + callingUid
13325                        + " was previously registered for uid " + rl.uid);
13326            } else if (rl.pid != callingPid) {
13327                throw new IllegalArgumentException(
13328                        "Receiver requested to register for pid " + callingPid
13329                        + " was previously registered for pid " + rl.pid);
13330            } else if (rl.userId != userId) {
13331                throw new IllegalArgumentException(
13332                        "Receiver requested to register for user " + userId
13333                        + " was previously registered for user " + rl.userId);
13334            }
13335            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13336                    permission, callingUid, userId);
13337            rl.add(bf);
13338            if (!bf.debugCheck()) {
13339                Slog.w(TAG, "==> For Dynamic broadast");
13340            }
13341            mReceiverResolver.addFilter(bf);
13342
13343            // Enqueue broadcasts for all existing stickies that match
13344            // this filter.
13345            if (allSticky != null) {
13346                ArrayList receivers = new ArrayList();
13347                receivers.add(bf);
13348
13349                int N = allSticky.size();
13350                for (int i=0; i<N; i++) {
13351                    Intent intent = (Intent)allSticky.get(i);
13352                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13353                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13354                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13355                            null, null, false, true, true, -1);
13356                    queue.enqueueParallelBroadcastLocked(r);
13357                    queue.scheduleBroadcastsLocked();
13358                }
13359            }
13360
13361            return sticky;
13362        }
13363    }
13364
13365    public void unregisterReceiver(IIntentReceiver receiver) {
13366        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13367
13368        final long origId = Binder.clearCallingIdentity();
13369        try {
13370            boolean doTrim = false;
13371
13372            synchronized(this) {
13373                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13374                if (rl != null) {
13375                    if (rl.curBroadcast != null) {
13376                        BroadcastRecord r = rl.curBroadcast;
13377                        final boolean doNext = finishReceiverLocked(
13378                                receiver.asBinder(), r.resultCode, r.resultData,
13379                                r.resultExtras, r.resultAbort);
13380                        if (doNext) {
13381                            doTrim = true;
13382                            r.queue.processNextBroadcast(false);
13383                        }
13384                    }
13385
13386                    if (rl.app != null) {
13387                        rl.app.receivers.remove(rl);
13388                    }
13389                    removeReceiverLocked(rl);
13390                    if (rl.linkedToDeath) {
13391                        rl.linkedToDeath = false;
13392                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13393                    }
13394                }
13395            }
13396
13397            // If we actually concluded any broadcasts, we might now be able
13398            // to trim the recipients' apps from our working set
13399            if (doTrim) {
13400                trimApplications();
13401                return;
13402            }
13403
13404        } finally {
13405            Binder.restoreCallingIdentity(origId);
13406        }
13407    }
13408
13409    void removeReceiverLocked(ReceiverList rl) {
13410        mRegisteredReceivers.remove(rl.receiver.asBinder());
13411        int N = rl.size();
13412        for (int i=0; i<N; i++) {
13413            mReceiverResolver.removeFilter(rl.get(i));
13414        }
13415    }
13416
13417    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13418        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13419            ProcessRecord r = mLruProcesses.get(i);
13420            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13421                try {
13422                    r.thread.dispatchPackageBroadcast(cmd, packages);
13423                } catch (RemoteException ex) {
13424                }
13425            }
13426        }
13427    }
13428
13429    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13430            int[] users) {
13431        List<ResolveInfo> receivers = null;
13432        try {
13433            HashSet<ComponentName> singleUserReceivers = null;
13434            boolean scannedFirstReceivers = false;
13435            for (int user : users) {
13436                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13437                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13438                if (user != 0 && newReceivers != null) {
13439                    // If this is not the primary user, we need to check for
13440                    // any receivers that should be filtered out.
13441                    for (int i=0; i<newReceivers.size(); i++) {
13442                        ResolveInfo ri = newReceivers.get(i);
13443                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13444                            newReceivers.remove(i);
13445                            i--;
13446                        }
13447                    }
13448                }
13449                if (newReceivers != null && newReceivers.size() == 0) {
13450                    newReceivers = null;
13451                }
13452                if (receivers == null) {
13453                    receivers = newReceivers;
13454                } else if (newReceivers != null) {
13455                    // We need to concatenate the additional receivers
13456                    // found with what we have do far.  This would be easy,
13457                    // but we also need to de-dup any receivers that are
13458                    // singleUser.
13459                    if (!scannedFirstReceivers) {
13460                        // Collect any single user receivers we had already retrieved.
13461                        scannedFirstReceivers = true;
13462                        for (int i=0; i<receivers.size(); i++) {
13463                            ResolveInfo ri = receivers.get(i);
13464                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13465                                ComponentName cn = new ComponentName(
13466                                        ri.activityInfo.packageName, ri.activityInfo.name);
13467                                if (singleUserReceivers == null) {
13468                                    singleUserReceivers = new HashSet<ComponentName>();
13469                                }
13470                                singleUserReceivers.add(cn);
13471                            }
13472                        }
13473                    }
13474                    // Add the new results to the existing results, tracking
13475                    // and de-dupping single user receivers.
13476                    for (int i=0; i<newReceivers.size(); i++) {
13477                        ResolveInfo ri = newReceivers.get(i);
13478                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13479                            ComponentName cn = new ComponentName(
13480                                    ri.activityInfo.packageName, ri.activityInfo.name);
13481                            if (singleUserReceivers == null) {
13482                                singleUserReceivers = new HashSet<ComponentName>();
13483                            }
13484                            if (!singleUserReceivers.contains(cn)) {
13485                                singleUserReceivers.add(cn);
13486                                receivers.add(ri);
13487                            }
13488                        } else {
13489                            receivers.add(ri);
13490                        }
13491                    }
13492                }
13493            }
13494        } catch (RemoteException ex) {
13495            // pm is in same process, this will never happen.
13496        }
13497        return receivers;
13498    }
13499
13500    private final int broadcastIntentLocked(ProcessRecord callerApp,
13501            String callerPackage, Intent intent, String resolvedType,
13502            IIntentReceiver resultTo, int resultCode, String resultData,
13503            Bundle map, String requiredPermission, int appOp,
13504            boolean ordered, boolean sticky, int callingPid, int callingUid,
13505            int userId) {
13506        intent = new Intent(intent);
13507
13508        // By default broadcasts do not go to stopped apps.
13509        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13510
13511        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13512            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13513            + " ordered=" + ordered + " userid=" + userId);
13514        if ((resultTo != null) && !ordered) {
13515            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13516        }
13517
13518        userId = handleIncomingUser(callingPid, callingUid, userId,
13519                true, false, "broadcast", callerPackage);
13520
13521        // Make sure that the user who is receiving this broadcast is started.
13522        // If not, we will just skip it.
13523        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13524            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13525                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13526                Slog.w(TAG, "Skipping broadcast of " + intent
13527                        + ": user " + userId + " is stopped");
13528                return ActivityManager.BROADCAST_SUCCESS;
13529            }
13530        }
13531
13532        /*
13533         * Prevent non-system code (defined here to be non-persistent
13534         * processes) from sending protected broadcasts.
13535         */
13536        int callingAppId = UserHandle.getAppId(callingUid);
13537        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13538            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13539            callingUid == 0) {
13540            // Always okay.
13541        } else if (callerApp == null || !callerApp.persistent) {
13542            try {
13543                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13544                        intent.getAction())) {
13545                    String msg = "Permission Denial: not allowed to send broadcast "
13546                            + intent.getAction() + " from pid="
13547                            + callingPid + ", uid=" + callingUid;
13548                    Slog.w(TAG, msg);
13549                    throw new SecurityException(msg);
13550                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13551                    // Special case for compatibility: we don't want apps to send this,
13552                    // but historically it has not been protected and apps may be using it
13553                    // to poke their own app widget.  So, instead of making it protected,
13554                    // just limit it to the caller.
13555                    if (callerApp == null) {
13556                        String msg = "Permission Denial: not allowed to send broadcast "
13557                                + intent.getAction() + " from unknown caller.";
13558                        Slog.w(TAG, msg);
13559                        throw new SecurityException(msg);
13560                    } else if (intent.getComponent() != null) {
13561                        // They are good enough to send to an explicit component...  verify
13562                        // it is being sent to the calling app.
13563                        if (!intent.getComponent().getPackageName().equals(
13564                                callerApp.info.packageName)) {
13565                            String msg = "Permission Denial: not allowed to send broadcast "
13566                                    + intent.getAction() + " to "
13567                                    + intent.getComponent().getPackageName() + " from "
13568                                    + callerApp.info.packageName;
13569                            Slog.w(TAG, msg);
13570                            throw new SecurityException(msg);
13571                        }
13572                    } else {
13573                        // Limit broadcast to their own package.
13574                        intent.setPackage(callerApp.info.packageName);
13575                    }
13576                }
13577            } catch (RemoteException e) {
13578                Slog.w(TAG, "Remote exception", e);
13579                return ActivityManager.BROADCAST_SUCCESS;
13580            }
13581        }
13582
13583        // Handle special intents: if this broadcast is from the package
13584        // manager about a package being removed, we need to remove all of
13585        // its activities from the history stack.
13586        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13587                intent.getAction());
13588        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13589                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13590                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13591                || uidRemoved) {
13592            if (checkComponentPermission(
13593                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13594                    callingPid, callingUid, -1, true)
13595                    == PackageManager.PERMISSION_GRANTED) {
13596                if (uidRemoved) {
13597                    final Bundle intentExtras = intent.getExtras();
13598                    final int uid = intentExtras != null
13599                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13600                    if (uid >= 0) {
13601                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13602                        synchronized (bs) {
13603                            bs.removeUidStatsLocked(uid);
13604                        }
13605                        mAppOpsService.uidRemoved(uid);
13606                    }
13607                } else {
13608                    // If resources are unavailable just force stop all
13609                    // those packages and flush the attribute cache as well.
13610                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13611                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13612                        if (list != null && (list.length > 0)) {
13613                            for (String pkg : list) {
13614                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13615                                        "storage unmount");
13616                            }
13617                            sendPackageBroadcastLocked(
13618                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13619                        }
13620                    } else {
13621                        Uri data = intent.getData();
13622                        String ssp;
13623                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13624                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13625                                    intent.getAction());
13626                            boolean fullUninstall = removed &&
13627                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13628                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13629                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13630                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13631                                        false, fullUninstall, userId,
13632                                        removed ? "pkg removed" : "pkg changed");
13633                            }
13634                            if (removed) {
13635                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13636                                        new String[] {ssp}, userId);
13637                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13638                                    mAppOpsService.packageRemoved(
13639                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13640
13641                                    // Remove all permissions granted from/to this package
13642                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13643                                }
13644                            }
13645                        }
13646                    }
13647                }
13648            } else {
13649                String msg = "Permission Denial: " + intent.getAction()
13650                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13651                        + ", uid=" + callingUid + ")"
13652                        + " requires "
13653                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13654                Slog.w(TAG, msg);
13655                throw new SecurityException(msg);
13656            }
13657
13658        // Special case for adding a package: by default turn on compatibility
13659        // mode.
13660        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13661            Uri data = intent.getData();
13662            String ssp;
13663            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13664                mCompatModePackages.handlePackageAddedLocked(ssp,
13665                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13666            }
13667        }
13668
13669        /*
13670         * If this is the time zone changed action, queue up a message that will reset the timezone
13671         * of all currently running processes. This message will get queued up before the broadcast
13672         * happens.
13673         */
13674        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13675            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13676        }
13677
13678        /*
13679         * If the user set the time, let all running processes know.
13680         */
13681        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13682            final int is24Hour = intent.getBooleanExtra(
13683                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13684            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13685        }
13686
13687        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13688            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13689        }
13690
13691        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13692            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13693            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13694        }
13695
13696        // Add to the sticky list if requested.
13697        if (sticky) {
13698            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13699                    callingPid, callingUid)
13700                    != PackageManager.PERMISSION_GRANTED) {
13701                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13702                        + callingPid + ", uid=" + callingUid
13703                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13704                Slog.w(TAG, msg);
13705                throw new SecurityException(msg);
13706            }
13707            if (requiredPermission != null) {
13708                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13709                        + " and enforce permission " + requiredPermission);
13710                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13711            }
13712            if (intent.getComponent() != null) {
13713                throw new SecurityException(
13714                        "Sticky broadcasts can't target a specific component");
13715            }
13716            // We use userId directly here, since the "all" target is maintained
13717            // as a separate set of sticky broadcasts.
13718            if (userId != UserHandle.USER_ALL) {
13719                // But first, if this is not a broadcast to all users, then
13720                // make sure it doesn't conflict with an existing broadcast to
13721                // all users.
13722                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13723                        UserHandle.USER_ALL);
13724                if (stickies != null) {
13725                    ArrayList<Intent> list = stickies.get(intent.getAction());
13726                    if (list != null) {
13727                        int N = list.size();
13728                        int i;
13729                        for (i=0; i<N; i++) {
13730                            if (intent.filterEquals(list.get(i))) {
13731                                throw new IllegalArgumentException(
13732                                        "Sticky broadcast " + intent + " for user "
13733                                        + userId + " conflicts with existing global broadcast");
13734                            }
13735                        }
13736                    }
13737                }
13738            }
13739            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13740            if (stickies == null) {
13741                stickies = new ArrayMap<String, ArrayList<Intent>>();
13742                mStickyBroadcasts.put(userId, stickies);
13743            }
13744            ArrayList<Intent> list = stickies.get(intent.getAction());
13745            if (list == null) {
13746                list = new ArrayList<Intent>();
13747                stickies.put(intent.getAction(), list);
13748            }
13749            int N = list.size();
13750            int i;
13751            for (i=0; i<N; i++) {
13752                if (intent.filterEquals(list.get(i))) {
13753                    // This sticky already exists, replace it.
13754                    list.set(i, new Intent(intent));
13755                    break;
13756                }
13757            }
13758            if (i >= N) {
13759                list.add(new Intent(intent));
13760            }
13761        }
13762
13763        int[] users;
13764        if (userId == UserHandle.USER_ALL) {
13765            // Caller wants broadcast to go to all started users.
13766            users = mStartedUserArray;
13767        } else {
13768            // Caller wants broadcast to go to one specific user.
13769            users = new int[] {userId};
13770        }
13771
13772        // Figure out who all will receive this broadcast.
13773        List receivers = null;
13774        List<BroadcastFilter> registeredReceivers = null;
13775        // Need to resolve the intent to interested receivers...
13776        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13777                 == 0) {
13778            receivers = collectReceiverComponents(intent, resolvedType, users);
13779        }
13780        if (intent.getComponent() == null) {
13781            registeredReceivers = mReceiverResolver.queryIntent(intent,
13782                    resolvedType, false, userId);
13783        }
13784
13785        final boolean replacePending =
13786                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13787
13788        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13789                + " replacePending=" + replacePending);
13790
13791        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13792        if (!ordered && NR > 0) {
13793            // If we are not serializing this broadcast, then send the
13794            // registered receivers separately so they don't wait for the
13795            // components to be launched.
13796            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13797            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13798                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13799                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13800                    ordered, sticky, false, userId);
13801            if (DEBUG_BROADCAST) Slog.v(
13802                    TAG, "Enqueueing parallel broadcast " + r);
13803            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13804            if (!replaced) {
13805                queue.enqueueParallelBroadcastLocked(r);
13806                queue.scheduleBroadcastsLocked();
13807            }
13808            registeredReceivers = null;
13809            NR = 0;
13810        }
13811
13812        // Merge into one list.
13813        int ir = 0;
13814        if (receivers != null) {
13815            // A special case for PACKAGE_ADDED: do not allow the package
13816            // being added to see this broadcast.  This prevents them from
13817            // using this as a back door to get run as soon as they are
13818            // installed.  Maybe in the future we want to have a special install
13819            // broadcast or such for apps, but we'd like to deliberately make
13820            // this decision.
13821            String skipPackages[] = null;
13822            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13823                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13824                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13825                Uri data = intent.getData();
13826                if (data != null) {
13827                    String pkgName = data.getSchemeSpecificPart();
13828                    if (pkgName != null) {
13829                        skipPackages = new String[] { pkgName };
13830                    }
13831                }
13832            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13833                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13834            }
13835            if (skipPackages != null && (skipPackages.length > 0)) {
13836                for (String skipPackage : skipPackages) {
13837                    if (skipPackage != null) {
13838                        int NT = receivers.size();
13839                        for (int it=0; it<NT; it++) {
13840                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13841                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13842                                receivers.remove(it);
13843                                it--;
13844                                NT--;
13845                            }
13846                        }
13847                    }
13848                }
13849            }
13850
13851            int NT = receivers != null ? receivers.size() : 0;
13852            int it = 0;
13853            ResolveInfo curt = null;
13854            BroadcastFilter curr = null;
13855            while (it < NT && ir < NR) {
13856                if (curt == null) {
13857                    curt = (ResolveInfo)receivers.get(it);
13858                }
13859                if (curr == null) {
13860                    curr = registeredReceivers.get(ir);
13861                }
13862                if (curr.getPriority() >= curt.priority) {
13863                    // Insert this broadcast record into the final list.
13864                    receivers.add(it, curr);
13865                    ir++;
13866                    curr = null;
13867                    it++;
13868                    NT++;
13869                } else {
13870                    // Skip to the next ResolveInfo in the final list.
13871                    it++;
13872                    curt = null;
13873                }
13874            }
13875        }
13876        while (ir < NR) {
13877            if (receivers == null) {
13878                receivers = new ArrayList();
13879            }
13880            receivers.add(registeredReceivers.get(ir));
13881            ir++;
13882        }
13883
13884        if ((receivers != null && receivers.size() > 0)
13885                || resultTo != null) {
13886            BroadcastQueue queue = broadcastQueueForIntent(intent);
13887            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13888                    callerPackage, callingPid, callingUid, resolvedType,
13889                    requiredPermission, appOp, receivers, resultTo, resultCode,
13890                    resultData, map, ordered, sticky, false, userId);
13891            if (DEBUG_BROADCAST) Slog.v(
13892                    TAG, "Enqueueing ordered broadcast " + r
13893                    + ": prev had " + queue.mOrderedBroadcasts.size());
13894            if (DEBUG_BROADCAST) {
13895                int seq = r.intent.getIntExtra("seq", -1);
13896                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13897            }
13898            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13899            if (!replaced) {
13900                queue.enqueueOrderedBroadcastLocked(r);
13901                queue.scheduleBroadcastsLocked();
13902            }
13903        }
13904
13905        return ActivityManager.BROADCAST_SUCCESS;
13906    }
13907
13908    final Intent verifyBroadcastLocked(Intent intent) {
13909        // Refuse possible leaked file descriptors
13910        if (intent != null && intent.hasFileDescriptors() == true) {
13911            throw new IllegalArgumentException("File descriptors passed in Intent");
13912        }
13913
13914        int flags = intent.getFlags();
13915
13916        if (!mProcessesReady) {
13917            // if the caller really truly claims to know what they're doing, go
13918            // ahead and allow the broadcast without launching any receivers
13919            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13920                intent = new Intent(intent);
13921                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13922            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13923                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13924                        + " before boot completion");
13925                throw new IllegalStateException("Cannot broadcast before boot completed");
13926            }
13927        }
13928
13929        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13930            throw new IllegalArgumentException(
13931                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13932        }
13933
13934        return intent;
13935    }
13936
13937    public final int broadcastIntent(IApplicationThread caller,
13938            Intent intent, String resolvedType, IIntentReceiver resultTo,
13939            int resultCode, String resultData, Bundle map,
13940            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13941        enforceNotIsolatedCaller("broadcastIntent");
13942        synchronized(this) {
13943            intent = verifyBroadcastLocked(intent);
13944
13945            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13946            final int callingPid = Binder.getCallingPid();
13947            final int callingUid = Binder.getCallingUid();
13948            final long origId = Binder.clearCallingIdentity();
13949            int res = broadcastIntentLocked(callerApp,
13950                    callerApp != null ? callerApp.info.packageName : null,
13951                    intent, resolvedType, resultTo,
13952                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13953                    callingPid, callingUid, userId);
13954            Binder.restoreCallingIdentity(origId);
13955            return res;
13956        }
13957    }
13958
13959    int broadcastIntentInPackage(String packageName, int uid,
13960            Intent intent, String resolvedType, IIntentReceiver resultTo,
13961            int resultCode, String resultData, Bundle map,
13962            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13963        synchronized(this) {
13964            intent = verifyBroadcastLocked(intent);
13965
13966            final long origId = Binder.clearCallingIdentity();
13967            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13968                    resultTo, resultCode, resultData, map, requiredPermission,
13969                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13970            Binder.restoreCallingIdentity(origId);
13971            return res;
13972        }
13973    }
13974
13975    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13976        // Refuse possible leaked file descriptors
13977        if (intent != null && intent.hasFileDescriptors() == true) {
13978            throw new IllegalArgumentException("File descriptors passed in Intent");
13979        }
13980
13981        userId = handleIncomingUser(Binder.getCallingPid(),
13982                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13983
13984        synchronized(this) {
13985            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13986                    != PackageManager.PERMISSION_GRANTED) {
13987                String msg = "Permission Denial: unbroadcastIntent() from pid="
13988                        + Binder.getCallingPid()
13989                        + ", uid=" + Binder.getCallingUid()
13990                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13991                Slog.w(TAG, msg);
13992                throw new SecurityException(msg);
13993            }
13994            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13995            if (stickies != null) {
13996                ArrayList<Intent> list = stickies.get(intent.getAction());
13997                if (list != null) {
13998                    int N = list.size();
13999                    int i;
14000                    for (i=0; i<N; i++) {
14001                        if (intent.filterEquals(list.get(i))) {
14002                            list.remove(i);
14003                            break;
14004                        }
14005                    }
14006                    if (list.size() <= 0) {
14007                        stickies.remove(intent.getAction());
14008                    }
14009                }
14010                if (stickies.size() <= 0) {
14011                    mStickyBroadcasts.remove(userId);
14012                }
14013            }
14014        }
14015    }
14016
14017    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14018            String resultData, Bundle resultExtras, boolean resultAbort) {
14019        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14020        if (r == null) {
14021            Slog.w(TAG, "finishReceiver called but not found on queue");
14022            return false;
14023        }
14024
14025        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14026    }
14027
14028    void backgroundServicesFinishedLocked(int userId) {
14029        for (BroadcastQueue queue : mBroadcastQueues) {
14030            queue.backgroundServicesFinishedLocked(userId);
14031        }
14032    }
14033
14034    public void finishReceiver(IBinder who, int resultCode, String resultData,
14035            Bundle resultExtras, boolean resultAbort) {
14036        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14037
14038        // Refuse possible leaked file descriptors
14039        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14040            throw new IllegalArgumentException("File descriptors passed in Bundle");
14041        }
14042
14043        final long origId = Binder.clearCallingIdentity();
14044        try {
14045            boolean doNext = false;
14046            BroadcastRecord r;
14047
14048            synchronized(this) {
14049                r = broadcastRecordForReceiverLocked(who);
14050                if (r != null) {
14051                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14052                        resultData, resultExtras, resultAbort, true);
14053                }
14054            }
14055
14056            if (doNext) {
14057                r.queue.processNextBroadcast(false);
14058            }
14059            trimApplications();
14060        } finally {
14061            Binder.restoreCallingIdentity(origId);
14062        }
14063    }
14064
14065    // =========================================================
14066    // INSTRUMENTATION
14067    // =========================================================
14068
14069    public boolean startInstrumentation(ComponentName className,
14070            String profileFile, int flags, Bundle arguments,
14071            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14072            int userId) {
14073        enforceNotIsolatedCaller("startInstrumentation");
14074        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14075                userId, false, true, "startInstrumentation", null);
14076        // Refuse possible leaked file descriptors
14077        if (arguments != null && arguments.hasFileDescriptors()) {
14078            throw new IllegalArgumentException("File descriptors passed in Bundle");
14079        }
14080
14081        synchronized(this) {
14082            InstrumentationInfo ii = null;
14083            ApplicationInfo ai = null;
14084            try {
14085                ii = mContext.getPackageManager().getInstrumentationInfo(
14086                    className, STOCK_PM_FLAGS);
14087                ai = AppGlobals.getPackageManager().getApplicationInfo(
14088                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14089            } catch (PackageManager.NameNotFoundException e) {
14090            } catch (RemoteException e) {
14091            }
14092            if (ii == null) {
14093                reportStartInstrumentationFailure(watcher, className,
14094                        "Unable to find instrumentation info for: " + className);
14095                return false;
14096            }
14097            if (ai == null) {
14098                reportStartInstrumentationFailure(watcher, className,
14099                        "Unable to find instrumentation target package: " + ii.targetPackage);
14100                return false;
14101            }
14102
14103            int match = mContext.getPackageManager().checkSignatures(
14104                    ii.targetPackage, ii.packageName);
14105            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14106                String msg = "Permission Denial: starting instrumentation "
14107                        + className + " from pid="
14108                        + Binder.getCallingPid()
14109                        + ", uid=" + Binder.getCallingPid()
14110                        + " not allowed because package " + ii.packageName
14111                        + " does not have a signature matching the target "
14112                        + ii.targetPackage;
14113                reportStartInstrumentationFailure(watcher, className, msg);
14114                throw new SecurityException(msg);
14115            }
14116
14117            final long origId = Binder.clearCallingIdentity();
14118            // Instrumentation can kill and relaunch even persistent processes
14119            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14120                    "start instr");
14121            ProcessRecord app = addAppLocked(ai, false);
14122            app.instrumentationClass = className;
14123            app.instrumentationInfo = ai;
14124            app.instrumentationProfileFile = profileFile;
14125            app.instrumentationArguments = arguments;
14126            app.instrumentationWatcher = watcher;
14127            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14128            app.instrumentationResultClass = className;
14129            Binder.restoreCallingIdentity(origId);
14130        }
14131
14132        return true;
14133    }
14134
14135    /**
14136     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14137     * error to the logs, but if somebody is watching, send the report there too.  This enables
14138     * the "am" command to report errors with more information.
14139     *
14140     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14141     * @param cn The component name of the instrumentation.
14142     * @param report The error report.
14143     */
14144    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14145            ComponentName cn, String report) {
14146        Slog.w(TAG, report);
14147        try {
14148            if (watcher != null) {
14149                Bundle results = new Bundle();
14150                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14151                results.putString("Error", report);
14152                watcher.instrumentationStatus(cn, -1, results);
14153            }
14154        } catch (RemoteException e) {
14155            Slog.w(TAG, e);
14156        }
14157    }
14158
14159    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14160        if (app.instrumentationWatcher != null) {
14161            try {
14162                // NOTE:  IInstrumentationWatcher *must* be oneway here
14163                app.instrumentationWatcher.instrumentationFinished(
14164                    app.instrumentationClass,
14165                    resultCode,
14166                    results);
14167            } catch (RemoteException e) {
14168            }
14169        }
14170        if (app.instrumentationUiAutomationConnection != null) {
14171            try {
14172                app.instrumentationUiAutomationConnection.shutdown();
14173            } catch (RemoteException re) {
14174                /* ignore */
14175            }
14176            // Only a UiAutomation can set this flag and now that
14177            // it is finished we make sure it is reset to its default.
14178            mUserIsMonkey = false;
14179        }
14180        app.instrumentationWatcher = null;
14181        app.instrumentationUiAutomationConnection = null;
14182        app.instrumentationClass = null;
14183        app.instrumentationInfo = null;
14184        app.instrumentationProfileFile = null;
14185        app.instrumentationArguments = null;
14186
14187        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14188                "finished inst");
14189    }
14190
14191    public void finishInstrumentation(IApplicationThread target,
14192            int resultCode, Bundle results) {
14193        int userId = UserHandle.getCallingUserId();
14194        // Refuse possible leaked file descriptors
14195        if (results != null && results.hasFileDescriptors()) {
14196            throw new IllegalArgumentException("File descriptors passed in Intent");
14197        }
14198
14199        synchronized(this) {
14200            ProcessRecord app = getRecordForAppLocked(target);
14201            if (app == null) {
14202                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14203                return;
14204            }
14205            final long origId = Binder.clearCallingIdentity();
14206            finishInstrumentationLocked(app, resultCode, results);
14207            Binder.restoreCallingIdentity(origId);
14208        }
14209    }
14210
14211    // =========================================================
14212    // CONFIGURATION
14213    // =========================================================
14214
14215    public ConfigurationInfo getDeviceConfigurationInfo() {
14216        ConfigurationInfo config = new ConfigurationInfo();
14217        synchronized (this) {
14218            config.reqTouchScreen = mConfiguration.touchscreen;
14219            config.reqKeyboardType = mConfiguration.keyboard;
14220            config.reqNavigation = mConfiguration.navigation;
14221            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14222                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14223                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14224            }
14225            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14226                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14227                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14228            }
14229            config.reqGlEsVersion = GL_ES_VERSION;
14230        }
14231        return config;
14232    }
14233
14234    ActivityStack getFocusedStack() {
14235        return mStackSupervisor.getFocusedStack();
14236    }
14237
14238    public Configuration getConfiguration() {
14239        Configuration ci;
14240        synchronized(this) {
14241            ci = new Configuration(mConfiguration);
14242        }
14243        return ci;
14244    }
14245
14246    public void updatePersistentConfiguration(Configuration values) {
14247        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14248                "updateConfiguration()");
14249        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14250                "updateConfiguration()");
14251        if (values == null) {
14252            throw new NullPointerException("Configuration must not be null");
14253        }
14254
14255        synchronized(this) {
14256            final long origId = Binder.clearCallingIdentity();
14257            updateConfigurationLocked(values, null, true, false);
14258            Binder.restoreCallingIdentity(origId);
14259        }
14260    }
14261
14262    public void updateConfiguration(Configuration values) {
14263        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14264                "updateConfiguration()");
14265
14266        synchronized(this) {
14267            if (values == null && mWindowManager != null) {
14268                // sentinel: fetch the current configuration from the window manager
14269                values = mWindowManager.computeNewConfiguration();
14270            }
14271
14272            if (mWindowManager != null) {
14273                mProcessList.applyDisplaySize(mWindowManager);
14274            }
14275
14276            final long origId = Binder.clearCallingIdentity();
14277            if (values != null) {
14278                Settings.System.clearConfiguration(values);
14279            }
14280            updateConfigurationLocked(values, null, false, false);
14281            Binder.restoreCallingIdentity(origId);
14282        }
14283    }
14284
14285    /**
14286     * Do either or both things: (1) change the current configuration, and (2)
14287     * make sure the given activity is running with the (now) current
14288     * configuration.  Returns true if the activity has been left running, or
14289     * false if <var>starting</var> is being destroyed to match the new
14290     * configuration.
14291     * @param persistent TODO
14292     */
14293    boolean updateConfigurationLocked(Configuration values,
14294            ActivityRecord starting, boolean persistent, boolean initLocale) {
14295        int changes = 0;
14296
14297        if (values != null) {
14298            Configuration newConfig = new Configuration(mConfiguration);
14299            changes = newConfig.updateFrom(values);
14300            if (changes != 0) {
14301                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14302                    Slog.i(TAG, "Updating configuration to: " + values);
14303                }
14304
14305                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14306
14307                if (values.locale != null && !initLocale) {
14308                    saveLocaleLocked(values.locale,
14309                                     !values.locale.equals(mConfiguration.locale),
14310                                     values.userSetLocale);
14311                }
14312
14313                mConfigurationSeq++;
14314                if (mConfigurationSeq <= 0) {
14315                    mConfigurationSeq = 1;
14316                }
14317                newConfig.seq = mConfigurationSeq;
14318                mConfiguration = newConfig;
14319                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14320
14321                final Configuration configCopy = new Configuration(mConfiguration);
14322
14323                // TODO: If our config changes, should we auto dismiss any currently
14324                // showing dialogs?
14325                mShowDialogs = shouldShowDialogs(newConfig);
14326
14327                AttributeCache ac = AttributeCache.instance();
14328                if (ac != null) {
14329                    ac.updateConfiguration(configCopy);
14330                }
14331
14332                // Make sure all resources in our process are updated
14333                // right now, so that anyone who is going to retrieve
14334                // resource values after we return will be sure to get
14335                // the new ones.  This is especially important during
14336                // boot, where the first config change needs to guarantee
14337                // all resources have that config before following boot
14338                // code is executed.
14339                mSystemThread.applyConfigurationToResources(configCopy);
14340
14341                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14342                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14343                    msg.obj = new Configuration(configCopy);
14344                    mHandler.sendMessage(msg);
14345                }
14346
14347                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14348                    ProcessRecord app = mLruProcesses.get(i);
14349                    try {
14350                        if (app.thread != null) {
14351                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14352                                    + app.processName + " new config " + mConfiguration);
14353                            app.thread.scheduleConfigurationChanged(configCopy);
14354                        }
14355                    } catch (Exception e) {
14356                    }
14357                }
14358                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14359                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14360                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14361                        | Intent.FLAG_RECEIVER_FOREGROUND);
14362                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14363                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14364                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14365                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14366                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14367                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14368                    broadcastIntentLocked(null, null, intent,
14369                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14370                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14371                }
14372            }
14373        }
14374
14375        boolean kept = true;
14376        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14377        // mainStack is null during startup.
14378        if (mainStack != null) {
14379            if (changes != 0 && starting == null) {
14380                // If the configuration changed, and the caller is not already
14381                // in the process of starting an activity, then find the top
14382                // activity to check if its configuration needs to change.
14383                starting = mainStack.topRunningActivityLocked(null);
14384            }
14385
14386            if (starting != null) {
14387                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14388                // And we need to make sure at this point that all other activities
14389                // are made visible with the correct configuration.
14390                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14391            }
14392        }
14393
14394        if (values != null && mWindowManager != null) {
14395            mWindowManager.setNewConfiguration(mConfiguration);
14396        }
14397
14398        return kept;
14399    }
14400
14401    /**
14402     * Decide based on the configuration whether we should shouw the ANR,
14403     * crash, etc dialogs.  The idea is that if there is no affordnace to
14404     * press the on-screen buttons, we shouldn't show the dialog.
14405     *
14406     * A thought: SystemUI might also want to get told about this, the Power
14407     * dialog / global actions also might want different behaviors.
14408     */
14409    private static final boolean shouldShowDialogs(Configuration config) {
14410        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14411                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14412    }
14413
14414    /**
14415     * Save the locale.  You must be inside a synchronized (this) block.
14416     */
14417    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14418        if(isDiff) {
14419            SystemProperties.set("user.language", l.getLanguage());
14420            SystemProperties.set("user.region", l.getCountry());
14421        }
14422
14423        if(isPersist) {
14424            SystemProperties.set("persist.sys.language", l.getLanguage());
14425            SystemProperties.set("persist.sys.country", l.getCountry());
14426            SystemProperties.set("persist.sys.localevar", l.getVariant());
14427        }
14428    }
14429
14430    @Override
14431    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14432        ActivityRecord srec = ActivityRecord.forToken(token);
14433        return srec != null && srec.task.affinity != null &&
14434                srec.task.affinity.equals(destAffinity);
14435    }
14436
14437    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14438            Intent resultData) {
14439
14440        synchronized (this) {
14441            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14442            if (stack != null) {
14443                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14444            }
14445            return false;
14446        }
14447    }
14448
14449    public int getLaunchedFromUid(IBinder activityToken) {
14450        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14451        if (srec == null) {
14452            return -1;
14453        }
14454        return srec.launchedFromUid;
14455    }
14456
14457    public String getLaunchedFromPackage(IBinder activityToken) {
14458        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14459        if (srec == null) {
14460            return null;
14461        }
14462        return srec.launchedFromPackage;
14463    }
14464
14465    // =========================================================
14466    // LIFETIME MANAGEMENT
14467    // =========================================================
14468
14469    // Returns which broadcast queue the app is the current [or imminent] receiver
14470    // on, or 'null' if the app is not an active broadcast recipient.
14471    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14472        BroadcastRecord r = app.curReceiver;
14473        if (r != null) {
14474            return r.queue;
14475        }
14476
14477        // It's not the current receiver, but it might be starting up to become one
14478        synchronized (this) {
14479            for (BroadcastQueue queue : mBroadcastQueues) {
14480                r = queue.mPendingBroadcast;
14481                if (r != null && r.curApp == app) {
14482                    // found it; report which queue it's in
14483                    return queue;
14484                }
14485            }
14486        }
14487
14488        return null;
14489    }
14490
14491    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14492            boolean doingAll, long now) {
14493        if (mAdjSeq == app.adjSeq) {
14494            // This adjustment has already been computed.
14495            return app.curRawAdj;
14496        }
14497
14498        if (app.thread == null) {
14499            app.adjSeq = mAdjSeq;
14500            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14501            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14502            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14503        }
14504
14505        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14506        app.adjSource = null;
14507        app.adjTarget = null;
14508        app.empty = false;
14509        app.cached = false;
14510
14511        final int activitiesSize = app.activities.size();
14512
14513        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14514            // The max adjustment doesn't allow this app to be anything
14515            // below foreground, so it is not worth doing work for it.
14516            app.adjType = "fixed";
14517            app.adjSeq = mAdjSeq;
14518            app.curRawAdj = app.maxAdj;
14519            app.foregroundActivities = false;
14520            app.keeping = true;
14521            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14522            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14523            // System process can do UI, and when they do we want to have
14524            // them trim their memory after the user leaves the UI.  To
14525            // facilitate this, here we need to determine whether or not it
14526            // is currently showing UI.
14527            app.systemNoUi = true;
14528            if (app == TOP_APP) {
14529                app.systemNoUi = false;
14530            } else if (activitiesSize > 0) {
14531                for (int j = 0; j < activitiesSize; j++) {
14532                    final ActivityRecord r = app.activities.get(j);
14533                    if (r.visible) {
14534                        app.systemNoUi = false;
14535                    }
14536                }
14537            }
14538            if (!app.systemNoUi) {
14539                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14540            }
14541            return (app.curAdj=app.maxAdj);
14542        }
14543
14544        app.keeping = false;
14545        app.systemNoUi = false;
14546
14547        // Determine the importance of the process, starting with most
14548        // important to least, and assign an appropriate OOM adjustment.
14549        int adj;
14550        int schedGroup;
14551        int procState;
14552        boolean foregroundActivities = false;
14553        boolean interesting = false;
14554        BroadcastQueue queue;
14555        if (app == TOP_APP) {
14556            // The last app on the list is the foreground app.
14557            adj = ProcessList.FOREGROUND_APP_ADJ;
14558            schedGroup = Process.THREAD_GROUP_DEFAULT;
14559            app.adjType = "top-activity";
14560            foregroundActivities = true;
14561            interesting = true;
14562            procState = ActivityManager.PROCESS_STATE_TOP;
14563        } else if (app.instrumentationClass != null) {
14564            // Don't want to kill running instrumentation.
14565            adj = ProcessList.FOREGROUND_APP_ADJ;
14566            schedGroup = Process.THREAD_GROUP_DEFAULT;
14567            app.adjType = "instrumentation";
14568            interesting = true;
14569            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14570        } else if ((queue = isReceivingBroadcast(app)) != null) {
14571            // An app that is currently receiving a broadcast also
14572            // counts as being in the foreground for OOM killer purposes.
14573            // It's placed in a sched group based on the nature of the
14574            // broadcast as reflected by which queue it's active in.
14575            adj = ProcessList.FOREGROUND_APP_ADJ;
14576            schedGroup = (queue == mFgBroadcastQueue)
14577                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14578            app.adjType = "broadcast";
14579            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14580        } else if (app.executingServices.size() > 0) {
14581            // An app that is currently executing a service callback also
14582            // counts as being in the foreground.
14583            adj = ProcessList.FOREGROUND_APP_ADJ;
14584            schedGroup = app.execServicesFg ?
14585                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14586            app.adjType = "exec-service";
14587            procState = ActivityManager.PROCESS_STATE_SERVICE;
14588            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14589        } else {
14590            // As far as we know the process is empty.  We may change our mind later.
14591            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14592            // At this point we don't actually know the adjustment.  Use the cached adj
14593            // value that the caller wants us to.
14594            adj = cachedAdj;
14595            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14596            app.cached = true;
14597            app.empty = true;
14598            app.adjType = "cch-empty";
14599        }
14600
14601        // Examine all activities if not already foreground.
14602        if (!foregroundActivities && activitiesSize > 0) {
14603            for (int j = 0; j < activitiesSize; j++) {
14604                final ActivityRecord r = app.activities.get(j);
14605                if (r.app != app) {
14606                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14607                            + app + "?!?");
14608                    continue;
14609                }
14610                if (r.visible) {
14611                    // App has a visible activity; only upgrade adjustment.
14612                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14613                        adj = ProcessList.VISIBLE_APP_ADJ;
14614                        app.adjType = "visible";
14615                    }
14616                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14617                        procState = ActivityManager.PROCESS_STATE_TOP;
14618                    }
14619                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14620                    app.cached = false;
14621                    app.empty = false;
14622                    foregroundActivities = true;
14623                    break;
14624                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14625                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14626                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14627                        app.adjType = "pausing";
14628                    }
14629                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14630                        procState = ActivityManager.PROCESS_STATE_TOP;
14631                    }
14632                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14633                    app.cached = false;
14634                    app.empty = false;
14635                    foregroundActivities = true;
14636                } else if (r.state == ActivityState.STOPPING) {
14637                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14638                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14639                        app.adjType = "stopping";
14640                    }
14641                    // For the process state, we will at this point consider the
14642                    // process to be cached.  It will be cached either as an activity
14643                    // or empty depending on whether the activity is finishing.  We do
14644                    // this so that we can treat the process as cached for purposes of
14645                    // memory trimming (determing current memory level, trim command to
14646                    // send to process) since there can be an arbitrary number of stopping
14647                    // processes and they should soon all go into the cached state.
14648                    if (!r.finishing) {
14649                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14650                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14651                        }
14652                    }
14653                    app.cached = false;
14654                    app.empty = false;
14655                    foregroundActivities = true;
14656                } else {
14657                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14658                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14659                        app.adjType = "cch-act";
14660                    }
14661                }
14662            }
14663        }
14664
14665        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14666            if (app.foregroundServices) {
14667                // The user is aware of this app, so make it visible.
14668                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14669                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14670                app.cached = false;
14671                app.adjType = "fg-service";
14672                schedGroup = Process.THREAD_GROUP_DEFAULT;
14673            } else if (app.forcingToForeground != null) {
14674                // The user is aware of this app, so make it visible.
14675                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14676                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14677                app.cached = false;
14678                app.adjType = "force-fg";
14679                app.adjSource = app.forcingToForeground;
14680                schedGroup = Process.THREAD_GROUP_DEFAULT;
14681            }
14682        }
14683
14684        if (app.foregroundServices) {
14685            interesting = true;
14686        }
14687
14688        if (app == mHeavyWeightProcess) {
14689            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14690                // We don't want to kill the current heavy-weight process.
14691                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14692                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14693                app.cached = false;
14694                app.adjType = "heavy";
14695            }
14696            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14697                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14698            }
14699        }
14700
14701        if (app == mHomeProcess) {
14702            if (adj > ProcessList.HOME_APP_ADJ) {
14703                // This process is hosting what we currently consider to be the
14704                // home app, so we don't want to let it go into the background.
14705                adj = ProcessList.HOME_APP_ADJ;
14706                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14707                app.cached = false;
14708                app.adjType = "home";
14709            }
14710            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14711                procState = ActivityManager.PROCESS_STATE_HOME;
14712            }
14713        }
14714
14715        if (app == mPreviousProcess && app.activities.size() > 0) {
14716            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14717                // This was the previous process that showed UI to the user.
14718                // We want to try to keep it around more aggressively, to give
14719                // a good experience around switching between two apps.
14720                adj = ProcessList.PREVIOUS_APP_ADJ;
14721                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14722                app.cached = false;
14723                app.adjType = "previous";
14724            }
14725            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14726                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14727            }
14728        }
14729
14730        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14731                + " reason=" + app.adjType);
14732
14733        // By default, we use the computed adjustment.  It may be changed if
14734        // there are applications dependent on our services or providers, but
14735        // this gives us a baseline and makes sure we don't get into an
14736        // infinite recursion.
14737        app.adjSeq = mAdjSeq;
14738        app.curRawAdj = adj;
14739        app.hasStartedServices = false;
14740
14741        if (mBackupTarget != null && app == mBackupTarget.app) {
14742            // If possible we want to avoid killing apps while they're being backed up
14743            if (adj > ProcessList.BACKUP_APP_ADJ) {
14744                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14745                adj = ProcessList.BACKUP_APP_ADJ;
14746                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14747                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14748                }
14749                app.adjType = "backup";
14750                app.cached = false;
14751            }
14752            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14753                procState = ActivityManager.PROCESS_STATE_BACKUP;
14754            }
14755        }
14756
14757        boolean mayBeTop = false;
14758
14759        for (int is = app.services.size()-1;
14760                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14761                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14762                        || procState > ActivityManager.PROCESS_STATE_TOP);
14763                is--) {
14764            ServiceRecord s = app.services.valueAt(is);
14765            if (s.startRequested) {
14766                app.hasStartedServices = true;
14767                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14768                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14769                }
14770                if (app.hasShownUi && app != mHomeProcess) {
14771                    // If this process has shown some UI, let it immediately
14772                    // go to the LRU list because it may be pretty heavy with
14773                    // UI stuff.  We'll tag it with a label just to help
14774                    // debug and understand what is going on.
14775                    if (adj > ProcessList.SERVICE_ADJ) {
14776                        app.adjType = "cch-started-ui-services";
14777                    }
14778                } else {
14779                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14780                        // This service has seen some activity within
14781                        // recent memory, so we will keep its process ahead
14782                        // of the background processes.
14783                        if (adj > ProcessList.SERVICE_ADJ) {
14784                            adj = ProcessList.SERVICE_ADJ;
14785                            app.adjType = "started-services";
14786                            app.cached = false;
14787                        }
14788                    }
14789                    // If we have let the service slide into the background
14790                    // state, still have some text describing what it is doing
14791                    // even though the service no longer has an impact.
14792                    if (adj > ProcessList.SERVICE_ADJ) {
14793                        app.adjType = "cch-started-services";
14794                    }
14795                }
14796                // Don't kill this process because it is doing work; it
14797                // has said it is doing work.
14798                app.keeping = true;
14799            }
14800            for (int conni = s.connections.size()-1;
14801                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14802                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14803                            || procState > ActivityManager.PROCESS_STATE_TOP);
14804                    conni--) {
14805                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14806                for (int i = 0;
14807                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14808                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14809                                || procState > ActivityManager.PROCESS_STATE_TOP);
14810                        i++) {
14811                    // XXX should compute this based on the max of
14812                    // all connected clients.
14813                    ConnectionRecord cr = clist.get(i);
14814                    if (cr.binding.client == app) {
14815                        // Binding to ourself is not interesting.
14816                        continue;
14817                    }
14818                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14819                        ProcessRecord client = cr.binding.client;
14820                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14821                                TOP_APP, doingAll, now);
14822                        int clientProcState = client.curProcState;
14823                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14824                            // If the other app is cached for any reason, for purposes here
14825                            // we are going to consider it empty.  The specific cached state
14826                            // doesn't propagate except under certain conditions.
14827                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14828                        }
14829                        String adjType = null;
14830                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14831                            // Not doing bind OOM management, so treat
14832                            // this guy more like a started service.
14833                            if (app.hasShownUi && app != mHomeProcess) {
14834                                // If this process has shown some UI, let it immediately
14835                                // go to the LRU list because it may be pretty heavy with
14836                                // UI stuff.  We'll tag it with a label just to help
14837                                // debug and understand what is going on.
14838                                if (adj > clientAdj) {
14839                                    adjType = "cch-bound-ui-services";
14840                                }
14841                                app.cached = false;
14842                                clientAdj = adj;
14843                                clientProcState = procState;
14844                            } else {
14845                                if (now >= (s.lastActivity
14846                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14847                                    // This service has not seen activity within
14848                                    // recent memory, so allow it to drop to the
14849                                    // LRU list if there is no other reason to keep
14850                                    // it around.  We'll also tag it with a label just
14851                                    // to help debug and undertand what is going on.
14852                                    if (adj > clientAdj) {
14853                                        adjType = "cch-bound-services";
14854                                    }
14855                                    clientAdj = adj;
14856                                }
14857                            }
14858                        }
14859                        if (adj > clientAdj) {
14860                            // If this process has recently shown UI, and
14861                            // the process that is binding to it is less
14862                            // important than being visible, then we don't
14863                            // care about the binding as much as we care
14864                            // about letting this process get into the LRU
14865                            // list to be killed and restarted if needed for
14866                            // memory.
14867                            if (app.hasShownUi && app != mHomeProcess
14868                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14869                                adjType = "cch-bound-ui-services";
14870                            } else {
14871                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14872                                        |Context.BIND_IMPORTANT)) != 0) {
14873                                    adj = clientAdj;
14874                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14875                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14876                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14877                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14878                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14879                                    adj = clientAdj;
14880                                } else {
14881                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14882                                        adj = ProcessList.VISIBLE_APP_ADJ;
14883                                    }
14884                                }
14885                                if (!client.cached) {
14886                                    app.cached = false;
14887                                }
14888                                if (client.keeping) {
14889                                    app.keeping = true;
14890                                }
14891                                adjType = "service";
14892                            }
14893                        }
14894                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14895                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14896                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14897                            }
14898                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14899                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14900                                    // Special handling of clients who are in the top state.
14901                                    // We *may* want to consider this process to be in the
14902                                    // top state as well, but only if there is not another
14903                                    // reason for it to be running.  Being on the top is a
14904                                    // special state, meaning you are specifically running
14905                                    // for the current top app.  If the process is already
14906                                    // running in the background for some other reason, it
14907                                    // is more important to continue considering it to be
14908                                    // in the background state.
14909                                    mayBeTop = true;
14910                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14911                                } else {
14912                                    // Special handling for above-top states (persistent
14913                                    // processes).  These should not bring the current process
14914                                    // into the top state, since they are not on top.  Instead
14915                                    // give them the best state after that.
14916                                    clientProcState =
14917                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14918                                }
14919                            }
14920                        } else {
14921                            if (clientProcState <
14922                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14923                                clientProcState =
14924                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14925                            }
14926                        }
14927                        if (procState > clientProcState) {
14928                            procState = clientProcState;
14929                        }
14930                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14931                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14932                            app.pendingUiClean = true;
14933                        }
14934                        if (adjType != null) {
14935                            app.adjType = adjType;
14936                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14937                                    .REASON_SERVICE_IN_USE;
14938                            app.adjSource = cr.binding.client;
14939                            app.adjSourceOom = clientAdj;
14940                            app.adjTarget = s.name;
14941                        }
14942                    }
14943                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
14944                        app.treatLikeActivity = true;
14945                    }
14946                    final ActivityRecord a = cr.activity;
14947                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14948                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14949                                (a.visible || a.state == ActivityState.RESUMED
14950                                 || a.state == ActivityState.PAUSING)) {
14951                            adj = ProcessList.FOREGROUND_APP_ADJ;
14952                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14953                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14954                            }
14955                            app.cached = false;
14956                            app.adjType = "service";
14957                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14958                                    .REASON_SERVICE_IN_USE;
14959                            app.adjSource = a;
14960                            app.adjSourceOom = adj;
14961                            app.adjTarget = s.name;
14962                        }
14963                    }
14964                }
14965            }
14966        }
14967
14968        for (int provi = app.pubProviders.size()-1;
14969                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14970                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14971                        || procState > ActivityManager.PROCESS_STATE_TOP);
14972                provi--) {
14973            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14974            for (int i = cpr.connections.size()-1;
14975                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14976                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14977                            || procState > ActivityManager.PROCESS_STATE_TOP);
14978                    i--) {
14979                ContentProviderConnection conn = cpr.connections.get(i);
14980                ProcessRecord client = conn.client;
14981                if (client == app) {
14982                    // Being our own client is not interesting.
14983                    continue;
14984                }
14985                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14986                int clientProcState = client.curProcState;
14987                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14988                    // If the other app is cached for any reason, for purposes here
14989                    // we are going to consider it empty.
14990                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14991                }
14992                if (adj > clientAdj) {
14993                    if (app.hasShownUi && app != mHomeProcess
14994                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14995                        app.adjType = "cch-ui-provider";
14996                    } else {
14997                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14998                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14999                        app.adjType = "provider";
15000                    }
15001                    app.cached &= client.cached;
15002                    app.keeping |= client.keeping;
15003                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15004                            .REASON_PROVIDER_IN_USE;
15005                    app.adjSource = client;
15006                    app.adjSourceOom = clientAdj;
15007                    app.adjTarget = cpr.name;
15008                }
15009                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15010                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15011                        // Special handling of clients who are in the top state.
15012                        // We *may* want to consider this process to be in the
15013                        // top state as well, but only if there is not another
15014                        // reason for it to be running.  Being on the top is a
15015                        // special state, meaning you are specifically running
15016                        // for the current top app.  If the process is already
15017                        // running in the background for some other reason, it
15018                        // is more important to continue considering it to be
15019                        // in the background state.
15020                        mayBeTop = true;
15021                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15022                    } else {
15023                        // Special handling for above-top states (persistent
15024                        // processes).  These should not bring the current process
15025                        // into the top state, since they are not on top.  Instead
15026                        // give them the best state after that.
15027                        clientProcState =
15028                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15029                    }
15030                }
15031                if (procState > clientProcState) {
15032                    procState = clientProcState;
15033                }
15034                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15035                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15036                }
15037            }
15038            // If the provider has external (non-framework) process
15039            // dependencies, ensure that its adjustment is at least
15040            // FOREGROUND_APP_ADJ.
15041            if (cpr.hasExternalProcessHandles()) {
15042                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15043                    adj = ProcessList.FOREGROUND_APP_ADJ;
15044                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15045                    app.cached = false;
15046                    app.keeping = true;
15047                    app.adjType = "provider";
15048                    app.adjTarget = cpr.name;
15049                }
15050                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15051                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15052                }
15053            }
15054        }
15055
15056        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15057            // A client of one of our services or providers is in the top state.  We
15058            // *may* want to be in the top state, but not if we are already running in
15059            // the background for some other reason.  For the decision here, we are going
15060            // to pick out a few specific states that we want to remain in when a client
15061            // is top (states that tend to be longer-term) and otherwise allow it to go
15062            // to the top state.
15063            switch (procState) {
15064                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15065                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15066                case ActivityManager.PROCESS_STATE_SERVICE:
15067                    // These all are longer-term states, so pull them up to the top
15068                    // of the background states, but not all the way to the top state.
15069                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15070                    break;
15071                default:
15072                    // Otherwise, top is a better choice, so take it.
15073                    procState = ActivityManager.PROCESS_STATE_TOP;
15074                    break;
15075            }
15076        }
15077
15078        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15079            if (app.hasClientActivities) {
15080                // This is a cached process, but with client activities.  Mark it so.
15081                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15082                app.adjType = "cch-client-act";
15083            } else if (app.treatLikeActivity) {
15084                // This is a cached process, but somebody wants us to treat it like it has
15085                // an activity, okay!
15086                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15087                app.adjType = "cch-as-act";
15088            }
15089        }
15090
15091        if (adj == ProcessList.SERVICE_ADJ) {
15092            if (doingAll) {
15093                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15094                mNewNumServiceProcs++;
15095                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15096                if (!app.serviceb) {
15097                    // This service isn't far enough down on the LRU list to
15098                    // normally be a B service, but if we are low on RAM and it
15099                    // is large we want to force it down since we would prefer to
15100                    // keep launcher over it.
15101                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15102                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15103                        app.serviceHighRam = true;
15104                        app.serviceb = true;
15105                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15106                    } else {
15107                        mNewNumAServiceProcs++;
15108                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15109                    }
15110                } else {
15111                    app.serviceHighRam = false;
15112                }
15113            }
15114            if (app.serviceb) {
15115                adj = ProcessList.SERVICE_B_ADJ;
15116            }
15117        }
15118
15119        app.curRawAdj = adj;
15120
15121        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15122        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15123        if (adj > app.maxAdj) {
15124            adj = app.maxAdj;
15125            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15126                schedGroup = Process.THREAD_GROUP_DEFAULT;
15127            }
15128        }
15129        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15130            app.keeping = true;
15131        }
15132
15133        // Do final modification to adj.  Everything we do between here and applying
15134        // the final setAdj must be done in this function, because we will also use
15135        // it when computing the final cached adj later.  Note that we don't need to
15136        // worry about this for max adj above, since max adj will always be used to
15137        // keep it out of the cached vaues.
15138        adj = app.modifyRawOomAdj(adj);
15139
15140        app.curProcState = procState;
15141
15142        int importance = app.memImportance;
15143        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
15144            app.curAdj = adj;
15145            app.curSchedGroup = schedGroup;
15146            if (!interesting) {
15147                // For this reporting, if there is not something explicitly
15148                // interesting in this process then we will push it to the
15149                // background importance.
15150                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15151            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
15152                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15153            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
15154                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15155            } else if (adj >= ProcessList.HOME_APP_ADJ) {
15156                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15157            } else if (adj >= ProcessList.SERVICE_ADJ) {
15158                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15159            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15160                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
15161            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
15162                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
15163            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
15164                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
15165            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
15166                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
15167            } else {
15168                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
15169            }
15170        }
15171
15172        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
15173        if (foregroundActivities != app.foregroundActivities) {
15174            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15175        }
15176        if (changes != 0) {
15177            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15178            app.memImportance = importance;
15179            app.foregroundActivities = foregroundActivities;
15180            int i = mPendingProcessChanges.size()-1;
15181            ProcessChangeItem item = null;
15182            while (i >= 0) {
15183                item = mPendingProcessChanges.get(i);
15184                if (item.pid == app.pid) {
15185                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15186                    break;
15187                }
15188                i--;
15189            }
15190            if (i < 0) {
15191                // No existing item in pending changes; need a new one.
15192                final int NA = mAvailProcessChanges.size();
15193                if (NA > 0) {
15194                    item = mAvailProcessChanges.remove(NA-1);
15195                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15196                } else {
15197                    item = new ProcessChangeItem();
15198                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15199                }
15200                item.changes = 0;
15201                item.pid = app.pid;
15202                item.uid = app.info.uid;
15203                if (mPendingProcessChanges.size() == 0) {
15204                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15205                            "*** Enqueueing dispatch processes changed!");
15206                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15207                }
15208                mPendingProcessChanges.add(item);
15209            }
15210            item.changes |= changes;
15211            item.importance = importance;
15212            item.foregroundActivities = foregroundActivities;
15213            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15214                    + Integer.toHexString(System.identityHashCode(item))
15215                    + " " + app.toShortString() + ": changes=" + item.changes
15216                    + " importance=" + item.importance
15217                    + " foreground=" + item.foregroundActivities
15218                    + " type=" + app.adjType + " source=" + app.adjSource
15219                    + " target=" + app.adjTarget);
15220        }
15221
15222        return app.curRawAdj;
15223    }
15224
15225    /**
15226     * Schedule PSS collection of a process.
15227     */
15228    void requestPssLocked(ProcessRecord proc, int procState) {
15229        if (mPendingPssProcesses.contains(proc)) {
15230            return;
15231        }
15232        if (mPendingPssProcesses.size() == 0) {
15233            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15234        }
15235        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15236        proc.pssProcState = procState;
15237        mPendingPssProcesses.add(proc);
15238    }
15239
15240    /**
15241     * Schedule PSS collection of all processes.
15242     */
15243    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15244        if (!always) {
15245            if (now < (mLastFullPssTime +
15246                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15247                return;
15248            }
15249        }
15250        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15251        mLastFullPssTime = now;
15252        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15253        mPendingPssProcesses.clear();
15254        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15255            ProcessRecord app = mLruProcesses.get(i);
15256            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15257                app.pssProcState = app.setProcState;
15258                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15259                        mSleeping, now);
15260                mPendingPssProcesses.add(app);
15261            }
15262        }
15263        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15264    }
15265
15266    /**
15267     * Ask a given process to GC right now.
15268     */
15269    final void performAppGcLocked(ProcessRecord app) {
15270        try {
15271            app.lastRequestedGc = SystemClock.uptimeMillis();
15272            if (app.thread != null) {
15273                if (app.reportLowMemory) {
15274                    app.reportLowMemory = false;
15275                    app.thread.scheduleLowMemory();
15276                } else {
15277                    app.thread.processInBackground();
15278                }
15279            }
15280        } catch (Exception e) {
15281            // whatever.
15282        }
15283    }
15284
15285    /**
15286     * Returns true if things are idle enough to perform GCs.
15287     */
15288    private final boolean canGcNowLocked() {
15289        boolean processingBroadcasts = false;
15290        for (BroadcastQueue q : mBroadcastQueues) {
15291            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15292                processingBroadcasts = true;
15293            }
15294        }
15295        return !processingBroadcasts
15296                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15297    }
15298
15299    /**
15300     * Perform GCs on all processes that are waiting for it, but only
15301     * if things are idle.
15302     */
15303    final void performAppGcsLocked() {
15304        final int N = mProcessesToGc.size();
15305        if (N <= 0) {
15306            return;
15307        }
15308        if (canGcNowLocked()) {
15309            while (mProcessesToGc.size() > 0) {
15310                ProcessRecord proc = mProcessesToGc.remove(0);
15311                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15312                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15313                            <= SystemClock.uptimeMillis()) {
15314                        // To avoid spamming the system, we will GC processes one
15315                        // at a time, waiting a few seconds between each.
15316                        performAppGcLocked(proc);
15317                        scheduleAppGcsLocked();
15318                        return;
15319                    } else {
15320                        // It hasn't been long enough since we last GCed this
15321                        // process...  put it in the list to wait for its time.
15322                        addProcessToGcListLocked(proc);
15323                        break;
15324                    }
15325                }
15326            }
15327
15328            scheduleAppGcsLocked();
15329        }
15330    }
15331
15332    /**
15333     * If all looks good, perform GCs on all processes waiting for them.
15334     */
15335    final void performAppGcsIfAppropriateLocked() {
15336        if (canGcNowLocked()) {
15337            performAppGcsLocked();
15338            return;
15339        }
15340        // Still not idle, wait some more.
15341        scheduleAppGcsLocked();
15342    }
15343
15344    /**
15345     * Schedule the execution of all pending app GCs.
15346     */
15347    final void scheduleAppGcsLocked() {
15348        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15349
15350        if (mProcessesToGc.size() > 0) {
15351            // Schedule a GC for the time to the next process.
15352            ProcessRecord proc = mProcessesToGc.get(0);
15353            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15354
15355            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15356            long now = SystemClock.uptimeMillis();
15357            if (when < (now+GC_TIMEOUT)) {
15358                when = now + GC_TIMEOUT;
15359            }
15360            mHandler.sendMessageAtTime(msg, when);
15361        }
15362    }
15363
15364    /**
15365     * Add a process to the array of processes waiting to be GCed.  Keeps the
15366     * list in sorted order by the last GC time.  The process can't already be
15367     * on the list.
15368     */
15369    final void addProcessToGcListLocked(ProcessRecord proc) {
15370        boolean added = false;
15371        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15372            if (mProcessesToGc.get(i).lastRequestedGc <
15373                    proc.lastRequestedGc) {
15374                added = true;
15375                mProcessesToGc.add(i+1, proc);
15376                break;
15377            }
15378        }
15379        if (!added) {
15380            mProcessesToGc.add(0, proc);
15381        }
15382    }
15383
15384    /**
15385     * Set up to ask a process to GC itself.  This will either do it
15386     * immediately, or put it on the list of processes to gc the next
15387     * time things are idle.
15388     */
15389    final void scheduleAppGcLocked(ProcessRecord app) {
15390        long now = SystemClock.uptimeMillis();
15391        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15392            return;
15393        }
15394        if (!mProcessesToGc.contains(app)) {
15395            addProcessToGcListLocked(app);
15396            scheduleAppGcsLocked();
15397        }
15398    }
15399
15400    final void checkExcessivePowerUsageLocked(boolean doKills) {
15401        updateCpuStatsNow();
15402
15403        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15404        boolean doWakeKills = doKills;
15405        boolean doCpuKills = doKills;
15406        if (mLastPowerCheckRealtime == 0) {
15407            doWakeKills = false;
15408        }
15409        if (mLastPowerCheckUptime == 0) {
15410            doCpuKills = false;
15411        }
15412        if (stats.isScreenOn()) {
15413            doWakeKills = false;
15414        }
15415        final long curRealtime = SystemClock.elapsedRealtime();
15416        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15417        final long curUptime = SystemClock.uptimeMillis();
15418        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15419        mLastPowerCheckRealtime = curRealtime;
15420        mLastPowerCheckUptime = curUptime;
15421        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15422            doWakeKills = false;
15423        }
15424        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15425            doCpuKills = false;
15426        }
15427        int i = mLruProcesses.size();
15428        while (i > 0) {
15429            i--;
15430            ProcessRecord app = mLruProcesses.get(i);
15431            if (!app.keeping) {
15432                long wtime;
15433                synchronized (stats) {
15434                    wtime = stats.getProcessWakeTime(app.info.uid,
15435                            app.pid, curRealtime);
15436                }
15437                long wtimeUsed = wtime - app.lastWakeTime;
15438                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15439                if (DEBUG_POWER) {
15440                    StringBuilder sb = new StringBuilder(128);
15441                    sb.append("Wake for ");
15442                    app.toShortString(sb);
15443                    sb.append(": over ");
15444                    TimeUtils.formatDuration(realtimeSince, sb);
15445                    sb.append(" used ");
15446                    TimeUtils.formatDuration(wtimeUsed, sb);
15447                    sb.append(" (");
15448                    sb.append((wtimeUsed*100)/realtimeSince);
15449                    sb.append("%)");
15450                    Slog.i(TAG, sb.toString());
15451                    sb.setLength(0);
15452                    sb.append("CPU for ");
15453                    app.toShortString(sb);
15454                    sb.append(": over ");
15455                    TimeUtils.formatDuration(uptimeSince, sb);
15456                    sb.append(" used ");
15457                    TimeUtils.formatDuration(cputimeUsed, sb);
15458                    sb.append(" (");
15459                    sb.append((cputimeUsed*100)/uptimeSince);
15460                    sb.append("%)");
15461                    Slog.i(TAG, sb.toString());
15462                }
15463                // If a process has held a wake lock for more
15464                // than 50% of the time during this period,
15465                // that sounds bad.  Kill!
15466                if (doWakeKills && realtimeSince > 0
15467                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15468                    synchronized (stats) {
15469                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15470                                realtimeSince, wtimeUsed);
15471                    }
15472                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15473                            + " during " + realtimeSince);
15474                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15475                } else if (doCpuKills && uptimeSince > 0
15476                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15477                    synchronized (stats) {
15478                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15479                                uptimeSince, cputimeUsed);
15480                    }
15481                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15482                            + " during " + uptimeSince);
15483                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15484                } else {
15485                    app.lastWakeTime = wtime;
15486                    app.lastCpuTime = app.curCpuTime;
15487                }
15488            }
15489        }
15490    }
15491
15492    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15493            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15494        boolean success = true;
15495
15496        if (app.curRawAdj != app.setRawAdj) {
15497            if (wasKeeping && !app.keeping) {
15498                // This app is no longer something we want to keep.  Note
15499                // its current wake lock time to later know to kill it if
15500                // it is not behaving well.
15501                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15502                synchronized (stats) {
15503                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15504                            app.pid, SystemClock.elapsedRealtime());
15505                }
15506                app.lastCpuTime = app.curCpuTime;
15507            }
15508
15509            app.setRawAdj = app.curRawAdj;
15510        }
15511
15512        if (app.curAdj != app.setAdj) {
15513            ProcessList.setOomAdj(app.pid, app.curAdj);
15514            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15515                TAG, "Set " + app.pid + " " + app.processName +
15516                " adj " + app.curAdj + ": " + app.adjType);
15517            app.setAdj = app.curAdj;
15518        }
15519
15520        if (app.setSchedGroup != app.curSchedGroup) {
15521            app.setSchedGroup = app.curSchedGroup;
15522            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15523                    "Setting process group of " + app.processName
15524                    + " to " + app.curSchedGroup);
15525            if (app.waitingToKill != null &&
15526                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15527                killUnneededProcessLocked(app, app.waitingToKill);
15528                success = false;
15529            } else {
15530                if (true) {
15531                    long oldId = Binder.clearCallingIdentity();
15532                    try {
15533                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15534                    } catch (Exception e) {
15535                        Slog.w(TAG, "Failed setting process group of " + app.pid
15536                                + " to " + app.curSchedGroup);
15537                        e.printStackTrace();
15538                    } finally {
15539                        Binder.restoreCallingIdentity(oldId);
15540                    }
15541                } else {
15542                    if (app.thread != null) {
15543                        try {
15544                            app.thread.setSchedulingGroup(app.curSchedGroup);
15545                        } catch (RemoteException e) {
15546                        }
15547                    }
15548                }
15549                Process.setSwappiness(app.pid,
15550                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15551            }
15552        }
15553        if (app.repProcState != app.curProcState) {
15554            app.repProcState = app.curProcState;
15555            if (!reportingProcessState && app.thread != null) {
15556                try {
15557                    if (false) {
15558                        //RuntimeException h = new RuntimeException("here");
15559                        Slog.i(TAG, "Sending new process state " + app.repProcState
15560                                + " to " + app /*, h*/);
15561                    }
15562                    app.thread.setProcessState(app.repProcState);
15563                } catch (RemoteException e) {
15564                }
15565            }
15566        }
15567        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15568                app.setProcState)) {
15569            app.lastStateTime = now;
15570            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15571                    mSleeping, now);
15572            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15573                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15574                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15575                    + (app.nextPssTime-now) + ": " + app);
15576        } else {
15577            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15578                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15579                requestPssLocked(app, app.setProcState);
15580                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15581                        mSleeping, now);
15582            } else if (false && DEBUG_PSS) {
15583                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15584            }
15585        }
15586        if (app.setProcState != app.curProcState) {
15587            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15588                    "Proc state change of " + app.processName
15589                    + " to " + app.curProcState);
15590            app.setProcState = app.curProcState;
15591            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15592                app.notCachedSinceIdle = false;
15593            }
15594            if (!doingAll) {
15595                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15596            } else {
15597                app.procStateChanged = true;
15598            }
15599        }
15600        return success;
15601    }
15602
15603    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15604        if (proc.thread != null && proc.baseProcessTracker != null) {
15605            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15606        }
15607    }
15608
15609    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15610            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15611        if (app.thread == null) {
15612            return false;
15613        }
15614
15615        final boolean wasKeeping = app.keeping;
15616
15617        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15618
15619        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15620                reportingProcessState, now);
15621    }
15622
15623    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15624            boolean oomAdj) {
15625        if (isForeground != proc.foregroundServices) {
15626            proc.foregroundServices = isForeground;
15627            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15628                    proc.info.uid);
15629            if (isForeground) {
15630                if (curProcs == null) {
15631                    curProcs = new ArrayList<ProcessRecord>();
15632                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15633                }
15634                if (!curProcs.contains(proc)) {
15635                    curProcs.add(proc);
15636                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15637                            proc.info.packageName, proc.info.uid);
15638                }
15639            } else {
15640                if (curProcs != null) {
15641                    if (curProcs.remove(proc)) {
15642                        mBatteryStatsService.noteEvent(
15643                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15644                                proc.info.packageName, proc.info.uid);
15645                        if (curProcs.size() <= 0) {
15646                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15647                        }
15648                    }
15649                }
15650            }
15651            if (oomAdj) {
15652                updateOomAdjLocked();
15653            }
15654        }
15655    }
15656
15657    private final ActivityRecord resumedAppLocked() {
15658        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15659        String pkg;
15660        int uid;
15661        if (act != null && !act.sleeping) {
15662            pkg = act.packageName;
15663            uid = act.info.applicationInfo.uid;
15664        } else {
15665            pkg = null;
15666            uid = -1;
15667        }
15668        // Has the UID or resumed package name changed?
15669        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15670                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15671            if (mCurResumedPackage != null) {
15672                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15673                        mCurResumedPackage, mCurResumedUid);
15674            }
15675            mCurResumedPackage = pkg;
15676            mCurResumedUid = uid;
15677            if (mCurResumedPackage != null) {
15678                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15679                        mCurResumedPackage, mCurResumedUid);
15680            }
15681        }
15682        return act;
15683    }
15684
15685    final boolean updateOomAdjLocked(ProcessRecord app) {
15686        return updateOomAdjLocked(app, false);
15687    }
15688
15689    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15690        final ActivityRecord TOP_ACT = resumedAppLocked();
15691        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15692        final boolean wasCached = app.cached;
15693
15694        mAdjSeq++;
15695
15696        // This is the desired cached adjusment we want to tell it to use.
15697        // If our app is currently cached, we know it, and that is it.  Otherwise,
15698        // we don't know it yet, and it needs to now be cached we will then
15699        // need to do a complete oom adj.
15700        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15701                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15702        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15703                SystemClock.uptimeMillis());
15704        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15705            // Changed to/from cached state, so apps after it in the LRU
15706            // list may also be changed.
15707            updateOomAdjLocked();
15708        }
15709        return success;
15710    }
15711
15712    final void updateOomAdjLocked() {
15713        final ActivityRecord TOP_ACT = resumedAppLocked();
15714        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15715        final long now = SystemClock.uptimeMillis();
15716        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15717        final int N = mLruProcesses.size();
15718
15719        if (false) {
15720            RuntimeException e = new RuntimeException();
15721            e.fillInStackTrace();
15722            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15723        }
15724
15725        mAdjSeq++;
15726        mNewNumServiceProcs = 0;
15727        mNewNumAServiceProcs = 0;
15728
15729        final int emptyProcessLimit;
15730        final int cachedProcessLimit;
15731        if (mProcessLimit <= 0) {
15732            emptyProcessLimit = cachedProcessLimit = 0;
15733        } else if (mProcessLimit == 1) {
15734            emptyProcessLimit = 1;
15735            cachedProcessLimit = 0;
15736        } else {
15737            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15738            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15739        }
15740
15741        // Let's determine how many processes we have running vs.
15742        // how many slots we have for background processes; we may want
15743        // to put multiple processes in a slot of there are enough of
15744        // them.
15745        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15746                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15747        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15748        if (numEmptyProcs > cachedProcessLimit) {
15749            // If there are more empty processes than our limit on cached
15750            // processes, then use the cached process limit for the factor.
15751            // This ensures that the really old empty processes get pushed
15752            // down to the bottom, so if we are running low on memory we will
15753            // have a better chance at keeping around more cached processes
15754            // instead of a gazillion empty processes.
15755            numEmptyProcs = cachedProcessLimit;
15756        }
15757        int emptyFactor = numEmptyProcs/numSlots;
15758        if (emptyFactor < 1) emptyFactor = 1;
15759        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15760        if (cachedFactor < 1) cachedFactor = 1;
15761        int stepCached = 0;
15762        int stepEmpty = 0;
15763        int numCached = 0;
15764        int numEmpty = 0;
15765        int numTrimming = 0;
15766
15767        mNumNonCachedProcs = 0;
15768        mNumCachedHiddenProcs = 0;
15769
15770        // First update the OOM adjustment for each of the
15771        // application processes based on their current state.
15772        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15773        int nextCachedAdj = curCachedAdj+1;
15774        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15775        int nextEmptyAdj = curEmptyAdj+2;
15776        for (int i=N-1; i>=0; i--) {
15777            ProcessRecord app = mLruProcesses.get(i);
15778            if (!app.killedByAm && app.thread != null) {
15779                app.procStateChanged = false;
15780                final boolean wasKeeping = app.keeping;
15781                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15782
15783                // If we haven't yet assigned the final cached adj
15784                // to the process, do that now.
15785                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15786                    switch (app.curProcState) {
15787                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15788                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15789                            // This process is a cached process holding activities...
15790                            // assign it the next cached value for that type, and then
15791                            // step that cached level.
15792                            app.curRawAdj = curCachedAdj;
15793                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15794                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15795                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15796                                    + ")");
15797                            if (curCachedAdj != nextCachedAdj) {
15798                                stepCached++;
15799                                if (stepCached >= cachedFactor) {
15800                                    stepCached = 0;
15801                                    curCachedAdj = nextCachedAdj;
15802                                    nextCachedAdj += 2;
15803                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15804                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15805                                    }
15806                                }
15807                            }
15808                            break;
15809                        default:
15810                            // For everything else, assign next empty cached process
15811                            // level and bump that up.  Note that this means that
15812                            // long-running services that have dropped down to the
15813                            // cached level will be treated as empty (since their process
15814                            // state is still as a service), which is what we want.
15815                            app.curRawAdj = curEmptyAdj;
15816                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15817                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15818                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15819                                    + ")");
15820                            if (curEmptyAdj != nextEmptyAdj) {
15821                                stepEmpty++;
15822                                if (stepEmpty >= emptyFactor) {
15823                                    stepEmpty = 0;
15824                                    curEmptyAdj = nextEmptyAdj;
15825                                    nextEmptyAdj += 2;
15826                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15827                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15828                                    }
15829                                }
15830                            }
15831                            break;
15832                    }
15833                }
15834
15835                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15836
15837                // Count the number of process types.
15838                switch (app.curProcState) {
15839                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15840                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15841                        mNumCachedHiddenProcs++;
15842                        numCached++;
15843                        if (numCached > cachedProcessLimit) {
15844                            killUnneededProcessLocked(app, "cached #" + numCached);
15845                        }
15846                        break;
15847                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15848                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15849                                && app.lastActivityTime < oldTime) {
15850                            killUnneededProcessLocked(app, "empty for "
15851                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15852                                    / 1000) + "s");
15853                        } else {
15854                            numEmpty++;
15855                            if (numEmpty > emptyProcessLimit) {
15856                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15857                            }
15858                        }
15859                        break;
15860                    default:
15861                        mNumNonCachedProcs++;
15862                        break;
15863                }
15864
15865                if (app.isolated && app.services.size() <= 0) {
15866                    // If this is an isolated process, and there are no
15867                    // services running in it, then the process is no longer
15868                    // needed.  We agressively kill these because we can by
15869                    // definition not re-use the same process again, and it is
15870                    // good to avoid having whatever code was running in them
15871                    // left sitting around after no longer needed.
15872                    killUnneededProcessLocked(app, "isolated not needed");
15873                }
15874
15875                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15876                        && !app.killedByAm) {
15877                    numTrimming++;
15878                }
15879            }
15880        }
15881
15882        mNumServiceProcs = mNewNumServiceProcs;
15883
15884        // Now determine the memory trimming level of background processes.
15885        // Unfortunately we need to start at the back of the list to do this
15886        // properly.  We only do this if the number of background apps we
15887        // are managing to keep around is less than half the maximum we desire;
15888        // if we are keeping a good number around, we'll let them use whatever
15889        // memory they want.
15890        final int numCachedAndEmpty = numCached + numEmpty;
15891        int memFactor;
15892        if (numCached <= ProcessList.TRIM_CACHED_APPS
15893                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15894            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15895                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15896            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15897                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15898            } else {
15899                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15900            }
15901        } else {
15902            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15903        }
15904        // We always allow the memory level to go up (better).  We only allow it to go
15905        // down if we are in a state where that is allowed, *and* the total number of processes
15906        // has gone down since last time.
15907        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15908                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15909                + " last=" + mLastNumProcesses);
15910        if (memFactor > mLastMemoryLevel) {
15911            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15912                memFactor = mLastMemoryLevel;
15913                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15914            }
15915        }
15916        mLastMemoryLevel = memFactor;
15917        mLastNumProcesses = mLruProcesses.size();
15918        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15919        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15920        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15921            if (mLowRamStartTime == 0) {
15922                mLowRamStartTime = now;
15923            }
15924            int step = 0;
15925            int fgTrimLevel;
15926            switch (memFactor) {
15927                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15928                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15929                    break;
15930                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15931                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15932                    break;
15933                default:
15934                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15935                    break;
15936            }
15937            int factor = numTrimming/3;
15938            int minFactor = 2;
15939            if (mHomeProcess != null) minFactor++;
15940            if (mPreviousProcess != null) minFactor++;
15941            if (factor < minFactor) factor = minFactor;
15942            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15943            for (int i=N-1; i>=0; i--) {
15944                ProcessRecord app = mLruProcesses.get(i);
15945                if (allChanged || app.procStateChanged) {
15946                    setProcessTrackerState(app, trackerMemFactor, now);
15947                    app.procStateChanged = false;
15948                }
15949                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15950                        && !app.killedByAm) {
15951                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15952                        try {
15953                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15954                                    "Trimming memory of " + app.processName
15955                                    + " to " + curLevel);
15956                            app.thread.scheduleTrimMemory(curLevel);
15957                        } catch (RemoteException e) {
15958                        }
15959                        if (false) {
15960                            // For now we won't do this; our memory trimming seems
15961                            // to be good enough at this point that destroying
15962                            // activities causes more harm than good.
15963                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15964                                    && app != mHomeProcess && app != mPreviousProcess) {
15965                                // Need to do this on its own message because the stack may not
15966                                // be in a consistent state at this point.
15967                                // For these apps we will also finish their activities
15968                                // to help them free memory.
15969                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15970                            }
15971                        }
15972                    }
15973                    app.trimMemoryLevel = curLevel;
15974                    step++;
15975                    if (step >= factor) {
15976                        step = 0;
15977                        switch (curLevel) {
15978                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15979                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15980                                break;
15981                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15982                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15983                                break;
15984                        }
15985                    }
15986                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15987                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15988                            && app.thread != null) {
15989                        try {
15990                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15991                                    "Trimming memory of heavy-weight " + app.processName
15992                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15993                            app.thread.scheduleTrimMemory(
15994                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15995                        } catch (RemoteException e) {
15996                        }
15997                    }
15998                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15999                } else {
16000                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16001                            || app.systemNoUi) && app.pendingUiClean) {
16002                        // If this application is now in the background and it
16003                        // had done UI, then give it the special trim level to
16004                        // have it free UI resources.
16005                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16006                        if (app.trimMemoryLevel < level && app.thread != null) {
16007                            try {
16008                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16009                                        "Trimming memory of bg-ui " + app.processName
16010                                        + " to " + level);
16011                                app.thread.scheduleTrimMemory(level);
16012                            } catch (RemoteException e) {
16013                            }
16014                        }
16015                        app.pendingUiClean = false;
16016                    }
16017                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16018                        try {
16019                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16020                                    "Trimming memory of fg " + app.processName
16021                                    + " to " + fgTrimLevel);
16022                            app.thread.scheduleTrimMemory(fgTrimLevel);
16023                        } catch (RemoteException e) {
16024                        }
16025                    }
16026                    app.trimMemoryLevel = fgTrimLevel;
16027                }
16028            }
16029        } else {
16030            if (mLowRamStartTime != 0) {
16031                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16032                mLowRamStartTime = 0;
16033            }
16034            for (int i=N-1; i>=0; i--) {
16035                ProcessRecord app = mLruProcesses.get(i);
16036                if (allChanged || app.procStateChanged) {
16037                    setProcessTrackerState(app, trackerMemFactor, now);
16038                    app.procStateChanged = false;
16039                }
16040                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16041                        || app.systemNoUi) && app.pendingUiClean) {
16042                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16043                            && app.thread != null) {
16044                        try {
16045                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16046                                    "Trimming memory of ui hidden " + app.processName
16047                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16048                            app.thread.scheduleTrimMemory(
16049                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16050                        } catch (RemoteException e) {
16051                        }
16052                    }
16053                    app.pendingUiClean = false;
16054                }
16055                app.trimMemoryLevel = 0;
16056            }
16057        }
16058
16059        if (mAlwaysFinishActivities) {
16060            // Need to do this on its own message because the stack may not
16061            // be in a consistent state at this point.
16062            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16063        }
16064
16065        if (allChanged) {
16066            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16067        }
16068
16069        if (mProcessStats.shouldWriteNowLocked(now)) {
16070            mHandler.post(new Runnable() {
16071                @Override public void run() {
16072                    synchronized (ActivityManagerService.this) {
16073                        mProcessStats.writeStateAsyncLocked();
16074                    }
16075                }
16076            });
16077        }
16078
16079        if (DEBUG_OOM_ADJ) {
16080            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16081        }
16082    }
16083
16084    final void trimApplications() {
16085        synchronized (this) {
16086            int i;
16087
16088            // First remove any unused application processes whose package
16089            // has been removed.
16090            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16091                final ProcessRecord app = mRemovedProcesses.get(i);
16092                if (app.activities.size() == 0
16093                        && app.curReceiver == null && app.services.size() == 0) {
16094                    Slog.i(
16095                        TAG, "Exiting empty application process "
16096                        + app.processName + " ("
16097                        + (app.thread != null ? app.thread.asBinder() : null)
16098                        + ")\n");
16099                    if (app.pid > 0 && app.pid != MY_PID) {
16100                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16101                                app.processName, app.setAdj, "empty");
16102                        app.killedByAm = true;
16103                        Process.killProcessQuiet(app.pid);
16104                    } else {
16105                        try {
16106                            app.thread.scheduleExit();
16107                        } catch (Exception e) {
16108                            // Ignore exceptions.
16109                        }
16110                    }
16111                    cleanUpApplicationRecordLocked(app, false, true, -1);
16112                    mRemovedProcesses.remove(i);
16113
16114                    if (app.persistent) {
16115                        if (app.persistent) {
16116                            addAppLocked(app.info, false);
16117                        }
16118                    }
16119                }
16120            }
16121
16122            // Now update the oom adj for all processes.
16123            updateOomAdjLocked();
16124        }
16125    }
16126
16127    /** This method sends the specified signal to each of the persistent apps */
16128    public void signalPersistentProcesses(int sig) throws RemoteException {
16129        if (sig != Process.SIGNAL_USR1) {
16130            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16131        }
16132
16133        synchronized (this) {
16134            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16135                    != PackageManager.PERMISSION_GRANTED) {
16136                throw new SecurityException("Requires permission "
16137                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16138            }
16139
16140            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16141                ProcessRecord r = mLruProcesses.get(i);
16142                if (r.thread != null && r.persistent) {
16143                    Process.sendSignal(r.pid, sig);
16144                }
16145            }
16146        }
16147    }
16148
16149    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16150        if (proc == null || proc == mProfileProc) {
16151            proc = mProfileProc;
16152            path = mProfileFile;
16153            profileType = mProfileType;
16154            clearProfilerLocked();
16155        }
16156        if (proc == null) {
16157            return;
16158        }
16159        try {
16160            proc.thread.profilerControl(false, path, null, profileType);
16161        } catch (RemoteException e) {
16162            throw new IllegalStateException("Process disappeared");
16163        }
16164    }
16165
16166    private void clearProfilerLocked() {
16167        if (mProfileFd != null) {
16168            try {
16169                mProfileFd.close();
16170            } catch (IOException e) {
16171            }
16172        }
16173        mProfileApp = null;
16174        mProfileProc = null;
16175        mProfileFile = null;
16176        mProfileType = 0;
16177        mAutoStopProfiler = false;
16178    }
16179
16180    public boolean profileControl(String process, int userId, boolean start,
16181            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16182
16183        try {
16184            synchronized (this) {
16185                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16186                // its own permission.
16187                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16188                        != PackageManager.PERMISSION_GRANTED) {
16189                    throw new SecurityException("Requires permission "
16190                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16191                }
16192
16193                if (start && fd == null) {
16194                    throw new IllegalArgumentException("null fd");
16195                }
16196
16197                ProcessRecord proc = null;
16198                if (process != null) {
16199                    proc = findProcessLocked(process, userId, "profileControl");
16200                }
16201
16202                if (start && (proc == null || proc.thread == null)) {
16203                    throw new IllegalArgumentException("Unknown process: " + process);
16204                }
16205
16206                if (start) {
16207                    stopProfilerLocked(null, null, 0);
16208                    setProfileApp(proc.info, proc.processName, path, fd, false);
16209                    mProfileProc = proc;
16210                    mProfileType = profileType;
16211                    try {
16212                        fd = fd.dup();
16213                    } catch (IOException e) {
16214                        fd = null;
16215                    }
16216                    proc.thread.profilerControl(start, path, fd, profileType);
16217                    fd = null;
16218                    mProfileFd = null;
16219                } else {
16220                    stopProfilerLocked(proc, path, profileType);
16221                    if (fd != null) {
16222                        try {
16223                            fd.close();
16224                        } catch (IOException e) {
16225                        }
16226                    }
16227                }
16228
16229                return true;
16230            }
16231        } catch (RemoteException e) {
16232            throw new IllegalStateException("Process disappeared");
16233        } finally {
16234            if (fd != null) {
16235                try {
16236                    fd.close();
16237                } catch (IOException e) {
16238                }
16239            }
16240        }
16241    }
16242
16243    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16244        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16245                userId, true, true, callName, null);
16246        ProcessRecord proc = null;
16247        try {
16248            int pid = Integer.parseInt(process);
16249            synchronized (mPidsSelfLocked) {
16250                proc = mPidsSelfLocked.get(pid);
16251            }
16252        } catch (NumberFormatException e) {
16253        }
16254
16255        if (proc == null) {
16256            ArrayMap<String, SparseArray<ProcessRecord>> all
16257                    = mProcessNames.getMap();
16258            SparseArray<ProcessRecord> procs = all.get(process);
16259            if (procs != null && procs.size() > 0) {
16260                proc = procs.valueAt(0);
16261                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16262                    for (int i=1; i<procs.size(); i++) {
16263                        ProcessRecord thisProc = procs.valueAt(i);
16264                        if (thisProc.userId == userId) {
16265                            proc = thisProc;
16266                            break;
16267                        }
16268                    }
16269                }
16270            }
16271        }
16272
16273        return proc;
16274    }
16275
16276    public boolean dumpHeap(String process, int userId, boolean managed,
16277            String path, ParcelFileDescriptor fd) throws RemoteException {
16278
16279        try {
16280            synchronized (this) {
16281                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16282                // its own permission (same as profileControl).
16283                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16284                        != PackageManager.PERMISSION_GRANTED) {
16285                    throw new SecurityException("Requires permission "
16286                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16287                }
16288
16289                if (fd == null) {
16290                    throw new IllegalArgumentException("null fd");
16291                }
16292
16293                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16294                if (proc == null || proc.thread == null) {
16295                    throw new IllegalArgumentException("Unknown process: " + process);
16296                }
16297
16298                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16299                if (!isDebuggable) {
16300                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16301                        throw new SecurityException("Process not debuggable: " + proc);
16302                    }
16303                }
16304
16305                proc.thread.dumpHeap(managed, path, fd);
16306                fd = null;
16307                return true;
16308            }
16309        } catch (RemoteException e) {
16310            throw new IllegalStateException("Process disappeared");
16311        } finally {
16312            if (fd != null) {
16313                try {
16314                    fd.close();
16315                } catch (IOException e) {
16316                }
16317            }
16318        }
16319    }
16320
16321    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16322    public void monitor() {
16323        synchronized (this) { }
16324    }
16325
16326    void onCoreSettingsChange(Bundle settings) {
16327        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16328            ProcessRecord processRecord = mLruProcesses.get(i);
16329            try {
16330                if (processRecord.thread != null) {
16331                    processRecord.thread.setCoreSettings(settings);
16332                }
16333            } catch (RemoteException re) {
16334                /* ignore */
16335            }
16336        }
16337    }
16338
16339    // Multi-user methods
16340
16341    /**
16342     * Start user, if its not already running, but don't bring it to foreground.
16343     */
16344    @Override
16345    public boolean startUserInBackground(final int userId) {
16346        return startUser(userId, /* foreground */ false);
16347    }
16348
16349    /**
16350     * Refreshes the list of users related to the current user when either a
16351     * user switch happens or when a new related user is started in the
16352     * background.
16353     */
16354    private void updateCurrentProfileIdsLocked() {
16355        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId);
16356        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16357        for (int i = 0; i < currentProfileIds.length; i++) {
16358            currentProfileIds[i] = profiles.get(i).id;
16359        }
16360        mCurrentProfileIds = currentProfileIds;
16361    }
16362
16363    private Set getProfileIdsLocked(int userId) {
16364        Set userIds = new HashSet<Integer>();
16365        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(userId);
16366        for (UserInfo user : profiles) {
16367            userIds.add(Integer.valueOf(user.id));
16368        }
16369        return userIds;
16370    }
16371
16372    @Override
16373    public boolean switchUser(final int userId) {
16374        return startUser(userId, /* foregound */ true);
16375    }
16376
16377    private boolean startUser(final int userId, boolean foreground) {
16378        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16379                != PackageManager.PERMISSION_GRANTED) {
16380            String msg = "Permission Denial: switchUser() from pid="
16381                    + Binder.getCallingPid()
16382                    + ", uid=" + Binder.getCallingUid()
16383                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16384            Slog.w(TAG, msg);
16385            throw new SecurityException(msg);
16386        }
16387
16388        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16389
16390        final long ident = Binder.clearCallingIdentity();
16391        try {
16392            synchronized (this) {
16393                final int oldUserId = mCurrentUserId;
16394                if (oldUserId == userId) {
16395                    return true;
16396                }
16397
16398                mStackSupervisor.setLockTaskModeLocked(null);
16399
16400                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16401                if (userInfo == null) {
16402                    Slog.w(TAG, "No user info for user #" + userId);
16403                    return false;
16404                }
16405
16406                if (foreground) {
16407                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16408                            R.anim.screen_user_enter);
16409                }
16410
16411                boolean needStart = false;
16412
16413                // If the user we are switching to is not currently started, then
16414                // we need to start it now.
16415                if (mStartedUsers.get(userId) == null) {
16416                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16417                    updateStartedUserArrayLocked();
16418                    needStart = true;
16419                }
16420
16421                final Integer userIdInt = Integer.valueOf(userId);
16422                mUserLru.remove(userIdInt);
16423                mUserLru.add(userIdInt);
16424
16425                if (foreground) {
16426                    mCurrentUserId = userId;
16427                    updateCurrentProfileIdsLocked();
16428                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16429                    // Once the internal notion of the active user has switched, we lock the device
16430                    // with the option to show the user switcher on the keyguard.
16431                    mWindowManager.lockNow(null);
16432                } else {
16433                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16434                    updateCurrentProfileIdsLocked();
16435                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16436                    mUserLru.remove(currentUserIdInt);
16437                    mUserLru.add(currentUserIdInt);
16438                }
16439
16440                final UserStartedState uss = mStartedUsers.get(userId);
16441
16442                // Make sure user is in the started state.  If it is currently
16443                // stopping, we need to knock that off.
16444                if (uss.mState == UserStartedState.STATE_STOPPING) {
16445                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16446                    // so we can just fairly silently bring the user back from
16447                    // the almost-dead.
16448                    uss.mState = UserStartedState.STATE_RUNNING;
16449                    updateStartedUserArrayLocked();
16450                    needStart = true;
16451                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16452                    // This means ACTION_SHUTDOWN has been sent, so we will
16453                    // need to treat this as a new boot of the user.
16454                    uss.mState = UserStartedState.STATE_BOOTING;
16455                    updateStartedUserArrayLocked();
16456                    needStart = true;
16457                }
16458
16459                if (foreground) {
16460                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16461                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16462                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16463                            oldUserId, userId, uss));
16464                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16465                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16466                }
16467
16468                if (needStart) {
16469                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16470                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16471                            | Intent.FLAG_RECEIVER_FOREGROUND);
16472                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16473                    broadcastIntentLocked(null, null, intent,
16474                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16475                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16476                }
16477
16478                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16479                    if (userId != 0) {
16480                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16481                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16482                        broadcastIntentLocked(null, null, intent, null,
16483                                new IIntentReceiver.Stub() {
16484                                    public void performReceive(Intent intent, int resultCode,
16485                                            String data, Bundle extras, boolean ordered,
16486                                            boolean sticky, int sendingUser) {
16487                                        userInitialized(uss, userId);
16488                                    }
16489                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16490                                true, false, MY_PID, Process.SYSTEM_UID,
16491                                userId);
16492                        uss.initializing = true;
16493                    } else {
16494                        getUserManagerLocked().makeInitialized(userInfo.id);
16495                    }
16496                }
16497
16498                if (foreground) {
16499                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16500                    if (homeInFront) {
16501                        startHomeActivityLocked(userId);
16502                    } else {
16503                        mStackSupervisor.resumeTopActivitiesLocked();
16504                    }
16505                    EventLogTags.writeAmSwitchUser(userId);
16506                    getUserManagerLocked().userForeground(userId);
16507                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16508                }
16509
16510                if (needStart) {
16511                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16512                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16513                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16514                    broadcastIntentLocked(null, null, intent,
16515                            null, new IIntentReceiver.Stub() {
16516                                @Override
16517                                public void performReceive(Intent intent, int resultCode, String data,
16518                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16519                                        throws RemoteException {
16520                                }
16521                            }, 0, null, null,
16522                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16523                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16524                }
16525            }
16526        } finally {
16527            Binder.restoreCallingIdentity(ident);
16528        }
16529
16530        return true;
16531    }
16532
16533    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16534        long ident = Binder.clearCallingIdentity();
16535        try {
16536            Intent intent;
16537            if (oldUserId >= 0) {
16538                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16539                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16540                        | Intent.FLAG_RECEIVER_FOREGROUND);
16541                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16542                broadcastIntentLocked(null, null, intent,
16543                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16544                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16545            }
16546            if (newUserId >= 0) {
16547                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16548                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16549                        | Intent.FLAG_RECEIVER_FOREGROUND);
16550                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16551                broadcastIntentLocked(null, null, intent,
16552                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16553                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16554                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16555                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16556                        | Intent.FLAG_RECEIVER_FOREGROUND);
16557                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16558                broadcastIntentLocked(null, null, intent,
16559                        null, null, 0, null, null,
16560                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16561                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16562            }
16563        } finally {
16564            Binder.restoreCallingIdentity(ident);
16565        }
16566    }
16567
16568    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16569            final int newUserId) {
16570        final int N = mUserSwitchObservers.beginBroadcast();
16571        if (N > 0) {
16572            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16573                int mCount = 0;
16574                @Override
16575                public void sendResult(Bundle data) throws RemoteException {
16576                    synchronized (ActivityManagerService.this) {
16577                        if (mCurUserSwitchCallback == this) {
16578                            mCount++;
16579                            if (mCount == N) {
16580                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16581                            }
16582                        }
16583                    }
16584                }
16585            };
16586            synchronized (this) {
16587                uss.switching = true;
16588                mCurUserSwitchCallback = callback;
16589            }
16590            for (int i=0; i<N; i++) {
16591                try {
16592                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16593                            newUserId, callback);
16594                } catch (RemoteException e) {
16595                }
16596            }
16597        } else {
16598            synchronized (this) {
16599                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16600            }
16601        }
16602        mUserSwitchObservers.finishBroadcast();
16603    }
16604
16605    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16606        synchronized (this) {
16607            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16608            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16609        }
16610    }
16611
16612    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16613        mCurUserSwitchCallback = null;
16614        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16615        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16616                oldUserId, newUserId, uss));
16617    }
16618
16619    void userInitialized(UserStartedState uss, int newUserId) {
16620        completeSwitchAndInitalize(uss, newUserId, true, false);
16621    }
16622
16623    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16624        completeSwitchAndInitalize(uss, newUserId, false, true);
16625    }
16626
16627    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16628            boolean clearInitializing, boolean clearSwitching) {
16629        boolean unfrozen = false;
16630        synchronized (this) {
16631            if (clearInitializing) {
16632                uss.initializing = false;
16633                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16634            }
16635            if (clearSwitching) {
16636                uss.switching = false;
16637            }
16638            if (!uss.switching && !uss.initializing) {
16639                mWindowManager.stopFreezingScreen();
16640                unfrozen = true;
16641            }
16642        }
16643        if (unfrozen) {
16644            final int N = mUserSwitchObservers.beginBroadcast();
16645            for (int i=0; i<N; i++) {
16646                try {
16647                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16648                } catch (RemoteException e) {
16649                }
16650            }
16651            mUserSwitchObservers.finishBroadcast();
16652        }
16653    }
16654
16655    void scheduleStartProfilesLocked() {
16656        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16657            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16658                    DateUtils.SECOND_IN_MILLIS);
16659        }
16660    }
16661
16662    void startProfilesLocked() {
16663        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16664        List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId);
16665        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16666        for (UserInfo user : profiles) {
16667            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16668                    && user.id != mCurrentUserId) {
16669                toStart.add(user);
16670            }
16671        }
16672        final int n = toStart.size();
16673        int i = 0;
16674        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16675            startUserInBackground(toStart.get(i).id);
16676        }
16677        if (i < n) {
16678            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16679        }
16680    }
16681
16682    void finishUserSwitch(UserStartedState uss) {
16683        synchronized (this) {
16684            if (uss.mState == UserStartedState.STATE_BOOTING
16685                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16686                uss.mState = UserStartedState.STATE_RUNNING;
16687                final int userId = uss.mHandle.getIdentifier();
16688                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16689                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16690                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16691                broadcastIntentLocked(null, null, intent,
16692                        null, null, 0, null, null,
16693                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16694                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16695            }
16696
16697            startProfilesLocked();
16698
16699            int num = mUserLru.size();
16700            int i = 0;
16701            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16702                Integer oldUserId = mUserLru.get(i);
16703                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16704                if (oldUss == null) {
16705                    // Shouldn't happen, but be sane if it does.
16706                    mUserLru.remove(i);
16707                    num--;
16708                    continue;
16709                }
16710                if (oldUss.mState == UserStartedState.STATE_STOPPING
16711                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16712                    // This user is already stopping, doesn't count.
16713                    num--;
16714                    i++;
16715                    continue;
16716                }
16717                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16718                    // Owner and current can't be stopped, but count as running.
16719                    i++;
16720                    continue;
16721                }
16722                // This is a user to be stopped.
16723                stopUserLocked(oldUserId, null);
16724                num--;
16725                i++;
16726            }
16727        }
16728    }
16729
16730    @Override
16731    public int stopUser(final int userId, final IStopUserCallback callback) {
16732        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16733                != PackageManager.PERMISSION_GRANTED) {
16734            String msg = "Permission Denial: switchUser() from pid="
16735                    + Binder.getCallingPid()
16736                    + ", uid=" + Binder.getCallingUid()
16737                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16738            Slog.w(TAG, msg);
16739            throw new SecurityException(msg);
16740        }
16741        if (userId <= 0) {
16742            throw new IllegalArgumentException("Can't stop primary user " + userId);
16743        }
16744        synchronized (this) {
16745            return stopUserLocked(userId, callback);
16746        }
16747    }
16748
16749    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16750        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16751        if (mCurrentUserId == userId) {
16752            return ActivityManager.USER_OP_IS_CURRENT;
16753        }
16754
16755        final UserStartedState uss = mStartedUsers.get(userId);
16756        if (uss == null) {
16757            // User is not started, nothing to do...  but we do need to
16758            // callback if requested.
16759            if (callback != null) {
16760                mHandler.post(new Runnable() {
16761                    @Override
16762                    public void run() {
16763                        try {
16764                            callback.userStopped(userId);
16765                        } catch (RemoteException e) {
16766                        }
16767                    }
16768                });
16769            }
16770            return ActivityManager.USER_OP_SUCCESS;
16771        }
16772
16773        if (callback != null) {
16774            uss.mStopCallbacks.add(callback);
16775        }
16776
16777        if (uss.mState != UserStartedState.STATE_STOPPING
16778                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16779            uss.mState = UserStartedState.STATE_STOPPING;
16780            updateStartedUserArrayLocked();
16781
16782            long ident = Binder.clearCallingIdentity();
16783            try {
16784                // We are going to broadcast ACTION_USER_STOPPING and then
16785                // once that is done send a final ACTION_SHUTDOWN and then
16786                // stop the user.
16787                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16788                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16789                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16790                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16791                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16792                // This is the result receiver for the final shutdown broadcast.
16793                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16794                    @Override
16795                    public void performReceive(Intent intent, int resultCode, String data,
16796                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16797                        finishUserStop(uss);
16798                    }
16799                };
16800                // This is the result receiver for the initial stopping broadcast.
16801                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16802                    @Override
16803                    public void performReceive(Intent intent, int resultCode, String data,
16804                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16805                        // On to the next.
16806                        synchronized (ActivityManagerService.this) {
16807                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16808                                // Whoops, we are being started back up.  Abort, abort!
16809                                return;
16810                            }
16811                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16812                        }
16813                        broadcastIntentLocked(null, null, shutdownIntent,
16814                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16815                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16816                    }
16817                };
16818                // Kick things off.
16819                broadcastIntentLocked(null, null, stoppingIntent,
16820                        null, stoppingReceiver, 0, null, null,
16821                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16822                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16823            } finally {
16824                Binder.restoreCallingIdentity(ident);
16825            }
16826        }
16827
16828        return ActivityManager.USER_OP_SUCCESS;
16829    }
16830
16831    void finishUserStop(UserStartedState uss) {
16832        final int userId = uss.mHandle.getIdentifier();
16833        boolean stopped;
16834        ArrayList<IStopUserCallback> callbacks;
16835        synchronized (this) {
16836            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16837            if (mStartedUsers.get(userId) != uss) {
16838                stopped = false;
16839            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16840                stopped = false;
16841            } else {
16842                stopped = true;
16843                // User can no longer run.
16844                mStartedUsers.remove(userId);
16845                mUserLru.remove(Integer.valueOf(userId));
16846                updateStartedUserArrayLocked();
16847
16848                // Clean up all state and processes associated with the user.
16849                // Kill all the processes for the user.
16850                forceStopUserLocked(userId, "finish user");
16851            }
16852        }
16853
16854        for (int i=0; i<callbacks.size(); i++) {
16855            try {
16856                if (stopped) callbacks.get(i).userStopped(userId);
16857                else callbacks.get(i).userStopAborted(userId);
16858            } catch (RemoteException e) {
16859            }
16860        }
16861
16862        mStackSupervisor.removeUserLocked(userId);
16863    }
16864
16865    @Override
16866    public UserInfo getCurrentUser() {
16867        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16868                != PackageManager.PERMISSION_GRANTED) && (
16869                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16870                != PackageManager.PERMISSION_GRANTED)) {
16871            String msg = "Permission Denial: getCurrentUser() from pid="
16872                    + Binder.getCallingPid()
16873                    + ", uid=" + Binder.getCallingUid()
16874                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16875            Slog.w(TAG, msg);
16876            throw new SecurityException(msg);
16877        }
16878        synchronized (this) {
16879            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16880        }
16881    }
16882
16883    int getCurrentUserIdLocked() {
16884        return mCurrentUserId;
16885    }
16886
16887    @Override
16888    public boolean isUserRunning(int userId, boolean orStopped) {
16889        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16890                != PackageManager.PERMISSION_GRANTED) {
16891            String msg = "Permission Denial: isUserRunning() 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 isUserRunningLocked(userId, orStopped);
16900        }
16901    }
16902
16903    boolean isUserRunningLocked(int userId, boolean orStopped) {
16904        UserStartedState state = mStartedUsers.get(userId);
16905        if (state == null) {
16906            return false;
16907        }
16908        if (orStopped) {
16909            return true;
16910        }
16911        return state.mState != UserStartedState.STATE_STOPPING
16912                && state.mState != UserStartedState.STATE_SHUTDOWN;
16913    }
16914
16915    @Override
16916    public int[] getRunningUserIds() {
16917        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16918                != PackageManager.PERMISSION_GRANTED) {
16919            String msg = "Permission Denial: isUserRunning() from pid="
16920                    + Binder.getCallingPid()
16921                    + ", uid=" + Binder.getCallingUid()
16922                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16923            Slog.w(TAG, msg);
16924            throw new SecurityException(msg);
16925        }
16926        synchronized (this) {
16927            return mStartedUserArray;
16928        }
16929    }
16930
16931    private void updateStartedUserArrayLocked() {
16932        int num = 0;
16933        for (int i=0; i<mStartedUsers.size();  i++) {
16934            UserStartedState uss = mStartedUsers.valueAt(i);
16935            // This list does not include stopping users.
16936            if (uss.mState != UserStartedState.STATE_STOPPING
16937                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16938                num++;
16939            }
16940        }
16941        mStartedUserArray = new int[num];
16942        num = 0;
16943        for (int i=0; i<mStartedUsers.size();  i++) {
16944            UserStartedState uss = mStartedUsers.valueAt(i);
16945            if (uss.mState != UserStartedState.STATE_STOPPING
16946                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16947                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16948                num++;
16949            }
16950        }
16951    }
16952
16953    @Override
16954    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16955        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16956                != PackageManager.PERMISSION_GRANTED) {
16957            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16958                    + Binder.getCallingPid()
16959                    + ", uid=" + Binder.getCallingUid()
16960                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16961            Slog.w(TAG, msg);
16962            throw new SecurityException(msg);
16963        }
16964
16965        mUserSwitchObservers.register(observer);
16966    }
16967
16968    @Override
16969    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16970        mUserSwitchObservers.unregister(observer);
16971    }
16972
16973    private boolean userExists(int userId) {
16974        if (userId == 0) {
16975            return true;
16976        }
16977        UserManagerService ums = getUserManagerLocked();
16978        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16979    }
16980
16981    int[] getUsersLocked() {
16982        UserManagerService ums = getUserManagerLocked();
16983        return ums != null ? ums.getUserIds() : new int[] { 0 };
16984    }
16985
16986    UserManagerService getUserManagerLocked() {
16987        if (mUserManager == null) {
16988            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16989            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16990        }
16991        return mUserManager;
16992    }
16993
16994    private int applyUserId(int uid, int userId) {
16995        return UserHandle.getUid(userId, uid);
16996    }
16997
16998    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16999        if (info == null) return null;
17000        ApplicationInfo newInfo = new ApplicationInfo(info);
17001        newInfo.uid = applyUserId(info.uid, userId);
17002        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17003                + info.packageName;
17004        return newInfo;
17005    }
17006
17007    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17008        if (aInfo == null
17009                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17010            return aInfo;
17011        }
17012
17013        ActivityInfo info = new ActivityInfo(aInfo);
17014        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17015        return info;
17016    }
17017
17018    private final class LocalService extends ActivityManagerInternal {
17019        @Override
17020        public void goingToSleep() {
17021            ActivityManagerService.this.goingToSleep();
17022        }
17023
17024        @Override
17025        public void wakingUp() {
17026            ActivityManagerService.this.wakingUp();
17027        }
17028    }
17029}
17030