ActivityManagerService.java revision 846318a3250fa95f47a9decfbffb05a31dbd0006
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(
5983            Uri uri, int uid, final int modeFlags, int minStrength) {
5984        // Root gets to do everything.
5985        if (uid == 0) {
5986            return true;
5987        }
5988
5989        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5990        if (perms == null) return false;
5991
5992        // First look for exact match
5993        final UriPermission exactPerm = perms.get(new GrantUri(uri, false));
5994        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
5995            return true;
5996        }
5997
5998        // No exact match, look for prefixes
5999        final int N = perms.size();
6000        for (int i = 0; i < N; i++) {
6001            final UriPermission perm = perms.valueAt(i);
6002            if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri)
6003                    && perm.getStrength(modeFlags) >= minStrength) {
6004                return true;
6005            }
6006        }
6007
6008        return false;
6009    }
6010
6011    @Override
6012    public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) {
6013        enforceNotIsolatedCaller("checkUriPermission");
6014
6015        // Another redirected-binder-call permissions check as in
6016        // {@link checkComponentPermission}.
6017        Identity tlsIdentity = sCallerIdentity.get();
6018        if (tlsIdentity != null) {
6019            uid = tlsIdentity.uid;
6020            pid = tlsIdentity.pid;
6021        }
6022
6023        // Our own process gets to do everything.
6024        if (pid == MY_PID) {
6025            return PackageManager.PERMISSION_GRANTED;
6026        }
6027        synchronized(this) {
6028            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
6029                    ? PackageManager.PERMISSION_GRANTED
6030                    : PackageManager.PERMISSION_DENIED;
6031        }
6032    }
6033
6034    /**
6035     * Check if the targetPkg can be granted permission to access uri by
6036     * the callingUid using the given modeFlags.  Throws a security exception
6037     * if callingUid is not allowed to do this.  Returns the uid of the target
6038     * if the URI permission grant should be performed; returns -1 if it is not
6039     * needed (for example targetPkg already has permission to access the URI).
6040     * If you already know the uid of the target, you can supply it in
6041     * lastTargetUid else set that to -1.
6042     */
6043    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
6044            Uri uri, final int modeFlags, int lastTargetUid) {
6045        if (!Intent.isAccessUriMode(modeFlags)) {
6046            return -1;
6047        }
6048
6049        if (targetPkg != null) {
6050            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6051                    "Checking grant " + targetPkg + " permission to " + uri);
6052        }
6053
6054        final IPackageManager pm = AppGlobals.getPackageManager();
6055
6056        // If this is not a content: uri, we can't do anything with it.
6057        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6058            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6059                    "Can't grant URI permission for non-content URI: " + uri);
6060            return -1;
6061        }
6062
6063        final String authority = uri.getAuthority();
6064        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6065        if (pi == null) {
6066            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6067            return -1;
6068        }
6069
6070        int targetUid = lastTargetUid;
6071        if (targetUid < 0 && targetPkg != null) {
6072            try {
6073                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6074                if (targetUid < 0) {
6075                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6076                            "Can't grant URI permission no uid for: " + targetPkg);
6077                    return -1;
6078                }
6079            } catch (RemoteException ex) {
6080                return -1;
6081            }
6082        }
6083
6084        if (targetUid >= 0) {
6085            // First...  does the target actually need this permission?
6086            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6087                // No need to grant the target this permission.
6088                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6089                        "Target " + targetPkg + " already has full permission to " + uri);
6090                return -1;
6091            }
6092        } else {
6093            // First...  there is no target package, so can anyone access it?
6094            boolean allowed = pi.exported;
6095            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6096                if (pi.readPermission != null) {
6097                    allowed = false;
6098                }
6099            }
6100            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6101                if (pi.writePermission != null) {
6102                    allowed = false;
6103                }
6104            }
6105            if (allowed) {
6106                return -1;
6107            }
6108        }
6109
6110        // Second...  is the provider allowing granting of URI permissions?
6111        if (!pi.grantUriPermissions) {
6112            throw new SecurityException("Provider " + pi.packageName
6113                    + "/" + pi.name
6114                    + " does not allow granting of Uri permissions (uri "
6115                    + uri + ")");
6116        }
6117        if (pi.uriPermissionPatterns != null) {
6118            final int N = pi.uriPermissionPatterns.length;
6119            boolean allowed = false;
6120            for (int i=0; i<N; i++) {
6121                if (pi.uriPermissionPatterns[i] != null
6122                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6123                    allowed = true;
6124                    break;
6125                }
6126            }
6127            if (!allowed) {
6128                throw new SecurityException("Provider " + pi.packageName
6129                        + "/" + pi.name
6130                        + " does not allow granting of permission to path of Uri "
6131                        + uri);
6132            }
6133        }
6134
6135        // Third...  does the caller itself have permission to access
6136        // this uri?
6137        if (callingUid != Process.myUid()) {
6138            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6139                // Require they hold a strong enough Uri permission
6140                final boolean persistable =
6141                        (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6142                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6143                        : UriPermission.STRENGTH_OWNED;
6144                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6145                    throw new SecurityException("Uid " + callingUid
6146                            + " does not have permission to uri " + uri);
6147                }
6148            }
6149        }
6150
6151        return targetUid;
6152    }
6153
6154    @Override
6155    public int checkGrantUriPermission(int callingUid, String targetPkg,
6156            Uri uri, final int modeFlags) {
6157        enforceNotIsolatedCaller("checkGrantUriPermission");
6158        synchronized(this) {
6159            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6160        }
6161    }
6162
6163    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri,
6164            final int modeFlags, UriPermissionOwner owner) {
6165        if (!Intent.isAccessUriMode(modeFlags)) {
6166            return;
6167        }
6168
6169        // So here we are: the caller has the assumed permission
6170        // to the uri, and the target doesn't.  Let's now give this to
6171        // the target.
6172
6173        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6174                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6175
6176        final String authority = uri.getAuthority();
6177        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6178        if (pi == null) {
6179            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6180            return;
6181        }
6182
6183        final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
6184        final UriPermission perm = findOrCreateUriPermissionLocked(
6185                pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix));
6186        perm.grantModes(modeFlags, owner);
6187    }
6188
6189    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6190            final int modeFlags, UriPermissionOwner owner) {
6191        if (targetPkg == null) {
6192            throw new NullPointerException("targetPkg");
6193        }
6194
6195        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6196        if (targetUid < 0) {
6197            return;
6198        }
6199
6200        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6201    }
6202
6203    static class NeededUriGrants extends ArrayList<Uri> {
6204        final String targetPkg;
6205        final int targetUid;
6206        final int flags;
6207
6208        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6209            this.targetPkg = targetPkg;
6210            this.targetUid = targetUid;
6211            this.flags = flags;
6212        }
6213    }
6214
6215    /**
6216     * Like checkGrantUriPermissionLocked, but takes an Intent.
6217     */
6218    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6219            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6220        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6221                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6222                + " clip=" + (intent != null ? intent.getClipData() : null)
6223                + " from " + intent + "; flags=0x"
6224                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6225
6226        if (targetPkg == null) {
6227            throw new NullPointerException("targetPkg");
6228        }
6229
6230        if (intent == null) {
6231            return null;
6232        }
6233        Uri data = intent.getData();
6234        ClipData clip = intent.getClipData();
6235        if (data == null && clip == null) {
6236            return null;
6237        }
6238
6239        if (data != null) {
6240            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6241                mode, needed != null ? needed.targetUid : -1);
6242            if (targetUid > 0) {
6243                if (needed == null) {
6244                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6245                }
6246                needed.add(data);
6247            }
6248        }
6249        if (clip != null) {
6250            for (int i=0; i<clip.getItemCount(); i++) {
6251                Uri uri = clip.getItemAt(i).getUri();
6252                if (uri != null) {
6253                    int targetUid = -1;
6254                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6255                            mode, needed != null ? needed.targetUid : -1);
6256                    if (targetUid > 0) {
6257                        if (needed == null) {
6258                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6259                        }
6260                        needed.add(uri);
6261                    }
6262                } else {
6263                    Intent clipIntent = clip.getItemAt(i).getIntent();
6264                    if (clipIntent != null) {
6265                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6266                                callingUid, targetPkg, clipIntent, mode, needed);
6267                        if (newNeeded != null) {
6268                            needed = newNeeded;
6269                        }
6270                    }
6271                }
6272            }
6273        }
6274
6275        return needed;
6276    }
6277
6278    /**
6279     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6280     */
6281    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6282            UriPermissionOwner owner) {
6283        if (needed != null) {
6284            for (int i=0; i<needed.size(); i++) {
6285                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6286                        needed.get(i), needed.flags, owner);
6287            }
6288        }
6289    }
6290
6291    void grantUriPermissionFromIntentLocked(int callingUid,
6292            String targetPkg, Intent intent, UriPermissionOwner owner) {
6293        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6294                intent, intent != null ? intent.getFlags() : 0, null);
6295        if (needed == null) {
6296            return;
6297        }
6298
6299        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6300    }
6301
6302    @Override
6303    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6304            Uri uri, final int modeFlags) {
6305        enforceNotIsolatedCaller("grantUriPermission");
6306        synchronized(this) {
6307            final ProcessRecord r = getRecordForAppLocked(caller);
6308            if (r == null) {
6309                throw new SecurityException("Unable to find app for caller "
6310                        + caller
6311                        + " when granting permission to uri " + uri);
6312            }
6313            if (targetPkg == null) {
6314                throw new IllegalArgumentException("null target");
6315            }
6316            if (uri == null) {
6317                throw new IllegalArgumentException("null uri");
6318            }
6319
6320            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6321                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6322                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6323                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6324
6325            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null);
6326        }
6327    }
6328
6329    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6330        if (perm.modeFlags == 0) {
6331            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6332                    perm.targetUid);
6333            if (perms != null) {
6334                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6335                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6336
6337                perms.remove(perm.uri);
6338                if (perms.isEmpty()) {
6339                    mGrantedUriPermissions.remove(perm.targetUid);
6340                }
6341            }
6342        }
6343    }
6344
6345    private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) {
6346        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6347
6348        final IPackageManager pm = AppGlobals.getPackageManager();
6349        final String authority = uri.getAuthority();
6350        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6351        if (pi == null) {
6352            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6353            return;
6354        }
6355
6356        // Does the caller have this permission on the URI?
6357        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6358            // Right now, if you are not the original owner of the permission,
6359            // you are not allowed to revoke it.
6360            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6361                throw new SecurityException("Uid " + callingUid
6362                        + " does not have permission to uri " + uri);
6363            //}
6364        }
6365
6366        boolean persistChanged = false;
6367
6368        // Go through all of the permissions and remove any that match.
6369        int N = mGrantedUriPermissions.size();
6370        for (int i = 0; i < N; i++) {
6371            final int targetUid = mGrantedUriPermissions.keyAt(i);
6372            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6373
6374            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6375                final UriPermission perm = it.next();
6376                if (perm.uri.uri.isPathPrefixMatch(uri)) {
6377                    if (DEBUG_URI_PERMISSION)
6378                        Slog.v(TAG,
6379                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6380                    persistChanged |= perm.revokeModes(
6381                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6382                    if (perm.modeFlags == 0) {
6383                        it.remove();
6384                    }
6385                }
6386            }
6387
6388            if (perms.isEmpty()) {
6389                mGrantedUriPermissions.remove(targetUid);
6390                N--;
6391                i--;
6392            }
6393        }
6394
6395        if (persistChanged) {
6396            schedulePersistUriGrants();
6397        }
6398    }
6399
6400    @Override
6401    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6402            final int modeFlags) {
6403        enforceNotIsolatedCaller("revokeUriPermission");
6404        synchronized(this) {
6405            final ProcessRecord r = getRecordForAppLocked(caller);
6406            if (r == null) {
6407                throw new SecurityException("Unable to find app for caller "
6408                        + caller
6409                        + " when revoking permission to uri " + uri);
6410            }
6411            if (uri == null) {
6412                Slog.w(TAG, "revokeUriPermission: null uri");
6413                return;
6414            }
6415
6416            if (!Intent.isAccessUriMode(modeFlags)) {
6417                return;
6418            }
6419
6420            final IPackageManager pm = AppGlobals.getPackageManager();
6421            final String authority = uri.getAuthority();
6422            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6423            if (pi == null) {
6424                Slog.w(TAG, "No content provider found for permission revoke: "
6425                        + uri.toSafeString());
6426                return;
6427            }
6428
6429            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6430        }
6431    }
6432
6433    /**
6434     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6435     * given package.
6436     *
6437     * @param packageName Package name to match, or {@code null} to apply to all
6438     *            packages.
6439     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6440     *            to all users.
6441     * @param persistable If persistable grants should be removed.
6442     */
6443    private void removeUriPermissionsForPackageLocked(
6444            String packageName, int userHandle, boolean persistable) {
6445        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6446            throw new IllegalArgumentException("Must narrow by either package or user");
6447        }
6448
6449        boolean persistChanged = false;
6450
6451        int N = mGrantedUriPermissions.size();
6452        for (int i = 0; i < N; i++) {
6453            final int targetUid = mGrantedUriPermissions.keyAt(i);
6454            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6455
6456            // Only inspect grants matching user
6457            if (userHandle == UserHandle.USER_ALL
6458                    || userHandle == UserHandle.getUserId(targetUid)) {
6459                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6460                    final UriPermission perm = it.next();
6461
6462                    // Only inspect grants matching package
6463                    if (packageName == null || perm.sourcePkg.equals(packageName)
6464                            || perm.targetPkg.equals(packageName)) {
6465                        persistChanged |= perm.revokeModes(
6466                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6467
6468                        // Only remove when no modes remain; any persisted grants
6469                        // will keep this alive.
6470                        if (perm.modeFlags == 0) {
6471                            it.remove();
6472                        }
6473                    }
6474                }
6475
6476                if (perms.isEmpty()) {
6477                    mGrantedUriPermissions.remove(targetUid);
6478                    N--;
6479                    i--;
6480                }
6481            }
6482        }
6483
6484        if (persistChanged) {
6485            schedulePersistUriGrants();
6486        }
6487    }
6488
6489    @Override
6490    public IBinder newUriPermissionOwner(String name) {
6491        enforceNotIsolatedCaller("newUriPermissionOwner");
6492        synchronized(this) {
6493            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6494            return owner.getExternalTokenLocked();
6495        }
6496    }
6497
6498    @Override
6499    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6500            Uri uri, final int modeFlags) {
6501        synchronized(this) {
6502            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6503            if (owner == null) {
6504                throw new IllegalArgumentException("Unknown owner: " + token);
6505            }
6506            if (fromUid != Binder.getCallingUid()) {
6507                if (Binder.getCallingUid() != Process.myUid()) {
6508                    // Only system code can grant URI permissions on behalf
6509                    // of other users.
6510                    throw new SecurityException("nice try");
6511                }
6512            }
6513            if (targetPkg == null) {
6514                throw new IllegalArgumentException("null target");
6515            }
6516            if (uri == null) {
6517                throw new IllegalArgumentException("null uri");
6518            }
6519
6520            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6521        }
6522    }
6523
6524    @Override
6525    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6526        synchronized(this) {
6527            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6528            if (owner == null) {
6529                throw new IllegalArgumentException("Unknown owner: " + token);
6530            }
6531
6532            if (uri == null) {
6533                owner.removeUriPermissionsLocked(mode);
6534            } else {
6535                owner.removeUriPermissionLocked(uri, mode);
6536            }
6537        }
6538    }
6539
6540    private void schedulePersistUriGrants() {
6541        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6542            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6543                    10 * DateUtils.SECOND_IN_MILLIS);
6544        }
6545    }
6546
6547    private void writeGrantedUriPermissions() {
6548        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6549
6550        // Snapshot permissions so we can persist without lock
6551        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6552        synchronized (this) {
6553            final int size = mGrantedUriPermissions.size();
6554            for (int i = 0; i < size; i++) {
6555                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6556                for (UriPermission perm : perms.values()) {
6557                    if (perm.persistedModeFlags != 0) {
6558                        persist.add(perm.snapshot());
6559                    }
6560                }
6561            }
6562        }
6563
6564        FileOutputStream fos = null;
6565        try {
6566            fos = mGrantFile.startWrite();
6567
6568            XmlSerializer out = new FastXmlSerializer();
6569            out.setOutput(fos, "utf-8");
6570            out.startDocument(null, true);
6571            out.startTag(null, TAG_URI_GRANTS);
6572            for (UriPermission.Snapshot perm : persist) {
6573                out.startTag(null, TAG_URI_GRANT);
6574                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6575                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6576                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6577                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6578                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6579                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6580                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6581                out.endTag(null, TAG_URI_GRANT);
6582            }
6583            out.endTag(null, TAG_URI_GRANTS);
6584            out.endDocument();
6585
6586            mGrantFile.finishWrite(fos);
6587        } catch (IOException e) {
6588            if (fos != null) {
6589                mGrantFile.failWrite(fos);
6590            }
6591        }
6592    }
6593
6594    private void readGrantedUriPermissionsLocked() {
6595        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6596
6597        final long now = System.currentTimeMillis();
6598
6599        FileInputStream fis = null;
6600        try {
6601            fis = mGrantFile.openRead();
6602            final XmlPullParser in = Xml.newPullParser();
6603            in.setInput(fis, null);
6604
6605            int type;
6606            while ((type = in.next()) != END_DOCUMENT) {
6607                final String tag = in.getName();
6608                if (type == START_TAG) {
6609                    if (TAG_URI_GRANT.equals(tag)) {
6610                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6611                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6612                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6613                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6614                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6615                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6616                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6617
6618                        // Sanity check that provider still belongs to source package
6619                        final ProviderInfo pi = getProviderInfoLocked(
6620                                uri.getAuthority(), userHandle);
6621                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6622                            int targetUid = -1;
6623                            try {
6624                                targetUid = AppGlobals.getPackageManager()
6625                                        .getPackageUid(targetPkg, userHandle);
6626                            } catch (RemoteException e) {
6627                            }
6628                            if (targetUid != -1) {
6629                                final UriPermission perm = findOrCreateUriPermissionLocked(
6630                                        sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix));
6631                                perm.initPersistedModes(modeFlags, createdTime);
6632                            }
6633                        } else {
6634                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6635                                    + " but instead found " + pi);
6636                        }
6637                    }
6638                }
6639            }
6640        } catch (FileNotFoundException e) {
6641            // Missing grants is okay
6642        } catch (IOException e) {
6643            Log.wtf(TAG, "Failed reading Uri grants", e);
6644        } catch (XmlPullParserException e) {
6645            Log.wtf(TAG, "Failed reading Uri grants", e);
6646        } finally {
6647            IoUtils.closeQuietly(fis);
6648        }
6649    }
6650
6651    @Override
6652    public void takePersistableUriPermission(Uri uri, final int modeFlags) {
6653        enforceNotIsolatedCaller("takePersistableUriPermission");
6654
6655        Preconditions.checkFlagsArgument(modeFlags,
6656                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6657
6658        synchronized (this) {
6659            final int callingUid = Binder.getCallingUid();
6660            boolean persistChanged = false;
6661
6662            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6663            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6664
6665            final boolean exactValid = (exactPerm != null)
6666                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6667            final boolean prefixValid = (prefixPerm != null)
6668                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6669
6670            if (!(exactValid || prefixValid)) {
6671                throw new SecurityException("No persistable permission grants found for UID "
6672                        + callingUid + " and Uri " + uri.toSafeString());
6673            }
6674
6675            if (exactValid) {
6676                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6677            }
6678            if (prefixValid) {
6679                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6680            }
6681
6682            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6683
6684            if (persistChanged) {
6685                schedulePersistUriGrants();
6686            }
6687        }
6688    }
6689
6690    @Override
6691    public void releasePersistableUriPermission(Uri uri, final int modeFlags) {
6692        enforceNotIsolatedCaller("releasePersistableUriPermission");
6693
6694        Preconditions.checkFlagsArgument(modeFlags,
6695                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6696
6697        synchronized (this) {
6698            final int callingUid = Binder.getCallingUid();
6699            boolean persistChanged = false;
6700
6701            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6702            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6703            if (exactPerm == null && prefixPerm == null) {
6704                throw new SecurityException("No permission grants found for UID " + callingUid
6705                        + " and Uri " + uri.toSafeString());
6706            }
6707
6708            if (exactPerm != null) {
6709                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6710                removeUriPermissionIfNeededLocked(exactPerm);
6711            }
6712            if (prefixPerm != null) {
6713                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6714                removeUriPermissionIfNeededLocked(prefixPerm);
6715            }
6716
6717            if (persistChanged) {
6718                schedulePersistUriGrants();
6719            }
6720        }
6721    }
6722
6723    /**
6724     * Prune any older {@link UriPermission} for the given UID until outstanding
6725     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6726     *
6727     * @return if any mutations occured that require persisting.
6728     */
6729    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6730        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6731        if (perms == null) return false;
6732        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6733
6734        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6735        for (UriPermission perm : perms.values()) {
6736            if (perm.persistedModeFlags != 0) {
6737                persisted.add(perm);
6738            }
6739        }
6740
6741        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6742        if (trimCount <= 0) return false;
6743
6744        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6745        for (int i = 0; i < trimCount; i++) {
6746            final UriPermission perm = persisted.get(i);
6747
6748            if (DEBUG_URI_PERMISSION) {
6749                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6750            }
6751
6752            perm.releasePersistableModes(~0);
6753            removeUriPermissionIfNeededLocked(perm);
6754        }
6755
6756        return true;
6757    }
6758
6759    @Override
6760    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6761            String packageName, boolean incoming) {
6762        enforceNotIsolatedCaller("getPersistedUriPermissions");
6763        Preconditions.checkNotNull(packageName, "packageName");
6764
6765        final int callingUid = Binder.getCallingUid();
6766        final IPackageManager pm = AppGlobals.getPackageManager();
6767        try {
6768            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6769            if (packageUid != callingUid) {
6770                throw new SecurityException(
6771                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6772            }
6773        } catch (RemoteException e) {
6774            throw new SecurityException("Failed to verify package name ownership");
6775        }
6776
6777        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6778        synchronized (this) {
6779            if (incoming) {
6780                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6781                        callingUid);
6782                if (perms == null) {
6783                    Slog.w(TAG, "No permission grants found for " + packageName);
6784                } else {
6785                    for (UriPermission perm : perms.values()) {
6786                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6787                            result.add(perm.buildPersistedPublicApiObject());
6788                        }
6789                    }
6790                }
6791            } else {
6792                final int size = mGrantedUriPermissions.size();
6793                for (int i = 0; i < size; i++) {
6794                    final ArrayMap<GrantUri, UriPermission> perms =
6795                            mGrantedUriPermissions.valueAt(i);
6796                    for (UriPermission perm : perms.values()) {
6797                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6798                            result.add(perm.buildPersistedPublicApiObject());
6799                        }
6800                    }
6801                }
6802            }
6803        }
6804        return new ParceledListSlice<android.content.UriPermission>(result);
6805    }
6806
6807    @Override
6808    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6809        synchronized (this) {
6810            ProcessRecord app =
6811                who != null ? getRecordForAppLocked(who) : null;
6812            if (app == null) return;
6813
6814            Message msg = Message.obtain();
6815            msg.what = WAIT_FOR_DEBUGGER_MSG;
6816            msg.obj = app;
6817            msg.arg1 = waiting ? 1 : 0;
6818            mHandler.sendMessage(msg);
6819        }
6820    }
6821
6822    @Override
6823    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6824        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6825        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6826        outInfo.availMem = Process.getFreeMemory();
6827        outInfo.totalMem = Process.getTotalMemory();
6828        outInfo.threshold = homeAppMem;
6829        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6830        outInfo.hiddenAppThreshold = cachedAppMem;
6831        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6832                ProcessList.SERVICE_ADJ);
6833        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6834                ProcessList.VISIBLE_APP_ADJ);
6835        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6836                ProcessList.FOREGROUND_APP_ADJ);
6837    }
6838
6839    // =========================================================
6840    // TASK MANAGEMENT
6841    // =========================================================
6842
6843    @Override
6844    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6845                         IThumbnailReceiver receiver) {
6846        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6847
6848        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6849        ActivityRecord topRecord = null;
6850
6851        synchronized(this) {
6852            if (localLOGV) Slog.v(
6853                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6854                + ", receiver=" + receiver);
6855
6856            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6857                    != PackageManager.PERMISSION_GRANTED) {
6858                if (receiver != null) {
6859                    // If the caller wants to wait for pending thumbnails,
6860                    // it ain't gonna get them.
6861                    try {
6862                        receiver.finished();
6863                    } catch (RemoteException ex) {
6864                    }
6865                }
6866                String msg = "Permission Denial: getTasks() from pid="
6867                        + Binder.getCallingPid()
6868                        + ", uid=" + Binder.getCallingUid()
6869                        + " requires " + android.Manifest.permission.GET_TASKS;
6870                Slog.w(TAG, msg);
6871                throw new SecurityException(msg);
6872            }
6873
6874            // TODO: Improve with MRU list from all ActivityStacks.
6875            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6876
6877            if (!pending.pendingRecords.isEmpty()) {
6878                mPendingThumbnails.add(pending);
6879            }
6880        }
6881
6882        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6883
6884        if (topRecord != null) {
6885            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6886            try {
6887                IApplicationThread topThumbnail = topRecord.app.thread;
6888                topThumbnail.requestThumbnail(topRecord.appToken);
6889            } catch (Exception e) {
6890                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6891                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6892            }
6893        }
6894
6895        if (pending.pendingRecords.isEmpty() && receiver != null) {
6896            // In this case all thumbnails were available and the client
6897            // is being asked to be told when the remaining ones come in...
6898            // which is unusually, since the top-most currently running
6899            // activity should never have a canned thumbnail!  Oh well.
6900            try {
6901                receiver.finished();
6902            } catch (RemoteException ex) {
6903            }
6904        }
6905
6906        return list;
6907    }
6908
6909    TaskRecord getMostRecentTask() {
6910        return mRecentTasks.get(0);
6911    }
6912
6913    @Override
6914    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6915            int flags, int userId) {
6916        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6917                false, true, "getRecentTasks", null);
6918
6919        synchronized (this) {
6920            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6921                    "getRecentTasks()");
6922            final boolean detailed = checkCallingPermission(
6923                    android.Manifest.permission.GET_DETAILED_TASKS)
6924                    == PackageManager.PERMISSION_GRANTED;
6925
6926            IPackageManager pm = AppGlobals.getPackageManager();
6927
6928            final int N = mRecentTasks.size();
6929            ArrayList<ActivityManager.RecentTaskInfo> res
6930                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6931                            maxNum < N ? maxNum : N);
6932
6933            final Set<Integer> includedUsers;
6934            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
6935                includedUsers = getProfileIdsLocked(userId);
6936            } else {
6937                includedUsers = new HashSet<Integer>();
6938            }
6939            includedUsers.add(Integer.valueOf(userId));
6940            for (int i=0; i<N && maxNum > 0; i++) {
6941                TaskRecord tr = mRecentTasks.get(i);
6942                // Only add calling user or related users recent tasks
6943                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
6944
6945                // Return the entry if desired by the caller.  We always return
6946                // the first entry, because callers always expect this to be the
6947                // foreground app.  We may filter others if the caller has
6948                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6949                // we should exclude the entry.
6950
6951                if (i == 0
6952                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6953                        || (tr.intent == null)
6954                        || ((tr.intent.getFlags()
6955                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6956                    ActivityManager.RecentTaskInfo rti
6957                            = new ActivityManager.RecentTaskInfo();
6958                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6959                    rti.persistentId = tr.taskId;
6960                    rti.baseIntent = new Intent(
6961                            tr.intent != null ? tr.intent : tr.affinityIntent);
6962                    if (!detailed) {
6963                        rti.baseIntent.replaceExtras((Bundle)null);
6964                    }
6965                    rti.origActivity = tr.origActivity;
6966                    rti.description = tr.lastDescription;
6967                    rti.stackId = tr.stack.mStackId;
6968                    rti.userId = tr.userId;
6969
6970                    // Traverse upwards looking for any break between main task activities and
6971                    // utility activities.
6972                    final ArrayList<ActivityRecord> activities = tr.mActivities;
6973                    int activityNdx;
6974                    final int numActivities = activities.size();
6975                    for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
6976                            ++activityNdx) {
6977                        final ActivityRecord r = activities.get(activityNdx);
6978                        if (r.intent != null &&
6979                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
6980                                        != 0) {
6981                            break;
6982                        }
6983                    }
6984                    // Traverse downwards starting below break looking for set label and icon.
6985                    for (--activityNdx; activityNdx >= 0; --activityNdx) {
6986                        final ActivityRecord r = activities.get(activityNdx);
6987                        if (r.activityLabel != null || r.activityIcon != null) {
6988                            rti.activityLabel = r.activityLabel;
6989                            rti.activityIcon = r.activityIcon;
6990                            break;
6991                        }
6992                    }
6993
6994                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6995                        // Check whether this activity is currently available.
6996                        try {
6997                            if (rti.origActivity != null) {
6998                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6999                                        == null) {
7000                                    continue;
7001                                }
7002                            } else if (rti.baseIntent != null) {
7003                                if (pm.queryIntentActivities(rti.baseIntent,
7004                                        null, 0, userId) == null) {
7005                                    continue;
7006                                }
7007                            }
7008                        } catch (RemoteException e) {
7009                            // Will never happen.
7010                        }
7011                    }
7012
7013                    res.add(rti);
7014                    maxNum--;
7015                }
7016            }
7017            return res;
7018        }
7019    }
7020
7021    private TaskRecord recentTaskForIdLocked(int id) {
7022        final int N = mRecentTasks.size();
7023            for (int i=0; i<N; i++) {
7024                TaskRecord tr = mRecentTasks.get(i);
7025                if (tr.taskId == id) {
7026                    return tr;
7027                }
7028            }
7029            return null;
7030    }
7031
7032    @Override
7033    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7034        synchronized (this) {
7035            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7036                    "getTaskThumbnails()");
7037            TaskRecord tr = recentTaskForIdLocked(id);
7038            if (tr != null) {
7039                return tr.getTaskThumbnailsLocked();
7040            }
7041        }
7042        return null;
7043    }
7044
7045    @Override
7046    public Bitmap getTaskTopThumbnail(int id) {
7047        synchronized (this) {
7048            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7049                    "getTaskTopThumbnail()");
7050            TaskRecord tr = recentTaskForIdLocked(id);
7051            if (tr != null) {
7052                return tr.getTaskTopThumbnailLocked();
7053            }
7054        }
7055        return null;
7056    }
7057
7058    @Override
7059    public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel,
7060            Bitmap activityIcon) {
7061        synchronized (this) {
7062            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7063            if (r != null) {
7064                r.activityLabel = activityLabel.toString();
7065                r.activityIcon = activityIcon;
7066            }
7067        }
7068    }
7069
7070    @Override
7071    public boolean removeSubTask(int taskId, int subTaskIndex) {
7072        synchronized (this) {
7073            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7074                    "removeSubTask()");
7075            long ident = Binder.clearCallingIdentity();
7076            try {
7077                TaskRecord tr = recentTaskForIdLocked(taskId);
7078                if (tr != null) {
7079                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7080                }
7081                return false;
7082            } finally {
7083                Binder.restoreCallingIdentity(ident);
7084            }
7085        }
7086    }
7087
7088    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7089        if (!pr.killedByAm) {
7090            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7091            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7092                    pr.processName, pr.setAdj, reason);
7093            pr.killedByAm = true;
7094            Process.killProcessQuiet(pr.pid);
7095        }
7096    }
7097
7098    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7099        tr.disposeThumbnail();
7100        mRecentTasks.remove(tr);
7101        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7102        Intent baseIntent = new Intent(
7103                tr.intent != null ? tr.intent : tr.affinityIntent);
7104        ComponentName component = baseIntent.getComponent();
7105        if (component == null) {
7106            Slog.w(TAG, "Now component for base intent of task: " + tr);
7107            return;
7108        }
7109
7110        // Find any running services associated with this app.
7111        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7112
7113        if (killProcesses) {
7114            // Find any running processes associated with this app.
7115            final String pkg = component.getPackageName();
7116            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7117            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7118            for (int i=0; i<pmap.size(); i++) {
7119                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7120                for (int j=0; j<uids.size(); j++) {
7121                    ProcessRecord proc = uids.valueAt(j);
7122                    if (proc.userId != tr.userId) {
7123                        continue;
7124                    }
7125                    if (!proc.pkgList.containsKey(pkg)) {
7126                        continue;
7127                    }
7128                    procs.add(proc);
7129                }
7130            }
7131
7132            // Kill the running processes.
7133            for (int i=0; i<procs.size(); i++) {
7134                ProcessRecord pr = procs.get(i);
7135                if (pr == mHomeProcess) {
7136                    // Don't kill the home process along with tasks from the same package.
7137                    continue;
7138                }
7139                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7140                    killUnneededProcessLocked(pr, "remove task");
7141                } else {
7142                    pr.waitingToKill = "remove task";
7143                }
7144            }
7145        }
7146    }
7147
7148    @Override
7149    public boolean removeTask(int taskId, int flags) {
7150        synchronized (this) {
7151            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7152                    "removeTask()");
7153            long ident = Binder.clearCallingIdentity();
7154            try {
7155                TaskRecord tr = recentTaskForIdLocked(taskId);
7156                if (tr != null) {
7157                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
7158                    if (r != null) {
7159                        cleanUpRemovedTaskLocked(tr, flags);
7160                        return true;
7161                    }
7162                    if (tr.mActivities.size() == 0) {
7163                        // Caller is just removing a recent task that is
7164                        // not actively running.  That is easy!
7165                        cleanUpRemovedTaskLocked(tr, flags);
7166                        return true;
7167                    }
7168                    Slog.w(TAG, "removeTask: task " + taskId
7169                            + " does not have activities to remove, "
7170                            + " but numActivities=" + tr.numActivities
7171                            + ": " + tr);
7172                }
7173            } finally {
7174                Binder.restoreCallingIdentity(ident);
7175            }
7176        }
7177        return false;
7178    }
7179
7180    /**
7181     * TODO: Add mController hook
7182     */
7183    @Override
7184    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7185        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7186                "moveTaskToFront()");
7187
7188        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7189        synchronized(this) {
7190            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7191                    Binder.getCallingUid(), "Task to front")) {
7192                ActivityOptions.abort(options);
7193                return;
7194            }
7195            final long origId = Binder.clearCallingIdentity();
7196            try {
7197                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7198                if (task == null) {
7199                    return;
7200                }
7201                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7202                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7203                    return;
7204                }
7205                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7206            } finally {
7207                Binder.restoreCallingIdentity(origId);
7208            }
7209            ActivityOptions.abort(options);
7210        }
7211    }
7212
7213    @Override
7214    public void moveTaskToBack(int taskId) {
7215        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7216                "moveTaskToBack()");
7217
7218        synchronized(this) {
7219            TaskRecord tr = recentTaskForIdLocked(taskId);
7220            if (tr != null) {
7221                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7222                ActivityStack stack = tr.stack;
7223                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7224                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7225                            Binder.getCallingUid(), "Task to back")) {
7226                        return;
7227                    }
7228                }
7229                final long origId = Binder.clearCallingIdentity();
7230                try {
7231                    stack.moveTaskToBackLocked(taskId, null);
7232                } finally {
7233                    Binder.restoreCallingIdentity(origId);
7234                }
7235            }
7236        }
7237    }
7238
7239    /**
7240     * Moves an activity, and all of the other activities within the same task, to the bottom
7241     * of the history stack.  The activity's order within the task is unchanged.
7242     *
7243     * @param token A reference to the activity we wish to move
7244     * @param nonRoot If false then this only works if the activity is the root
7245     *                of a task; if true it will work for any activity in a task.
7246     * @return Returns true if the move completed, false if not.
7247     */
7248    @Override
7249    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7250        enforceNotIsolatedCaller("moveActivityTaskToBack");
7251        synchronized(this) {
7252            final long origId = Binder.clearCallingIdentity();
7253            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7254            if (taskId >= 0) {
7255                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7256            }
7257            Binder.restoreCallingIdentity(origId);
7258        }
7259        return false;
7260    }
7261
7262    @Override
7263    public void moveTaskBackwards(int task) {
7264        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7265                "moveTaskBackwards()");
7266
7267        synchronized(this) {
7268            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7269                    Binder.getCallingUid(), "Task backwards")) {
7270                return;
7271            }
7272            final long origId = Binder.clearCallingIdentity();
7273            moveTaskBackwardsLocked(task);
7274            Binder.restoreCallingIdentity(origId);
7275        }
7276    }
7277
7278    private final void moveTaskBackwardsLocked(int task) {
7279        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7280    }
7281
7282    @Override
7283    public IBinder getHomeActivityToken() throws RemoteException {
7284        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7285                "getHomeActivityToken()");
7286        synchronized (this) {
7287            return mStackSupervisor.getHomeActivityToken();
7288        }
7289    }
7290
7291    @Override
7292    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7293            IActivityContainerCallback callback) throws RemoteException {
7294        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7295                "createActivityContainer()");
7296        synchronized (this) {
7297            if (parentActivityToken == null) {
7298                throw new IllegalArgumentException("parent token must not be null");
7299            }
7300            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7301            if (r == null) {
7302                return null;
7303            }
7304            if (callback == null) {
7305                throw new IllegalArgumentException("callback must not be null");
7306            }
7307            return mStackSupervisor.createActivityContainer(r, callback);
7308        }
7309    }
7310
7311    @Override
7312    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7313        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7314                "deleteActivityContainer()");
7315        synchronized (this) {
7316            mStackSupervisor.deleteActivityContainer(container);
7317        }
7318    }
7319
7320    @Override
7321    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7322            throws RemoteException {
7323        synchronized (this) {
7324            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7325            if (stack != null) {
7326                return stack.mActivityContainer;
7327            }
7328            return null;
7329        }
7330    }
7331
7332    @Override
7333    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7334        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7335                "moveTaskToStack()");
7336        if (stackId == HOME_STACK_ID) {
7337            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7338                    new RuntimeException("here").fillInStackTrace());
7339        }
7340        synchronized (this) {
7341            long ident = Binder.clearCallingIdentity();
7342            try {
7343                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7344                        + stackId + " toTop=" + toTop);
7345                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7346            } finally {
7347                Binder.restoreCallingIdentity(ident);
7348            }
7349        }
7350    }
7351
7352    @Override
7353    public void resizeStack(int stackBoxId, Rect bounds) {
7354        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7355                "resizeStackBox()");
7356        long ident = Binder.clearCallingIdentity();
7357        try {
7358            mWindowManager.resizeStack(stackBoxId, bounds);
7359        } finally {
7360            Binder.restoreCallingIdentity(ident);
7361        }
7362    }
7363
7364    @Override
7365    public List<StackInfo> getAllStackInfos() {
7366        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7367                "getAllStackInfos()");
7368        long ident = Binder.clearCallingIdentity();
7369        try {
7370            synchronized (this) {
7371                return mStackSupervisor.getAllStackInfosLocked();
7372            }
7373        } finally {
7374            Binder.restoreCallingIdentity(ident);
7375        }
7376    }
7377
7378    @Override
7379    public StackInfo getStackInfo(int stackId) {
7380        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7381                "getStackInfo()");
7382        long ident = Binder.clearCallingIdentity();
7383        try {
7384            synchronized (this) {
7385                return mStackSupervisor.getStackInfoLocked(stackId);
7386            }
7387        } finally {
7388            Binder.restoreCallingIdentity(ident);
7389        }
7390    }
7391
7392    @Override
7393    public boolean isInHomeStack(int taskId) {
7394        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7395                "getStackInfo()");
7396        long ident = Binder.clearCallingIdentity();
7397        try {
7398            synchronized (this) {
7399                TaskRecord tr = recentTaskForIdLocked(taskId);
7400                if (tr != null) {
7401                    return tr.stack.isHomeStack();
7402                }
7403            }
7404        } finally {
7405            Binder.restoreCallingIdentity(ident);
7406        }
7407        return false;
7408    }
7409
7410    @Override
7411    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7412        synchronized(this) {
7413            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7414        }
7415    }
7416
7417    private boolean isLockTaskAuthorized(ComponentName name) {
7418//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7419//                "startLockTaskMode()");
7420//        DevicePolicyManager dpm = (DevicePolicyManager)
7421//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7422//        return dpm != null && dpm.isLockTaskPermitted(name);
7423        return true;
7424    }
7425
7426    private void startLockTaskMode(TaskRecord task) {
7427        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7428            return;
7429        }
7430        long ident = Binder.clearCallingIdentity();
7431        try {
7432            synchronized (this) {
7433                // Since we lost lock on task, make sure it is still there.
7434                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7435                if (task != null) {
7436                    mStackSupervisor.setLockTaskModeLocked(task);
7437                }
7438            }
7439        } finally {
7440            Binder.restoreCallingIdentity(ident);
7441        }
7442    }
7443
7444    @Override
7445    public void startLockTaskMode(int taskId) {
7446        long ident = Binder.clearCallingIdentity();
7447        try {
7448            final TaskRecord task;
7449            synchronized (this) {
7450                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7451            }
7452            if (task != null) {
7453                startLockTaskMode(task);
7454            }
7455        } finally {
7456            Binder.restoreCallingIdentity(ident);
7457        }
7458    }
7459
7460    @Override
7461    public void startLockTaskMode(IBinder token) {
7462        long ident = Binder.clearCallingIdentity();
7463        try {
7464            final TaskRecord task;
7465            synchronized (this) {
7466                final ActivityRecord r = ActivityRecord.forToken(token);
7467                if (r == null) {
7468                    return;
7469                }
7470                task = r.task;
7471            }
7472            if (task != null) {
7473                startLockTaskMode(task);
7474            }
7475        } finally {
7476            Binder.restoreCallingIdentity(ident);
7477        }
7478    }
7479
7480    @Override
7481    public void stopLockTaskMode() {
7482//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7483//                "stopLockTaskMode()");
7484        synchronized (this) {
7485            mStackSupervisor.setLockTaskModeLocked(null);
7486        }
7487    }
7488
7489    @Override
7490    public boolean isInLockTaskMode() {
7491        synchronized (this) {
7492            return mStackSupervisor.isInLockTaskMode();
7493        }
7494    }
7495
7496    // =========================================================
7497    // THUMBNAILS
7498    // =========================================================
7499
7500    public void reportThumbnail(IBinder token,
7501            Bitmap thumbnail, CharSequence description) {
7502        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7503        final long origId = Binder.clearCallingIdentity();
7504        sendPendingThumbnail(null, token, thumbnail, description, true);
7505        Binder.restoreCallingIdentity(origId);
7506    }
7507
7508    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7509            Bitmap thumbnail, CharSequence description, boolean always) {
7510        TaskRecord task;
7511        ArrayList<PendingThumbnailsRecord> receivers = null;
7512
7513        //System.out.println("Send pending thumbnail: " + r);
7514
7515        synchronized(this) {
7516            if (r == null) {
7517                r = ActivityRecord.isInStackLocked(token);
7518                if (r == null) {
7519                    return;
7520                }
7521            }
7522            if (thumbnail == null && r.thumbHolder != null) {
7523                thumbnail = r.thumbHolder.lastThumbnail;
7524                description = r.thumbHolder.lastDescription;
7525            }
7526            if (thumbnail == null && !always) {
7527                // If there is no thumbnail, and this entry is not actually
7528                // going away, then abort for now and pick up the next
7529                // thumbnail we get.
7530                return;
7531            }
7532            task = r.task;
7533
7534            int N = mPendingThumbnails.size();
7535            int i=0;
7536            while (i<N) {
7537                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7538                //System.out.println("Looking in " + pr.pendingRecords);
7539                if (pr.pendingRecords.remove(r)) {
7540                    if (receivers == null) {
7541                        receivers = new ArrayList<PendingThumbnailsRecord>();
7542                    }
7543                    receivers.add(pr);
7544                    if (pr.pendingRecords.size() == 0) {
7545                        pr.finished = true;
7546                        mPendingThumbnails.remove(i);
7547                        N--;
7548                        continue;
7549                    }
7550                }
7551                i++;
7552            }
7553        }
7554
7555        if (receivers != null) {
7556            final int N = receivers.size();
7557            for (int i=0; i<N; i++) {
7558                try {
7559                    PendingThumbnailsRecord pr = receivers.get(i);
7560                    pr.receiver.newThumbnail(
7561                        task != null ? task.taskId : -1, thumbnail, description);
7562                    if (pr.finished) {
7563                        pr.receiver.finished();
7564                    }
7565                } catch (Exception e) {
7566                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7567                }
7568            }
7569        }
7570    }
7571
7572    // =========================================================
7573    // CONTENT PROVIDERS
7574    // =========================================================
7575
7576    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7577        List<ProviderInfo> providers = null;
7578        try {
7579            providers = AppGlobals.getPackageManager().
7580                queryContentProviders(app.processName, app.uid,
7581                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7582        } catch (RemoteException ex) {
7583        }
7584        if (DEBUG_MU)
7585            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7586        int userId = app.userId;
7587        if (providers != null) {
7588            int N = providers.size();
7589            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7590            for (int i=0; i<N; i++) {
7591                ProviderInfo cpi =
7592                    (ProviderInfo)providers.get(i);
7593                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7594                        cpi.name, cpi.flags);
7595                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7596                    // This is a singleton provider, but a user besides the
7597                    // default user is asking to initialize a process it runs
7598                    // in...  well, no, it doesn't actually run in this process,
7599                    // it runs in the process of the default user.  Get rid of it.
7600                    providers.remove(i);
7601                    N--;
7602                    i--;
7603                    continue;
7604                }
7605
7606                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7607                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7608                if (cpr == null) {
7609                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7610                    mProviderMap.putProviderByClass(comp, cpr);
7611                }
7612                if (DEBUG_MU)
7613                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7614                app.pubProviders.put(cpi.name, cpr);
7615                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7616                    // Don't add this if it is a platform component that is marked
7617                    // to run in multiple processes, because this is actually
7618                    // part of the framework so doesn't make sense to track as a
7619                    // separate apk in the process.
7620                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7621                }
7622                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7623            }
7624        }
7625        return providers;
7626    }
7627
7628    /**
7629     * Check if {@link ProcessRecord} has a possible chance at accessing the
7630     * given {@link ProviderInfo}. Final permission checking is always done
7631     * in {@link ContentProvider}.
7632     */
7633    private final String checkContentProviderPermissionLocked(
7634            ProviderInfo cpi, ProcessRecord r) {
7635        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7636        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7637        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7638                cpi.applicationInfo.uid, cpi.exported)
7639                == PackageManager.PERMISSION_GRANTED) {
7640            return null;
7641        }
7642        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7643                cpi.applicationInfo.uid, cpi.exported)
7644                == PackageManager.PERMISSION_GRANTED) {
7645            return null;
7646        }
7647
7648        PathPermission[] pps = cpi.pathPermissions;
7649        if (pps != null) {
7650            int i = pps.length;
7651            while (i > 0) {
7652                i--;
7653                PathPermission pp = pps[i];
7654                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7655                        cpi.applicationInfo.uid, cpi.exported)
7656                        == PackageManager.PERMISSION_GRANTED) {
7657                    return null;
7658                }
7659                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7660                        cpi.applicationInfo.uid, cpi.exported)
7661                        == PackageManager.PERMISSION_GRANTED) {
7662                    return null;
7663                }
7664            }
7665        }
7666
7667        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7668        if (perms != null) {
7669            for (GrantUri uri : perms.keySet()) {
7670                if (uri.uri.getAuthority().equals(cpi.authority)) {
7671                    return null;
7672                }
7673            }
7674        }
7675
7676        String msg;
7677        if (!cpi.exported) {
7678            msg = "Permission Denial: opening provider " + cpi.name
7679                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7680                    + ", uid=" + callingUid + ") that is not exported from uid "
7681                    + cpi.applicationInfo.uid;
7682        } else {
7683            msg = "Permission Denial: opening provider " + cpi.name
7684                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7685                    + ", uid=" + callingUid + ") requires "
7686                    + cpi.readPermission + " or " + cpi.writePermission;
7687        }
7688        Slog.w(TAG, msg);
7689        return msg;
7690    }
7691
7692    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7693            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7694        if (r != null) {
7695            for (int i=0; i<r.conProviders.size(); i++) {
7696                ContentProviderConnection conn = r.conProviders.get(i);
7697                if (conn.provider == cpr) {
7698                    if (DEBUG_PROVIDER) Slog.v(TAG,
7699                            "Adding provider requested by "
7700                            + r.processName + " from process "
7701                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7702                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7703                    if (stable) {
7704                        conn.stableCount++;
7705                        conn.numStableIncs++;
7706                    } else {
7707                        conn.unstableCount++;
7708                        conn.numUnstableIncs++;
7709                    }
7710                    return conn;
7711                }
7712            }
7713            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7714            if (stable) {
7715                conn.stableCount = 1;
7716                conn.numStableIncs = 1;
7717            } else {
7718                conn.unstableCount = 1;
7719                conn.numUnstableIncs = 1;
7720            }
7721            cpr.connections.add(conn);
7722            r.conProviders.add(conn);
7723            return conn;
7724        }
7725        cpr.addExternalProcessHandleLocked(externalProcessToken);
7726        return null;
7727    }
7728
7729    boolean decProviderCountLocked(ContentProviderConnection conn,
7730            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7731        if (conn != null) {
7732            cpr = conn.provider;
7733            if (DEBUG_PROVIDER) Slog.v(TAG,
7734                    "Removing provider requested by "
7735                    + conn.client.processName + " from process "
7736                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7737                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7738            if (stable) {
7739                conn.stableCount--;
7740            } else {
7741                conn.unstableCount--;
7742            }
7743            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7744                cpr.connections.remove(conn);
7745                conn.client.conProviders.remove(conn);
7746                return true;
7747            }
7748            return false;
7749        }
7750        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7751        return false;
7752    }
7753
7754    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7755            String name, IBinder token, boolean stable, int userId) {
7756        ContentProviderRecord cpr;
7757        ContentProviderConnection conn = null;
7758        ProviderInfo cpi = null;
7759
7760        synchronized(this) {
7761            ProcessRecord r = null;
7762            if (caller != null) {
7763                r = getRecordForAppLocked(caller);
7764                if (r == null) {
7765                    throw new SecurityException(
7766                            "Unable to find app for caller " + caller
7767                          + " (pid=" + Binder.getCallingPid()
7768                          + ") when getting content provider " + name);
7769                }
7770            }
7771
7772            // First check if this content provider has been published...
7773            cpr = mProviderMap.getProviderByName(name, userId);
7774            boolean providerRunning = cpr != null;
7775            if (providerRunning) {
7776                cpi = cpr.info;
7777                String msg;
7778                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7779                    throw new SecurityException(msg);
7780                }
7781
7782                if (r != null && cpr.canRunHere(r)) {
7783                    // This provider has been published or is in the process
7784                    // of being published...  but it is also allowed to run
7785                    // in the caller's process, so don't make a connection
7786                    // and just let the caller instantiate its own instance.
7787                    ContentProviderHolder holder = cpr.newHolder(null);
7788                    // don't give caller the provider object, it needs
7789                    // to make its own.
7790                    holder.provider = null;
7791                    return holder;
7792                }
7793
7794                final long origId = Binder.clearCallingIdentity();
7795
7796                // In this case the provider instance already exists, so we can
7797                // return it right away.
7798                conn = incProviderCountLocked(r, cpr, token, stable);
7799                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7800                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7801                        // If this is a perceptible app accessing the provider,
7802                        // make sure to count it as being accessed and thus
7803                        // back up on the LRU list.  This is good because
7804                        // content providers are often expensive to start.
7805                        updateLruProcessLocked(cpr.proc, false, null);
7806                    }
7807                }
7808
7809                if (cpr.proc != null) {
7810                    if (false) {
7811                        if (cpr.name.flattenToShortString().equals(
7812                                "com.android.providers.calendar/.CalendarProvider2")) {
7813                            Slog.v(TAG, "****************** KILLING "
7814                                + cpr.name.flattenToShortString());
7815                            Process.killProcess(cpr.proc.pid);
7816                        }
7817                    }
7818                    boolean success = updateOomAdjLocked(cpr.proc);
7819                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7820                    // NOTE: there is still a race here where a signal could be
7821                    // pending on the process even though we managed to update its
7822                    // adj level.  Not sure what to do about this, but at least
7823                    // the race is now smaller.
7824                    if (!success) {
7825                        // Uh oh...  it looks like the provider's process
7826                        // has been killed on us.  We need to wait for a new
7827                        // process to be started, and make sure its death
7828                        // doesn't kill our process.
7829                        Slog.i(TAG,
7830                                "Existing provider " + cpr.name.flattenToShortString()
7831                                + " is crashing; detaching " + r);
7832                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7833                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7834                        if (!lastRef) {
7835                            // This wasn't the last ref our process had on
7836                            // the provider...  we have now been killed, bail.
7837                            return null;
7838                        }
7839                        providerRunning = false;
7840                        conn = null;
7841                    }
7842                }
7843
7844                Binder.restoreCallingIdentity(origId);
7845            }
7846
7847            boolean singleton;
7848            if (!providerRunning) {
7849                try {
7850                    cpi = AppGlobals.getPackageManager().
7851                        resolveContentProvider(name,
7852                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7853                } catch (RemoteException ex) {
7854                }
7855                if (cpi == null) {
7856                    return null;
7857                }
7858                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7859                        cpi.name, cpi.flags);
7860                if (singleton) {
7861                    userId = 0;
7862                }
7863                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7864
7865                String msg;
7866                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7867                    throw new SecurityException(msg);
7868                }
7869
7870                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7871                        && !cpi.processName.equals("system")) {
7872                    // If this content provider does not run in the system
7873                    // process, and the system is not yet ready to run other
7874                    // processes, then fail fast instead of hanging.
7875                    throw new IllegalArgumentException(
7876                            "Attempt to launch content provider before system ready");
7877                }
7878
7879                // Make sure that the user who owns this provider is started.  If not,
7880                // we don't want to allow it to run.
7881                if (mStartedUsers.get(userId) == null) {
7882                    Slog.w(TAG, "Unable to launch app "
7883                            + cpi.applicationInfo.packageName + "/"
7884                            + cpi.applicationInfo.uid + " for provider "
7885                            + name + ": user " + userId + " is stopped");
7886                    return null;
7887                }
7888
7889                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7890                cpr = mProviderMap.getProviderByClass(comp, userId);
7891                final boolean firstClass = cpr == null;
7892                if (firstClass) {
7893                    try {
7894                        ApplicationInfo ai =
7895                            AppGlobals.getPackageManager().
7896                                getApplicationInfo(
7897                                        cpi.applicationInfo.packageName,
7898                                        STOCK_PM_FLAGS, userId);
7899                        if (ai == null) {
7900                            Slog.w(TAG, "No package info for content provider "
7901                                    + cpi.name);
7902                            return null;
7903                        }
7904                        ai = getAppInfoForUser(ai, userId);
7905                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7906                    } catch (RemoteException ex) {
7907                        // pm is in same process, this will never happen.
7908                    }
7909                }
7910
7911                if (r != null && cpr.canRunHere(r)) {
7912                    // If this is a multiprocess provider, then just return its
7913                    // info and allow the caller to instantiate it.  Only do
7914                    // this if the provider is the same user as the caller's
7915                    // process, or can run as root (so can be in any process).
7916                    return cpr.newHolder(null);
7917                }
7918
7919                if (DEBUG_PROVIDER) {
7920                    RuntimeException e = new RuntimeException("here");
7921                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7922                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7923                }
7924
7925                // This is single process, and our app is now connecting to it.
7926                // See if we are already in the process of launching this
7927                // provider.
7928                final int N = mLaunchingProviders.size();
7929                int i;
7930                for (i=0; i<N; i++) {
7931                    if (mLaunchingProviders.get(i) == cpr) {
7932                        break;
7933                    }
7934                }
7935
7936                // If the provider is not already being launched, then get it
7937                // started.
7938                if (i >= N) {
7939                    final long origId = Binder.clearCallingIdentity();
7940
7941                    try {
7942                        // Content provider is now in use, its package can't be stopped.
7943                        try {
7944                            AppGlobals.getPackageManager().setPackageStoppedState(
7945                                    cpr.appInfo.packageName, false, userId);
7946                        } catch (RemoteException e) {
7947                        } catch (IllegalArgumentException e) {
7948                            Slog.w(TAG, "Failed trying to unstop package "
7949                                    + cpr.appInfo.packageName + ": " + e);
7950                        }
7951
7952                        // Use existing process if already started
7953                        ProcessRecord proc = getProcessRecordLocked(
7954                                cpi.processName, cpr.appInfo.uid, false);
7955                        if (proc != null && proc.thread != null) {
7956                            if (DEBUG_PROVIDER) {
7957                                Slog.d(TAG, "Installing in existing process " + proc);
7958                            }
7959                            proc.pubProviders.put(cpi.name, cpr);
7960                            try {
7961                                proc.thread.scheduleInstallProvider(cpi);
7962                            } catch (RemoteException e) {
7963                            }
7964                        } else {
7965                            proc = startProcessLocked(cpi.processName,
7966                                    cpr.appInfo, false, 0, "content provider",
7967                                    new ComponentName(cpi.applicationInfo.packageName,
7968                                            cpi.name), false, false, false);
7969                            if (proc == null) {
7970                                Slog.w(TAG, "Unable to launch app "
7971                                        + cpi.applicationInfo.packageName + "/"
7972                                        + cpi.applicationInfo.uid + " for provider "
7973                                        + name + ": process is bad");
7974                                return null;
7975                            }
7976                        }
7977                        cpr.launchingApp = proc;
7978                        mLaunchingProviders.add(cpr);
7979                    } finally {
7980                        Binder.restoreCallingIdentity(origId);
7981                    }
7982                }
7983
7984                // Make sure the provider is published (the same provider class
7985                // may be published under multiple names).
7986                if (firstClass) {
7987                    mProviderMap.putProviderByClass(comp, cpr);
7988                }
7989
7990                mProviderMap.putProviderByName(name, cpr);
7991                conn = incProviderCountLocked(r, cpr, token, stable);
7992                if (conn != null) {
7993                    conn.waiting = true;
7994                }
7995            }
7996        }
7997
7998        // Wait for the provider to be published...
7999        synchronized (cpr) {
8000            while (cpr.provider == null) {
8001                if (cpr.launchingApp == null) {
8002                    Slog.w(TAG, "Unable to launch app "
8003                            + cpi.applicationInfo.packageName + "/"
8004                            + cpi.applicationInfo.uid + " for provider "
8005                            + name + ": launching app became null");
8006                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8007                            UserHandle.getUserId(cpi.applicationInfo.uid),
8008                            cpi.applicationInfo.packageName,
8009                            cpi.applicationInfo.uid, name);
8010                    return null;
8011                }
8012                try {
8013                    if (DEBUG_MU) {
8014                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8015                                + cpr.launchingApp);
8016                    }
8017                    if (conn != null) {
8018                        conn.waiting = true;
8019                    }
8020                    cpr.wait();
8021                } catch (InterruptedException ex) {
8022                } finally {
8023                    if (conn != null) {
8024                        conn.waiting = false;
8025                    }
8026                }
8027            }
8028        }
8029        return cpr != null ? cpr.newHolder(conn) : null;
8030    }
8031
8032    public final ContentProviderHolder getContentProvider(
8033            IApplicationThread caller, String name, int userId, boolean stable) {
8034        enforceNotIsolatedCaller("getContentProvider");
8035        if (caller == null) {
8036            String msg = "null IApplicationThread when getting content provider "
8037                    + name;
8038            Slog.w(TAG, msg);
8039            throw new SecurityException(msg);
8040        }
8041
8042        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8043                false, true, "getContentProvider", null);
8044        return getContentProviderImpl(caller, name, null, stable, userId);
8045    }
8046
8047    public ContentProviderHolder getContentProviderExternal(
8048            String name, int userId, IBinder token) {
8049        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8050            "Do not have permission in call getContentProviderExternal()");
8051        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8052                false, true, "getContentProvider", null);
8053        return getContentProviderExternalUnchecked(name, token, userId);
8054    }
8055
8056    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8057            IBinder token, int userId) {
8058        return getContentProviderImpl(null, name, token, true, userId);
8059    }
8060
8061    /**
8062     * Drop a content provider from a ProcessRecord's bookkeeping
8063     */
8064    public void removeContentProvider(IBinder connection, boolean stable) {
8065        enforceNotIsolatedCaller("removeContentProvider");
8066        long ident = Binder.clearCallingIdentity();
8067        try {
8068            synchronized (this) {
8069                ContentProviderConnection conn;
8070                try {
8071                    conn = (ContentProviderConnection)connection;
8072                } catch (ClassCastException e) {
8073                    String msg ="removeContentProvider: " + connection
8074                            + " not a ContentProviderConnection";
8075                    Slog.w(TAG, msg);
8076                    throw new IllegalArgumentException(msg);
8077                }
8078                if (conn == null) {
8079                    throw new NullPointerException("connection is null");
8080                }
8081                if (decProviderCountLocked(conn, null, null, stable)) {
8082                    updateOomAdjLocked();
8083                }
8084            }
8085        } finally {
8086            Binder.restoreCallingIdentity(ident);
8087        }
8088    }
8089
8090    public void removeContentProviderExternal(String name, IBinder token) {
8091        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8092            "Do not have permission in call removeContentProviderExternal()");
8093        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8094    }
8095
8096    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8097        synchronized (this) {
8098            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8099            if(cpr == null) {
8100                //remove from mProvidersByClass
8101                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8102                return;
8103            }
8104
8105            //update content provider record entry info
8106            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8107            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8108            if (localCpr.hasExternalProcessHandles()) {
8109                if (localCpr.removeExternalProcessHandleLocked(token)) {
8110                    updateOomAdjLocked();
8111                } else {
8112                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8113                            + " with no external reference for token: "
8114                            + token + ".");
8115                }
8116            } else {
8117                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8118                        + " with no external references.");
8119            }
8120        }
8121    }
8122
8123    public final void publishContentProviders(IApplicationThread caller,
8124            List<ContentProviderHolder> providers) {
8125        if (providers == null) {
8126            return;
8127        }
8128
8129        enforceNotIsolatedCaller("publishContentProviders");
8130        synchronized (this) {
8131            final ProcessRecord r = getRecordForAppLocked(caller);
8132            if (DEBUG_MU)
8133                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8134            if (r == null) {
8135                throw new SecurityException(
8136                        "Unable to find app for caller " + caller
8137                      + " (pid=" + Binder.getCallingPid()
8138                      + ") when publishing content providers");
8139            }
8140
8141            final long origId = Binder.clearCallingIdentity();
8142
8143            final int N = providers.size();
8144            for (int i=0; i<N; i++) {
8145                ContentProviderHolder src = providers.get(i);
8146                if (src == null || src.info == null || src.provider == null) {
8147                    continue;
8148                }
8149                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8150                if (DEBUG_MU)
8151                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8152                if (dst != null) {
8153                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8154                    mProviderMap.putProviderByClass(comp, dst);
8155                    String names[] = dst.info.authority.split(";");
8156                    for (int j = 0; j < names.length; j++) {
8157                        mProviderMap.putProviderByName(names[j], dst);
8158                    }
8159
8160                    int NL = mLaunchingProviders.size();
8161                    int j;
8162                    for (j=0; j<NL; j++) {
8163                        if (mLaunchingProviders.get(j) == dst) {
8164                            mLaunchingProviders.remove(j);
8165                            j--;
8166                            NL--;
8167                        }
8168                    }
8169                    synchronized (dst) {
8170                        dst.provider = src.provider;
8171                        dst.proc = r;
8172                        dst.notifyAll();
8173                    }
8174                    updateOomAdjLocked(r);
8175                }
8176            }
8177
8178            Binder.restoreCallingIdentity(origId);
8179        }
8180    }
8181
8182    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8183        ContentProviderConnection conn;
8184        try {
8185            conn = (ContentProviderConnection)connection;
8186        } catch (ClassCastException e) {
8187            String msg ="refContentProvider: " + connection
8188                    + " not a ContentProviderConnection";
8189            Slog.w(TAG, msg);
8190            throw new IllegalArgumentException(msg);
8191        }
8192        if (conn == null) {
8193            throw new NullPointerException("connection is null");
8194        }
8195
8196        synchronized (this) {
8197            if (stable > 0) {
8198                conn.numStableIncs += stable;
8199            }
8200            stable = conn.stableCount + stable;
8201            if (stable < 0) {
8202                throw new IllegalStateException("stableCount < 0: " + stable);
8203            }
8204
8205            if (unstable > 0) {
8206                conn.numUnstableIncs += unstable;
8207            }
8208            unstable = conn.unstableCount + unstable;
8209            if (unstable < 0) {
8210                throw new IllegalStateException("unstableCount < 0: " + unstable);
8211            }
8212
8213            if ((stable+unstable) <= 0) {
8214                throw new IllegalStateException("ref counts can't go to zero here: stable="
8215                        + stable + " unstable=" + unstable);
8216            }
8217            conn.stableCount = stable;
8218            conn.unstableCount = unstable;
8219            return !conn.dead;
8220        }
8221    }
8222
8223    public void unstableProviderDied(IBinder connection) {
8224        ContentProviderConnection conn;
8225        try {
8226            conn = (ContentProviderConnection)connection;
8227        } catch (ClassCastException e) {
8228            String msg ="refContentProvider: " + connection
8229                    + " not a ContentProviderConnection";
8230            Slog.w(TAG, msg);
8231            throw new IllegalArgumentException(msg);
8232        }
8233        if (conn == null) {
8234            throw new NullPointerException("connection is null");
8235        }
8236
8237        // Safely retrieve the content provider associated with the connection.
8238        IContentProvider provider;
8239        synchronized (this) {
8240            provider = conn.provider.provider;
8241        }
8242
8243        if (provider == null) {
8244            // Um, yeah, we're way ahead of you.
8245            return;
8246        }
8247
8248        // Make sure the caller is being honest with us.
8249        if (provider.asBinder().pingBinder()) {
8250            // Er, no, still looks good to us.
8251            synchronized (this) {
8252                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8253                        + " says " + conn + " died, but we don't agree");
8254                return;
8255            }
8256        }
8257
8258        // Well look at that!  It's dead!
8259        synchronized (this) {
8260            if (conn.provider.provider != provider) {
8261                // But something changed...  good enough.
8262                return;
8263            }
8264
8265            ProcessRecord proc = conn.provider.proc;
8266            if (proc == null || proc.thread == null) {
8267                // Seems like the process is already cleaned up.
8268                return;
8269            }
8270
8271            // As far as we're concerned, this is just like receiving a
8272            // death notification...  just a bit prematurely.
8273            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8274                    + ") early provider death");
8275            final long ident = Binder.clearCallingIdentity();
8276            try {
8277                appDiedLocked(proc, proc.pid, proc.thread);
8278            } finally {
8279                Binder.restoreCallingIdentity(ident);
8280            }
8281        }
8282    }
8283
8284    @Override
8285    public void appNotRespondingViaProvider(IBinder connection) {
8286        enforceCallingPermission(
8287                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8288
8289        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8290        if (conn == null) {
8291            Slog.w(TAG, "ContentProviderConnection is null");
8292            return;
8293        }
8294
8295        final ProcessRecord host = conn.provider.proc;
8296        if (host == null) {
8297            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8298            return;
8299        }
8300
8301        final long token = Binder.clearCallingIdentity();
8302        try {
8303            appNotResponding(host, null, null, false, "ContentProvider not responding");
8304        } finally {
8305            Binder.restoreCallingIdentity(token);
8306        }
8307    }
8308
8309    public final void installSystemProviders() {
8310        List<ProviderInfo> providers;
8311        synchronized (this) {
8312            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8313            providers = generateApplicationProvidersLocked(app);
8314            if (providers != null) {
8315                for (int i=providers.size()-1; i>=0; i--) {
8316                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8317                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8318                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8319                                + ": not system .apk");
8320                        providers.remove(i);
8321                    }
8322                }
8323            }
8324        }
8325        if (providers != null) {
8326            mSystemThread.installSystemProviders(providers);
8327        }
8328
8329        mCoreSettingsObserver = new CoreSettingsObserver(this);
8330
8331        mUsageStatsService.monitorPackages();
8332    }
8333
8334    /**
8335     * Allows app to retrieve the MIME type of a URI without having permission
8336     * to access its content provider.
8337     *
8338     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8339     *
8340     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8341     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8342     */
8343    public String getProviderMimeType(Uri uri, int userId) {
8344        enforceNotIsolatedCaller("getProviderMimeType");
8345        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8346                userId, false, true, "getProviderMimeType", null);
8347        final String name = uri.getAuthority();
8348        final long ident = Binder.clearCallingIdentity();
8349        ContentProviderHolder holder = null;
8350
8351        try {
8352            holder = getContentProviderExternalUnchecked(name, null, userId);
8353            if (holder != null) {
8354                return holder.provider.getType(uri);
8355            }
8356        } catch (RemoteException e) {
8357            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8358            return null;
8359        } finally {
8360            if (holder != null) {
8361                removeContentProviderExternalUnchecked(name, null, userId);
8362            }
8363            Binder.restoreCallingIdentity(ident);
8364        }
8365
8366        return null;
8367    }
8368
8369    // =========================================================
8370    // GLOBAL MANAGEMENT
8371    // =========================================================
8372
8373    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8374            boolean isolated) {
8375        String proc = customProcess != null ? customProcess : info.processName;
8376        BatteryStatsImpl.Uid.Proc ps = null;
8377        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8378        int uid = info.uid;
8379        if (isolated) {
8380            int userId = UserHandle.getUserId(uid);
8381            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8382            while (true) {
8383                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8384                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8385                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8386                }
8387                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8388                mNextIsolatedProcessUid++;
8389                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8390                    // No process for this uid, use it.
8391                    break;
8392                }
8393                stepsLeft--;
8394                if (stepsLeft <= 0) {
8395                    return null;
8396                }
8397            }
8398        }
8399        return new ProcessRecord(stats, info, proc, uid);
8400    }
8401
8402    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8403        ProcessRecord app;
8404        if (!isolated) {
8405            app = getProcessRecordLocked(info.processName, info.uid, true);
8406        } else {
8407            app = null;
8408        }
8409
8410        if (app == null) {
8411            app = newProcessRecordLocked(info, null, isolated);
8412            mProcessNames.put(info.processName, app.uid, app);
8413            if (isolated) {
8414                mIsolatedProcesses.put(app.uid, app);
8415            }
8416            updateLruProcessLocked(app, false, null);
8417            updateOomAdjLocked();
8418        }
8419
8420        // This package really, really can not be stopped.
8421        try {
8422            AppGlobals.getPackageManager().setPackageStoppedState(
8423                    info.packageName, false, UserHandle.getUserId(app.uid));
8424        } catch (RemoteException e) {
8425        } catch (IllegalArgumentException e) {
8426            Slog.w(TAG, "Failed trying to unstop package "
8427                    + info.packageName + ": " + e);
8428        }
8429
8430        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8431                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8432            app.persistent = true;
8433            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8434        }
8435        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8436            mPersistentStartingProcesses.add(app);
8437            startProcessLocked(app, "added application", app.processName);
8438        }
8439
8440        return app;
8441    }
8442
8443    public void unhandledBack() {
8444        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8445                "unhandledBack()");
8446
8447        synchronized(this) {
8448            final long origId = Binder.clearCallingIdentity();
8449            try {
8450                getFocusedStack().unhandledBackLocked();
8451            } finally {
8452                Binder.restoreCallingIdentity(origId);
8453            }
8454        }
8455    }
8456
8457    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8458        enforceNotIsolatedCaller("openContentUri");
8459        final int userId = UserHandle.getCallingUserId();
8460        String name = uri.getAuthority();
8461        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8462        ParcelFileDescriptor pfd = null;
8463        if (cph != null) {
8464            // We record the binder invoker's uid in thread-local storage before
8465            // going to the content provider to open the file.  Later, in the code
8466            // that handles all permissions checks, we look for this uid and use
8467            // that rather than the Activity Manager's own uid.  The effect is that
8468            // we do the check against the caller's permissions even though it looks
8469            // to the content provider like the Activity Manager itself is making
8470            // the request.
8471            sCallerIdentity.set(new Identity(
8472                    Binder.getCallingPid(), Binder.getCallingUid()));
8473            try {
8474                pfd = cph.provider.openFile(null, uri, "r", null);
8475            } catch (FileNotFoundException e) {
8476                // do nothing; pfd will be returned null
8477            } finally {
8478                // Ensure that whatever happens, we clean up the identity state
8479                sCallerIdentity.remove();
8480            }
8481
8482            // We've got the fd now, so we're done with the provider.
8483            removeContentProviderExternalUnchecked(name, null, userId);
8484        } else {
8485            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8486        }
8487        return pfd;
8488    }
8489
8490    // Actually is sleeping or shutting down or whatever else in the future
8491    // is an inactive state.
8492    public boolean isSleepingOrShuttingDown() {
8493        return mSleeping || mShuttingDown;
8494    }
8495
8496    void goingToSleep() {
8497        synchronized(this) {
8498            mWentToSleep = true;
8499            updateEventDispatchingLocked();
8500
8501            if (!mSleeping) {
8502                mSleeping = true;
8503                mStackSupervisor.goingToSleepLocked();
8504
8505                // Initialize the wake times of all processes.
8506                checkExcessivePowerUsageLocked(false);
8507                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8508                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8509                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8510            }
8511        }
8512    }
8513
8514    @Override
8515    public boolean shutdown(int timeout) {
8516        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8517                != PackageManager.PERMISSION_GRANTED) {
8518            throw new SecurityException("Requires permission "
8519                    + android.Manifest.permission.SHUTDOWN);
8520        }
8521
8522        boolean timedout = false;
8523
8524        synchronized(this) {
8525            mShuttingDown = true;
8526            updateEventDispatchingLocked();
8527            timedout = mStackSupervisor.shutdownLocked(timeout);
8528        }
8529
8530        mAppOpsService.shutdown();
8531        mUsageStatsService.shutdown();
8532        mBatteryStatsService.shutdown();
8533        synchronized (this) {
8534            mProcessStats.shutdownLocked();
8535        }
8536
8537        return timedout;
8538    }
8539
8540    public final void activitySlept(IBinder token) {
8541        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8542
8543        final long origId = Binder.clearCallingIdentity();
8544
8545        synchronized (this) {
8546            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8547            if (r != null) {
8548                mStackSupervisor.activitySleptLocked(r);
8549            }
8550        }
8551
8552        Binder.restoreCallingIdentity(origId);
8553    }
8554
8555    void logLockScreen(String msg) {
8556        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8557                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8558                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8559                mStackSupervisor.mDismissKeyguardOnNextActivity);
8560    }
8561
8562    private void comeOutOfSleepIfNeededLocked() {
8563        if (!mWentToSleep && !mLockScreenShown) {
8564            if (mSleeping) {
8565                mSleeping = false;
8566                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8567            }
8568        }
8569    }
8570
8571    void wakingUp() {
8572        synchronized(this) {
8573            mWentToSleep = false;
8574            updateEventDispatchingLocked();
8575            comeOutOfSleepIfNeededLocked();
8576        }
8577    }
8578
8579    private void updateEventDispatchingLocked() {
8580        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8581    }
8582
8583    public void setLockScreenShown(boolean shown) {
8584        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8585                != PackageManager.PERMISSION_GRANTED) {
8586            throw new SecurityException("Requires permission "
8587                    + android.Manifest.permission.DEVICE_POWER);
8588        }
8589
8590        synchronized(this) {
8591            long ident = Binder.clearCallingIdentity();
8592            try {
8593                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8594                mLockScreenShown = shown;
8595                comeOutOfSleepIfNeededLocked();
8596            } finally {
8597                Binder.restoreCallingIdentity(ident);
8598            }
8599        }
8600    }
8601
8602    public void stopAppSwitches() {
8603        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8604                != PackageManager.PERMISSION_GRANTED) {
8605            throw new SecurityException("Requires permission "
8606                    + android.Manifest.permission.STOP_APP_SWITCHES);
8607        }
8608
8609        synchronized(this) {
8610            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8611                    + APP_SWITCH_DELAY_TIME;
8612            mDidAppSwitch = false;
8613            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8614            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8615            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8616        }
8617    }
8618
8619    public void resumeAppSwitches() {
8620        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8621                != PackageManager.PERMISSION_GRANTED) {
8622            throw new SecurityException("Requires permission "
8623                    + android.Manifest.permission.STOP_APP_SWITCHES);
8624        }
8625
8626        synchronized(this) {
8627            // Note that we don't execute any pending app switches... we will
8628            // let those wait until either the timeout, or the next start
8629            // activity request.
8630            mAppSwitchesAllowedTime = 0;
8631        }
8632    }
8633
8634    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8635            String name) {
8636        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8637            return true;
8638        }
8639
8640        final int perm = checkComponentPermission(
8641                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8642                callingUid, -1, true);
8643        if (perm == PackageManager.PERMISSION_GRANTED) {
8644            return true;
8645        }
8646
8647        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8648        return false;
8649    }
8650
8651    public void setDebugApp(String packageName, boolean waitForDebugger,
8652            boolean persistent) {
8653        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8654                "setDebugApp()");
8655
8656        long ident = Binder.clearCallingIdentity();
8657        try {
8658            // Note that this is not really thread safe if there are multiple
8659            // callers into it at the same time, but that's not a situation we
8660            // care about.
8661            if (persistent) {
8662                final ContentResolver resolver = mContext.getContentResolver();
8663                Settings.Global.putString(
8664                    resolver, Settings.Global.DEBUG_APP,
8665                    packageName);
8666                Settings.Global.putInt(
8667                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8668                    waitForDebugger ? 1 : 0);
8669            }
8670
8671            synchronized (this) {
8672                if (!persistent) {
8673                    mOrigDebugApp = mDebugApp;
8674                    mOrigWaitForDebugger = mWaitForDebugger;
8675                }
8676                mDebugApp = packageName;
8677                mWaitForDebugger = waitForDebugger;
8678                mDebugTransient = !persistent;
8679                if (packageName != null) {
8680                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8681                            false, UserHandle.USER_ALL, "set debug app");
8682                }
8683            }
8684        } finally {
8685            Binder.restoreCallingIdentity(ident);
8686        }
8687    }
8688
8689    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8690        synchronized (this) {
8691            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8692            if (!isDebuggable) {
8693                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8694                    throw new SecurityException("Process not debuggable: " + app.packageName);
8695                }
8696            }
8697
8698            mOpenGlTraceApp = processName;
8699        }
8700    }
8701
8702    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8703            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8704        synchronized (this) {
8705            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8706            if (!isDebuggable) {
8707                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8708                    throw new SecurityException("Process not debuggable: " + app.packageName);
8709                }
8710            }
8711            mProfileApp = processName;
8712            mProfileFile = profileFile;
8713            if (mProfileFd != null) {
8714                try {
8715                    mProfileFd.close();
8716                } catch (IOException e) {
8717                }
8718                mProfileFd = null;
8719            }
8720            mProfileFd = profileFd;
8721            mProfileType = 0;
8722            mAutoStopProfiler = autoStopProfiler;
8723        }
8724    }
8725
8726    @Override
8727    public void setAlwaysFinish(boolean enabled) {
8728        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8729                "setAlwaysFinish()");
8730
8731        Settings.Global.putInt(
8732                mContext.getContentResolver(),
8733                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8734
8735        synchronized (this) {
8736            mAlwaysFinishActivities = enabled;
8737        }
8738    }
8739
8740    @Override
8741    public void setActivityController(IActivityController controller) {
8742        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8743                "setActivityController()");
8744        synchronized (this) {
8745            mController = controller;
8746            Watchdog.getInstance().setActivityController(controller);
8747        }
8748    }
8749
8750    @Override
8751    public void setUserIsMonkey(boolean userIsMonkey) {
8752        synchronized (this) {
8753            synchronized (mPidsSelfLocked) {
8754                final int callingPid = Binder.getCallingPid();
8755                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8756                if (precessRecord == null) {
8757                    throw new SecurityException("Unknown process: " + callingPid);
8758                }
8759                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8760                    throw new SecurityException("Only an instrumentation process "
8761                            + "with a UiAutomation can call setUserIsMonkey");
8762                }
8763            }
8764            mUserIsMonkey = userIsMonkey;
8765        }
8766    }
8767
8768    @Override
8769    public boolean isUserAMonkey() {
8770        synchronized (this) {
8771            // If there is a controller also implies the user is a monkey.
8772            return (mUserIsMonkey || mController != null);
8773        }
8774    }
8775
8776    public void requestBugReport() {
8777        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8778        SystemProperties.set("ctl.start", "bugreport");
8779    }
8780
8781    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8782        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8783    }
8784
8785    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8786        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8787            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8788        }
8789        return KEY_DISPATCHING_TIMEOUT;
8790    }
8791
8792    @Override
8793    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8794        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8795                != PackageManager.PERMISSION_GRANTED) {
8796            throw new SecurityException("Requires permission "
8797                    + android.Manifest.permission.FILTER_EVENTS);
8798        }
8799        ProcessRecord proc;
8800        long timeout;
8801        synchronized (this) {
8802            synchronized (mPidsSelfLocked) {
8803                proc = mPidsSelfLocked.get(pid);
8804            }
8805            timeout = getInputDispatchingTimeoutLocked(proc);
8806        }
8807
8808        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8809            return -1;
8810        }
8811
8812        return timeout;
8813    }
8814
8815    /**
8816     * Handle input dispatching timeouts.
8817     * Returns whether input dispatching should be aborted or not.
8818     */
8819    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8820            final ActivityRecord activity, final ActivityRecord parent,
8821            final boolean aboveSystem, String reason) {
8822        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8823                != PackageManager.PERMISSION_GRANTED) {
8824            throw new SecurityException("Requires permission "
8825                    + android.Manifest.permission.FILTER_EVENTS);
8826        }
8827
8828        final String annotation;
8829        if (reason == null) {
8830            annotation = "Input dispatching timed out";
8831        } else {
8832            annotation = "Input dispatching timed out (" + reason + ")";
8833        }
8834
8835        if (proc != null) {
8836            synchronized (this) {
8837                if (proc.debugging) {
8838                    return false;
8839                }
8840
8841                if (mDidDexOpt) {
8842                    // Give more time since we were dexopting.
8843                    mDidDexOpt = false;
8844                    return false;
8845                }
8846
8847                if (proc.instrumentationClass != null) {
8848                    Bundle info = new Bundle();
8849                    info.putString("shortMsg", "keyDispatchingTimedOut");
8850                    info.putString("longMsg", annotation);
8851                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8852                    return true;
8853                }
8854            }
8855            mHandler.post(new Runnable() {
8856                @Override
8857                public void run() {
8858                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8859                }
8860            });
8861        }
8862
8863        return true;
8864    }
8865
8866    public Bundle getAssistContextExtras(int requestType) {
8867        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8868                "getAssistContextExtras()");
8869        PendingAssistExtras pae;
8870        Bundle extras = new Bundle();
8871        synchronized (this) {
8872            ActivityRecord activity = getFocusedStack().mResumedActivity;
8873            if (activity == null) {
8874                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8875                return null;
8876            }
8877            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8878            if (activity.app == null || activity.app.thread == null) {
8879                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8880                return extras;
8881            }
8882            if (activity.app.pid == Binder.getCallingPid()) {
8883                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8884                return extras;
8885            }
8886            pae = new PendingAssistExtras(activity);
8887            try {
8888                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8889                        requestType);
8890                mPendingAssistExtras.add(pae);
8891                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8892            } catch (RemoteException e) {
8893                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8894                return extras;
8895            }
8896        }
8897        synchronized (pae) {
8898            while (!pae.haveResult) {
8899                try {
8900                    pae.wait();
8901                } catch (InterruptedException e) {
8902                }
8903            }
8904            if (pae.result != null) {
8905                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8906            }
8907        }
8908        synchronized (this) {
8909            mPendingAssistExtras.remove(pae);
8910            mHandler.removeCallbacks(pae);
8911        }
8912        return extras;
8913    }
8914
8915    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8916        PendingAssistExtras pae = (PendingAssistExtras)token;
8917        synchronized (pae) {
8918            pae.result = extras;
8919            pae.haveResult = true;
8920            pae.notifyAll();
8921        }
8922    }
8923
8924    public void registerProcessObserver(IProcessObserver observer) {
8925        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8926                "registerProcessObserver()");
8927        synchronized (this) {
8928            mProcessObservers.register(observer);
8929        }
8930    }
8931
8932    @Override
8933    public void unregisterProcessObserver(IProcessObserver observer) {
8934        synchronized (this) {
8935            mProcessObservers.unregister(observer);
8936        }
8937    }
8938
8939    @Override
8940    public boolean convertFromTranslucent(IBinder token) {
8941        final long origId = Binder.clearCallingIdentity();
8942        try {
8943            synchronized (this) {
8944                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8945                if (r == null) {
8946                    return false;
8947                }
8948                if (r.changeWindowTranslucency(true)) {
8949                    mWindowManager.setAppFullscreen(token, true);
8950                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8951                    return true;
8952                }
8953                return false;
8954            }
8955        } finally {
8956            Binder.restoreCallingIdentity(origId);
8957        }
8958    }
8959
8960    @Override
8961    public boolean convertToTranslucent(IBinder token) {
8962        final long origId = Binder.clearCallingIdentity();
8963        try {
8964            synchronized (this) {
8965                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8966                if (r == null) {
8967                    return false;
8968                }
8969                if (r.changeWindowTranslucency(false)) {
8970                    r.task.stack.convertToTranslucent(r);
8971                    mWindowManager.setAppFullscreen(token, false);
8972                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8973                    return true;
8974                }
8975                return false;
8976            }
8977        } finally {
8978            Binder.restoreCallingIdentity(origId);
8979        }
8980    }
8981
8982    @Override
8983    public void setImmersive(IBinder token, boolean immersive) {
8984        synchronized(this) {
8985            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8986            if (r == null) {
8987                throw new IllegalArgumentException();
8988            }
8989            r.immersive = immersive;
8990
8991            // update associated state if we're frontmost
8992            if (r == mFocusedActivity) {
8993                if (DEBUG_IMMERSIVE) {
8994                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8995                }
8996                applyUpdateLockStateLocked(r);
8997            }
8998        }
8999    }
9000
9001    @Override
9002    public boolean isImmersive(IBinder token) {
9003        synchronized (this) {
9004            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9005            if (r == null) {
9006                throw new IllegalArgumentException();
9007            }
9008            return r.immersive;
9009        }
9010    }
9011
9012    public boolean isTopActivityImmersive() {
9013        enforceNotIsolatedCaller("startActivity");
9014        synchronized (this) {
9015            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9016            return (r != null) ? r.immersive : false;
9017        }
9018    }
9019
9020    public final void enterSafeMode() {
9021        synchronized(this) {
9022            // It only makes sense to do this before the system is ready
9023            // and started launching other packages.
9024            if (!mSystemReady) {
9025                try {
9026                    AppGlobals.getPackageManager().enterSafeMode();
9027                } catch (RemoteException e) {
9028                }
9029            }
9030
9031            mSafeMode = true;
9032        }
9033    }
9034
9035    public final void showSafeModeOverlay() {
9036        View v = LayoutInflater.from(mContext).inflate(
9037                com.android.internal.R.layout.safe_mode, null);
9038        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9039        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9040        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9041        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9042        lp.gravity = Gravity.BOTTOM | Gravity.START;
9043        lp.format = v.getBackground().getOpacity();
9044        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9045                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9046        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9047        ((WindowManager)mContext.getSystemService(
9048                Context.WINDOW_SERVICE)).addView(v, lp);
9049    }
9050
9051    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9052        if (!(sender instanceof PendingIntentRecord)) {
9053            return;
9054        }
9055        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9056        synchronized (stats) {
9057            if (mBatteryStatsService.isOnBattery()) {
9058                mBatteryStatsService.enforceCallingPermission();
9059                PendingIntentRecord rec = (PendingIntentRecord)sender;
9060                int MY_UID = Binder.getCallingUid();
9061                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9062                BatteryStatsImpl.Uid.Pkg pkg =
9063                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9064                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9065                pkg.incWakeupsLocked();
9066            }
9067        }
9068    }
9069
9070    public boolean killPids(int[] pids, String pReason, boolean secure) {
9071        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9072            throw new SecurityException("killPids only available to the system");
9073        }
9074        String reason = (pReason == null) ? "Unknown" : pReason;
9075        // XXX Note: don't acquire main activity lock here, because the window
9076        // manager calls in with its locks held.
9077
9078        boolean killed = false;
9079        synchronized (mPidsSelfLocked) {
9080            int[] types = new int[pids.length];
9081            int worstType = 0;
9082            for (int i=0; i<pids.length; i++) {
9083                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9084                if (proc != null) {
9085                    int type = proc.setAdj;
9086                    types[i] = type;
9087                    if (type > worstType) {
9088                        worstType = type;
9089                    }
9090                }
9091            }
9092
9093            // If the worst oom_adj is somewhere in the cached proc LRU range,
9094            // then constrain it so we will kill all cached procs.
9095            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9096                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9097                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9098            }
9099
9100            // If this is not a secure call, don't let it kill processes that
9101            // are important.
9102            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9103                worstType = ProcessList.SERVICE_ADJ;
9104            }
9105
9106            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9107            for (int i=0; i<pids.length; i++) {
9108                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9109                if (proc == null) {
9110                    continue;
9111                }
9112                int adj = proc.setAdj;
9113                if (adj >= worstType && !proc.killedByAm) {
9114                    killUnneededProcessLocked(proc, reason);
9115                    killed = true;
9116                }
9117            }
9118        }
9119        return killed;
9120    }
9121
9122    @Override
9123    public void killUid(int uid, String reason) {
9124        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9125            throw new SecurityException("killUid only available to the system");
9126        }
9127        synchronized (this) {
9128            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9129                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9130                    reason != null ? reason : "kill uid");
9131        }
9132    }
9133
9134    @Override
9135    public boolean killProcessesBelowForeground(String reason) {
9136        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9137            throw new SecurityException("killProcessesBelowForeground() only available to system");
9138        }
9139
9140        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9141    }
9142
9143    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9144        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9145            throw new SecurityException("killProcessesBelowAdj() only available to system");
9146        }
9147
9148        boolean killed = false;
9149        synchronized (mPidsSelfLocked) {
9150            final int size = mPidsSelfLocked.size();
9151            for (int i = 0; i < size; i++) {
9152                final int pid = mPidsSelfLocked.keyAt(i);
9153                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9154                if (proc == null) continue;
9155
9156                final int adj = proc.setAdj;
9157                if (adj > belowAdj && !proc.killedByAm) {
9158                    killUnneededProcessLocked(proc, reason);
9159                    killed = true;
9160                }
9161            }
9162        }
9163        return killed;
9164    }
9165
9166    @Override
9167    public void hang(final IBinder who, boolean allowRestart) {
9168        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9169                != PackageManager.PERMISSION_GRANTED) {
9170            throw new SecurityException("Requires permission "
9171                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9172        }
9173
9174        final IBinder.DeathRecipient death = new DeathRecipient() {
9175            @Override
9176            public void binderDied() {
9177                synchronized (this) {
9178                    notifyAll();
9179                }
9180            }
9181        };
9182
9183        try {
9184            who.linkToDeath(death, 0);
9185        } catch (RemoteException e) {
9186            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9187            return;
9188        }
9189
9190        synchronized (this) {
9191            Watchdog.getInstance().setAllowRestart(allowRestart);
9192            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9193            synchronized (death) {
9194                while (who.isBinderAlive()) {
9195                    try {
9196                        death.wait();
9197                    } catch (InterruptedException e) {
9198                    }
9199                }
9200            }
9201            Watchdog.getInstance().setAllowRestart(true);
9202        }
9203    }
9204
9205    @Override
9206    public void restart() {
9207        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9208                != PackageManager.PERMISSION_GRANTED) {
9209            throw new SecurityException("Requires permission "
9210                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9211        }
9212
9213        Log.i(TAG, "Sending shutdown broadcast...");
9214
9215        BroadcastReceiver br = new BroadcastReceiver() {
9216            @Override public void onReceive(Context context, Intent intent) {
9217                // Now the broadcast is done, finish up the low-level shutdown.
9218                Log.i(TAG, "Shutting down activity manager...");
9219                shutdown(10000);
9220                Log.i(TAG, "Shutdown complete, restarting!");
9221                Process.killProcess(Process.myPid());
9222                System.exit(10);
9223            }
9224        };
9225
9226        // First send the high-level shut down broadcast.
9227        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9228        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9229        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9230        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9231        mContext.sendOrderedBroadcastAsUser(intent,
9232                UserHandle.ALL, null, br, mHandler, 0, null, null);
9233        */
9234        br.onReceive(mContext, intent);
9235    }
9236
9237    private long getLowRamTimeSinceIdle(long now) {
9238        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9239    }
9240
9241    @Override
9242    public void performIdleMaintenance() {
9243        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9244                != PackageManager.PERMISSION_GRANTED) {
9245            throw new SecurityException("Requires permission "
9246                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9247        }
9248
9249        synchronized (this) {
9250            final long now = SystemClock.uptimeMillis();
9251            final long timeSinceLastIdle = now - mLastIdleTime;
9252            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9253            mLastIdleTime = now;
9254            mLowRamTimeSinceLastIdle = 0;
9255            if (mLowRamStartTime != 0) {
9256                mLowRamStartTime = now;
9257            }
9258
9259            StringBuilder sb = new StringBuilder(128);
9260            sb.append("Idle maintenance over ");
9261            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9262            sb.append(" low RAM for ");
9263            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9264            Slog.i(TAG, sb.toString());
9265
9266            // If at least 1/3 of our time since the last idle period has been spent
9267            // with RAM low, then we want to kill processes.
9268            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9269
9270            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9271                ProcessRecord proc = mLruProcesses.get(i);
9272                if (proc.notCachedSinceIdle) {
9273                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9274                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9275                        if (doKilling && proc.initialIdlePss != 0
9276                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9277                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9278                                    + " from " + proc.initialIdlePss + ")");
9279                        }
9280                    }
9281                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9282                    proc.notCachedSinceIdle = true;
9283                    proc.initialIdlePss = 0;
9284                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9285                            mSleeping, now);
9286                }
9287            }
9288
9289            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9290            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9291        }
9292    }
9293
9294    private void retrieveSettings() {
9295        final ContentResolver resolver = mContext.getContentResolver();
9296        String debugApp = Settings.Global.getString(
9297            resolver, Settings.Global.DEBUG_APP);
9298        boolean waitForDebugger = Settings.Global.getInt(
9299            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9300        boolean alwaysFinishActivities = Settings.Global.getInt(
9301            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9302        boolean forceRtl = Settings.Global.getInt(
9303                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9304        // Transfer any global setting for forcing RTL layout, into a System Property
9305        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9306
9307        Configuration configuration = new Configuration();
9308        Settings.System.getConfiguration(resolver, configuration);
9309        if (forceRtl) {
9310            // This will take care of setting the correct layout direction flags
9311            configuration.setLayoutDirection(configuration.locale);
9312        }
9313
9314        synchronized (this) {
9315            mDebugApp = mOrigDebugApp = debugApp;
9316            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9317            mAlwaysFinishActivities = alwaysFinishActivities;
9318            // This happens before any activities are started, so we can
9319            // change mConfiguration in-place.
9320            updateConfigurationLocked(configuration, null, false, true);
9321            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9322        }
9323    }
9324
9325    public boolean testIsSystemReady() {
9326        // no need to synchronize(this) just to read & return the value
9327        return mSystemReady;
9328    }
9329
9330    private static File getCalledPreBootReceiversFile() {
9331        File dataDir = Environment.getDataDirectory();
9332        File systemDir = new File(dataDir, "system");
9333        File fname = new File(systemDir, "called_pre_boots.dat");
9334        return fname;
9335    }
9336
9337    static final int LAST_DONE_VERSION = 10000;
9338
9339    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9340        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9341        File file = getCalledPreBootReceiversFile();
9342        FileInputStream fis = null;
9343        try {
9344            fis = new FileInputStream(file);
9345            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9346            int fvers = dis.readInt();
9347            if (fvers == LAST_DONE_VERSION) {
9348                String vers = dis.readUTF();
9349                String codename = dis.readUTF();
9350                String build = dis.readUTF();
9351                if (android.os.Build.VERSION.RELEASE.equals(vers)
9352                        && android.os.Build.VERSION.CODENAME.equals(codename)
9353                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9354                    int num = dis.readInt();
9355                    while (num > 0) {
9356                        num--;
9357                        String pkg = dis.readUTF();
9358                        String cls = dis.readUTF();
9359                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9360                    }
9361                }
9362            }
9363        } catch (FileNotFoundException e) {
9364        } catch (IOException e) {
9365            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9366        } finally {
9367            if (fis != null) {
9368                try {
9369                    fis.close();
9370                } catch (IOException e) {
9371                }
9372            }
9373        }
9374        return lastDoneReceivers;
9375    }
9376
9377    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9378        File file = getCalledPreBootReceiversFile();
9379        FileOutputStream fos = null;
9380        DataOutputStream dos = null;
9381        try {
9382            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9383            fos = new FileOutputStream(file);
9384            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9385            dos.writeInt(LAST_DONE_VERSION);
9386            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9387            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9388            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9389            dos.writeInt(list.size());
9390            for (int i=0; i<list.size(); i++) {
9391                dos.writeUTF(list.get(i).getPackageName());
9392                dos.writeUTF(list.get(i).getClassName());
9393            }
9394        } catch (IOException e) {
9395            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9396            file.delete();
9397        } finally {
9398            FileUtils.sync(fos);
9399            if (dos != null) {
9400                try {
9401                    dos.close();
9402                } catch (IOException e) {
9403                    // TODO Auto-generated catch block
9404                    e.printStackTrace();
9405                }
9406            }
9407        }
9408    }
9409
9410    public void systemReady(final Runnable goingCallback) {
9411        synchronized(this) {
9412            if (mSystemReady) {
9413                if (goingCallback != null) goingCallback.run();
9414                return;
9415            }
9416
9417            // Check to see if there are any update receivers to run.
9418            if (!mDidUpdate) {
9419                if (mWaitingUpdate) {
9420                    return;
9421                }
9422                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9423                List<ResolveInfo> ris = null;
9424                try {
9425                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9426                            intent, null, 0, 0);
9427                } catch (RemoteException e) {
9428                }
9429                if (ris != null) {
9430                    for (int i=ris.size()-1; i>=0; i--) {
9431                        if ((ris.get(i).activityInfo.applicationInfo.flags
9432                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9433                            ris.remove(i);
9434                        }
9435                    }
9436                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9437
9438                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9439
9440                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9441                    for (int i=0; i<ris.size(); i++) {
9442                        ActivityInfo ai = ris.get(i).activityInfo;
9443                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9444                        if (lastDoneReceivers.contains(comp)) {
9445                            // We already did the pre boot receiver for this app with the current
9446                            // platform version, so don't do it again...
9447                            ris.remove(i);
9448                            i--;
9449                            // ...however, do keep it as one that has been done, so we don't
9450                            // forget about it when rewriting the file of last done receivers.
9451                            doneReceivers.add(comp);
9452                        }
9453                    }
9454
9455                    final int[] users = getUsersLocked();
9456                    for (int i=0; i<ris.size(); i++) {
9457                        ActivityInfo ai = ris.get(i).activityInfo;
9458                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9459                        doneReceivers.add(comp);
9460                        intent.setComponent(comp);
9461                        for (int j=0; j<users.length; j++) {
9462                            IIntentReceiver finisher = null;
9463                            if (i == ris.size()-1 && j == users.length-1) {
9464                                finisher = new IIntentReceiver.Stub() {
9465                                    public void performReceive(Intent intent, int resultCode,
9466                                            String data, Bundle extras, boolean ordered,
9467                                            boolean sticky, int sendingUser) {
9468                                        // The raw IIntentReceiver interface is called
9469                                        // with the AM lock held, so redispatch to
9470                                        // execute our code without the lock.
9471                                        mHandler.post(new Runnable() {
9472                                            public void run() {
9473                                                synchronized (ActivityManagerService.this) {
9474                                                    mDidUpdate = true;
9475                                                }
9476                                                writeLastDonePreBootReceivers(doneReceivers);
9477                                                showBootMessage(mContext.getText(
9478                                                        R.string.android_upgrading_complete),
9479                                                        false);
9480                                                systemReady(goingCallback);
9481                                            }
9482                                        });
9483                                    }
9484                                };
9485                            }
9486                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9487                                    + " for user " + users[j]);
9488                            broadcastIntentLocked(null, null, intent, null, finisher,
9489                                    0, null, null, null, AppOpsManager.OP_NONE,
9490                                    true, false, MY_PID, Process.SYSTEM_UID,
9491                                    users[j]);
9492                            if (finisher != null) {
9493                                mWaitingUpdate = true;
9494                            }
9495                        }
9496                    }
9497                }
9498                if (mWaitingUpdate) {
9499                    return;
9500                }
9501                mDidUpdate = true;
9502            }
9503
9504            mAppOpsService.systemReady();
9505            mSystemReady = true;
9506        }
9507
9508        ArrayList<ProcessRecord> procsToKill = null;
9509        synchronized(mPidsSelfLocked) {
9510            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9511                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9512                if (!isAllowedWhileBooting(proc.info)){
9513                    if (procsToKill == null) {
9514                        procsToKill = new ArrayList<ProcessRecord>();
9515                    }
9516                    procsToKill.add(proc);
9517                }
9518            }
9519        }
9520
9521        synchronized(this) {
9522            if (procsToKill != null) {
9523                for (int i=procsToKill.size()-1; i>=0; i--) {
9524                    ProcessRecord proc = procsToKill.get(i);
9525                    Slog.i(TAG, "Removing system update proc: " + proc);
9526                    removeProcessLocked(proc, true, false, "system update done");
9527                }
9528            }
9529
9530            // Now that we have cleaned up any update processes, we
9531            // are ready to start launching real processes and know that
9532            // we won't trample on them any more.
9533            mProcessesReady = true;
9534        }
9535
9536        Slog.i(TAG, "System now ready");
9537        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9538            SystemClock.uptimeMillis());
9539
9540        synchronized(this) {
9541            // Make sure we have no pre-ready processes sitting around.
9542
9543            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9544                ResolveInfo ri = mContext.getPackageManager()
9545                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9546                                STOCK_PM_FLAGS);
9547                CharSequence errorMsg = null;
9548                if (ri != null) {
9549                    ActivityInfo ai = ri.activityInfo;
9550                    ApplicationInfo app = ai.applicationInfo;
9551                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9552                        mTopAction = Intent.ACTION_FACTORY_TEST;
9553                        mTopData = null;
9554                        mTopComponent = new ComponentName(app.packageName,
9555                                ai.name);
9556                    } else {
9557                        errorMsg = mContext.getResources().getText(
9558                                com.android.internal.R.string.factorytest_not_system);
9559                    }
9560                } else {
9561                    errorMsg = mContext.getResources().getText(
9562                            com.android.internal.R.string.factorytest_no_action);
9563                }
9564                if (errorMsg != null) {
9565                    mTopAction = null;
9566                    mTopData = null;
9567                    mTopComponent = null;
9568                    Message msg = Message.obtain();
9569                    msg.what = SHOW_FACTORY_ERROR_MSG;
9570                    msg.getData().putCharSequence("msg", errorMsg);
9571                    mHandler.sendMessage(msg);
9572                }
9573            }
9574        }
9575
9576        retrieveSettings();
9577
9578        synchronized (this) {
9579            readGrantedUriPermissionsLocked();
9580        }
9581
9582        if (goingCallback != null) goingCallback.run();
9583
9584        synchronized (this) {
9585            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9586                try {
9587                    List apps = AppGlobals.getPackageManager().
9588                        getPersistentApplications(STOCK_PM_FLAGS);
9589                    if (apps != null) {
9590                        int N = apps.size();
9591                        int i;
9592                        for (i=0; i<N; i++) {
9593                            ApplicationInfo info
9594                                = (ApplicationInfo)apps.get(i);
9595                            if (info != null &&
9596                                    !info.packageName.equals("android")) {
9597                                addAppLocked(info, false);
9598                            }
9599                        }
9600                    }
9601                } catch (RemoteException ex) {
9602                    // pm is in same process, this will never happen.
9603                }
9604            }
9605
9606            // Start up initial activity.
9607            mBooting = true;
9608
9609            try {
9610                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9611                    Message msg = Message.obtain();
9612                    msg.what = SHOW_UID_ERROR_MSG;
9613                    mHandler.sendMessage(msg);
9614                }
9615            } catch (RemoteException e) {
9616            }
9617
9618            long ident = Binder.clearCallingIdentity();
9619            try {
9620                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9621                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9622                        | Intent.FLAG_RECEIVER_FOREGROUND);
9623                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9624                broadcastIntentLocked(null, null, intent,
9625                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9626                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9627                intent = new Intent(Intent.ACTION_USER_STARTING);
9628                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9629                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9630                broadcastIntentLocked(null, null, intent,
9631                        null, new IIntentReceiver.Stub() {
9632                            @Override
9633                            public void performReceive(Intent intent, int resultCode, String data,
9634                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9635                                    throws RemoteException {
9636                            }
9637                        }, 0, null, null,
9638                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9639                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9640            } finally {
9641                Binder.restoreCallingIdentity(ident);
9642            }
9643            mStackSupervisor.resumeTopActivitiesLocked();
9644            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9645        }
9646    }
9647
9648    private boolean makeAppCrashingLocked(ProcessRecord app,
9649            String shortMsg, String longMsg, String stackTrace) {
9650        app.crashing = true;
9651        app.crashingReport = generateProcessError(app,
9652                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9653        startAppProblemLocked(app);
9654        app.stopFreezingAllLocked();
9655        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9656    }
9657
9658    private void makeAppNotRespondingLocked(ProcessRecord app,
9659            String activity, String shortMsg, String longMsg) {
9660        app.notResponding = true;
9661        app.notRespondingReport = generateProcessError(app,
9662                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9663                activity, shortMsg, longMsg, null);
9664        startAppProblemLocked(app);
9665        app.stopFreezingAllLocked();
9666    }
9667
9668    /**
9669     * Generate a process error record, suitable for attachment to a ProcessRecord.
9670     *
9671     * @param app The ProcessRecord in which the error occurred.
9672     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9673     *                      ActivityManager.AppErrorStateInfo
9674     * @param activity The activity associated with the crash, if known.
9675     * @param shortMsg Short message describing the crash.
9676     * @param longMsg Long message describing the crash.
9677     * @param stackTrace Full crash stack trace, may be null.
9678     *
9679     * @return Returns a fully-formed AppErrorStateInfo record.
9680     */
9681    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9682            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9683        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9684
9685        report.condition = condition;
9686        report.processName = app.processName;
9687        report.pid = app.pid;
9688        report.uid = app.info.uid;
9689        report.tag = activity;
9690        report.shortMsg = shortMsg;
9691        report.longMsg = longMsg;
9692        report.stackTrace = stackTrace;
9693
9694        return report;
9695    }
9696
9697    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9698        synchronized (this) {
9699            app.crashing = false;
9700            app.crashingReport = null;
9701            app.notResponding = false;
9702            app.notRespondingReport = null;
9703            if (app.anrDialog == fromDialog) {
9704                app.anrDialog = null;
9705            }
9706            if (app.waitDialog == fromDialog) {
9707                app.waitDialog = null;
9708            }
9709            if (app.pid > 0 && app.pid != MY_PID) {
9710                handleAppCrashLocked(app, null, null, null);
9711                killUnneededProcessLocked(app, "user request after error");
9712            }
9713        }
9714    }
9715
9716    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9717            String stackTrace) {
9718        long now = SystemClock.uptimeMillis();
9719
9720        Long crashTime;
9721        if (!app.isolated) {
9722            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9723        } else {
9724            crashTime = null;
9725        }
9726        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9727            // This process loses!
9728            Slog.w(TAG, "Process " + app.info.processName
9729                    + " has crashed too many times: killing!");
9730            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9731                    app.userId, app.info.processName, app.uid);
9732            mStackSupervisor.handleAppCrashLocked(app);
9733            if (!app.persistent) {
9734                // We don't want to start this process again until the user
9735                // explicitly does so...  but for persistent process, we really
9736                // need to keep it running.  If a persistent process is actually
9737                // repeatedly crashing, then badness for everyone.
9738                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9739                        app.info.processName);
9740                if (!app.isolated) {
9741                    // XXX We don't have a way to mark isolated processes
9742                    // as bad, since they don't have a peristent identity.
9743                    mBadProcesses.put(app.info.processName, app.uid,
9744                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9745                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9746                }
9747                app.bad = true;
9748                app.removed = true;
9749                // Don't let services in this process be restarted and potentially
9750                // annoy the user repeatedly.  Unless it is persistent, since those
9751                // processes run critical code.
9752                removeProcessLocked(app, false, false, "crash");
9753                mStackSupervisor.resumeTopActivitiesLocked();
9754                return false;
9755            }
9756            mStackSupervisor.resumeTopActivitiesLocked();
9757        } else {
9758            mStackSupervisor.finishTopRunningActivityLocked(app);
9759        }
9760
9761        // Bump up the crash count of any services currently running in the proc.
9762        for (int i=app.services.size()-1; i>=0; i--) {
9763            // Any services running in the application need to be placed
9764            // back in the pending list.
9765            ServiceRecord sr = app.services.valueAt(i);
9766            sr.crashCount++;
9767        }
9768
9769        // If the crashing process is what we consider to be the "home process" and it has been
9770        // replaced by a third-party app, clear the package preferred activities from packages
9771        // with a home activity running in the process to prevent a repeatedly crashing app
9772        // from blocking the user to manually clear the list.
9773        final ArrayList<ActivityRecord> activities = app.activities;
9774        if (app == mHomeProcess && activities.size() > 0
9775                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9776            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9777                final ActivityRecord r = activities.get(activityNdx);
9778                if (r.isHomeActivity()) {
9779                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9780                    try {
9781                        ActivityThread.getPackageManager()
9782                                .clearPackagePreferredActivities(r.packageName);
9783                    } catch (RemoteException c) {
9784                        // pm is in same process, this will never happen.
9785                    }
9786                }
9787            }
9788        }
9789
9790        if (!app.isolated) {
9791            // XXX Can't keep track of crash times for isolated processes,
9792            // because they don't have a perisistent identity.
9793            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9794        }
9795
9796        return true;
9797    }
9798
9799    void startAppProblemLocked(ProcessRecord app) {
9800        if (app.userId == mCurrentUserId) {
9801            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9802                    mContext, app.info.packageName, app.info.flags);
9803        } else {
9804            // If this app is not running under the current user, then we
9805            // can't give it a report button because that would require
9806            // launching the report UI under a different user.
9807            app.errorReportReceiver = null;
9808        }
9809        skipCurrentReceiverLocked(app);
9810    }
9811
9812    void skipCurrentReceiverLocked(ProcessRecord app) {
9813        for (BroadcastQueue queue : mBroadcastQueues) {
9814            queue.skipCurrentReceiverLocked(app);
9815        }
9816    }
9817
9818    /**
9819     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9820     * The application process will exit immediately after this call returns.
9821     * @param app object of the crashing app, null for the system server
9822     * @param crashInfo describing the exception
9823     */
9824    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9825        ProcessRecord r = findAppProcess(app, "Crash");
9826        final String processName = app == null ? "system_server"
9827                : (r == null ? "unknown" : r.processName);
9828
9829        handleApplicationCrashInner("crash", r, processName, crashInfo);
9830    }
9831
9832    /* Native crash reporting uses this inner version because it needs to be somewhat
9833     * decoupled from the AM-managed cleanup lifecycle
9834     */
9835    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9836            ApplicationErrorReport.CrashInfo crashInfo) {
9837        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9838                UserHandle.getUserId(Binder.getCallingUid()), processName,
9839                r == null ? -1 : r.info.flags,
9840                crashInfo.exceptionClassName,
9841                crashInfo.exceptionMessage,
9842                crashInfo.throwFileName,
9843                crashInfo.throwLineNumber);
9844
9845        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9846
9847        crashApplication(r, crashInfo);
9848    }
9849
9850    public void handleApplicationStrictModeViolation(
9851            IBinder app,
9852            int violationMask,
9853            StrictMode.ViolationInfo info) {
9854        ProcessRecord r = findAppProcess(app, "StrictMode");
9855        if (r == null) {
9856            return;
9857        }
9858
9859        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9860            Integer stackFingerprint = info.hashCode();
9861            boolean logIt = true;
9862            synchronized (mAlreadyLoggedViolatedStacks) {
9863                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9864                    logIt = false;
9865                    // TODO: sub-sample into EventLog for these, with
9866                    // the info.durationMillis?  Then we'd get
9867                    // the relative pain numbers, without logging all
9868                    // the stack traces repeatedly.  We'd want to do
9869                    // likewise in the client code, which also does
9870                    // dup suppression, before the Binder call.
9871                } else {
9872                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9873                        mAlreadyLoggedViolatedStacks.clear();
9874                    }
9875                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9876                }
9877            }
9878            if (logIt) {
9879                logStrictModeViolationToDropBox(r, info);
9880            }
9881        }
9882
9883        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9884            AppErrorResult result = new AppErrorResult();
9885            synchronized (this) {
9886                final long origId = Binder.clearCallingIdentity();
9887
9888                Message msg = Message.obtain();
9889                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9890                HashMap<String, Object> data = new HashMap<String, Object>();
9891                data.put("result", result);
9892                data.put("app", r);
9893                data.put("violationMask", violationMask);
9894                data.put("info", info);
9895                msg.obj = data;
9896                mHandler.sendMessage(msg);
9897
9898                Binder.restoreCallingIdentity(origId);
9899            }
9900            int res = result.get();
9901            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9902        }
9903    }
9904
9905    // Depending on the policy in effect, there could be a bunch of
9906    // these in quick succession so we try to batch these together to
9907    // minimize disk writes, number of dropbox entries, and maximize
9908    // compression, by having more fewer, larger records.
9909    private void logStrictModeViolationToDropBox(
9910            ProcessRecord process,
9911            StrictMode.ViolationInfo info) {
9912        if (info == null) {
9913            return;
9914        }
9915        final boolean isSystemApp = process == null ||
9916                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9917                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9918        final String processName = process == null ? "unknown" : process.processName;
9919        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9920        final DropBoxManager dbox = (DropBoxManager)
9921                mContext.getSystemService(Context.DROPBOX_SERVICE);
9922
9923        // Exit early if the dropbox isn't configured to accept this report type.
9924        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9925
9926        boolean bufferWasEmpty;
9927        boolean needsFlush;
9928        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9929        synchronized (sb) {
9930            bufferWasEmpty = sb.length() == 0;
9931            appendDropBoxProcessHeaders(process, processName, sb);
9932            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9933            sb.append("System-App: ").append(isSystemApp).append("\n");
9934            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9935            if (info.violationNumThisLoop != 0) {
9936                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9937            }
9938            if (info.numAnimationsRunning != 0) {
9939                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9940            }
9941            if (info.broadcastIntentAction != null) {
9942                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9943            }
9944            if (info.durationMillis != -1) {
9945                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9946            }
9947            if (info.numInstances != -1) {
9948                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9949            }
9950            if (info.tags != null) {
9951                for (String tag : info.tags) {
9952                    sb.append("Span-Tag: ").append(tag).append("\n");
9953                }
9954            }
9955            sb.append("\n");
9956            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9957                sb.append(info.crashInfo.stackTrace);
9958            }
9959            sb.append("\n");
9960
9961            // Only buffer up to ~64k.  Various logging bits truncate
9962            // things at 128k.
9963            needsFlush = (sb.length() > 64 * 1024);
9964        }
9965
9966        // Flush immediately if the buffer's grown too large, or this
9967        // is a non-system app.  Non-system apps are isolated with a
9968        // different tag & policy and not batched.
9969        //
9970        // Batching is useful during internal testing with
9971        // StrictMode settings turned up high.  Without batching,
9972        // thousands of separate files could be created on boot.
9973        if (!isSystemApp || needsFlush) {
9974            new Thread("Error dump: " + dropboxTag) {
9975                @Override
9976                public void run() {
9977                    String report;
9978                    synchronized (sb) {
9979                        report = sb.toString();
9980                        sb.delete(0, sb.length());
9981                        sb.trimToSize();
9982                    }
9983                    if (report.length() != 0) {
9984                        dbox.addText(dropboxTag, report);
9985                    }
9986                }
9987            }.start();
9988            return;
9989        }
9990
9991        // System app batching:
9992        if (!bufferWasEmpty) {
9993            // An existing dropbox-writing thread is outstanding, so
9994            // we don't need to start it up.  The existing thread will
9995            // catch the buffer appends we just did.
9996            return;
9997        }
9998
9999        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10000        // (After this point, we shouldn't access AMS internal data structures.)
10001        new Thread("Error dump: " + dropboxTag) {
10002            @Override
10003            public void run() {
10004                // 5 second sleep to let stacks arrive and be batched together
10005                try {
10006                    Thread.sleep(5000);  // 5 seconds
10007                } catch (InterruptedException e) {}
10008
10009                String errorReport;
10010                synchronized (mStrictModeBuffer) {
10011                    errorReport = mStrictModeBuffer.toString();
10012                    if (errorReport.length() == 0) {
10013                        return;
10014                    }
10015                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10016                    mStrictModeBuffer.trimToSize();
10017                }
10018                dbox.addText(dropboxTag, errorReport);
10019            }
10020        }.start();
10021    }
10022
10023    /**
10024     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10025     * @param app object of the crashing app, null for the system server
10026     * @param tag reported by the caller
10027     * @param crashInfo describing the context of the error
10028     * @return true if the process should exit immediately (WTF is fatal)
10029     */
10030    public boolean handleApplicationWtf(IBinder app, String tag,
10031            ApplicationErrorReport.CrashInfo crashInfo) {
10032        ProcessRecord r = findAppProcess(app, "WTF");
10033        final String processName = app == null ? "system_server"
10034                : (r == null ? "unknown" : r.processName);
10035
10036        EventLog.writeEvent(EventLogTags.AM_WTF,
10037                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10038                processName,
10039                r == null ? -1 : r.info.flags,
10040                tag, crashInfo.exceptionMessage);
10041
10042        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10043
10044        if (r != null && r.pid != Process.myPid() &&
10045                Settings.Global.getInt(mContext.getContentResolver(),
10046                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10047            crashApplication(r, crashInfo);
10048            return true;
10049        } else {
10050            return false;
10051        }
10052    }
10053
10054    /**
10055     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10056     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10057     */
10058    private ProcessRecord findAppProcess(IBinder app, String reason) {
10059        if (app == null) {
10060            return null;
10061        }
10062
10063        synchronized (this) {
10064            final int NP = mProcessNames.getMap().size();
10065            for (int ip=0; ip<NP; ip++) {
10066                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10067                final int NA = apps.size();
10068                for (int ia=0; ia<NA; ia++) {
10069                    ProcessRecord p = apps.valueAt(ia);
10070                    if (p.thread != null && p.thread.asBinder() == app) {
10071                        return p;
10072                    }
10073                }
10074            }
10075
10076            Slog.w(TAG, "Can't find mystery application for " + reason
10077                    + " from pid=" + Binder.getCallingPid()
10078                    + " uid=" + Binder.getCallingUid() + ": " + app);
10079            return null;
10080        }
10081    }
10082
10083    /**
10084     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10085     * to append various headers to the dropbox log text.
10086     */
10087    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10088            StringBuilder sb) {
10089        // Watchdog thread ends up invoking this function (with
10090        // a null ProcessRecord) to add the stack file to dropbox.
10091        // Do not acquire a lock on this (am) in such cases, as it
10092        // could cause a potential deadlock, if and when watchdog
10093        // is invoked due to unavailability of lock on am and it
10094        // would prevent watchdog from killing system_server.
10095        if (process == null) {
10096            sb.append("Process: ").append(processName).append("\n");
10097            return;
10098        }
10099        // Note: ProcessRecord 'process' is guarded by the service
10100        // instance.  (notably process.pkgList, which could otherwise change
10101        // concurrently during execution of this method)
10102        synchronized (this) {
10103            sb.append("Process: ").append(processName).append("\n");
10104            int flags = process.info.flags;
10105            IPackageManager pm = AppGlobals.getPackageManager();
10106            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10107            for (int ip=0; ip<process.pkgList.size(); ip++) {
10108                String pkg = process.pkgList.keyAt(ip);
10109                sb.append("Package: ").append(pkg);
10110                try {
10111                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10112                    if (pi != null) {
10113                        sb.append(" v").append(pi.versionCode);
10114                        if (pi.versionName != null) {
10115                            sb.append(" (").append(pi.versionName).append(")");
10116                        }
10117                    }
10118                } catch (RemoteException e) {
10119                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10120                }
10121                sb.append("\n");
10122            }
10123        }
10124    }
10125
10126    private static String processClass(ProcessRecord process) {
10127        if (process == null || process.pid == MY_PID) {
10128            return "system_server";
10129        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10130            return "system_app";
10131        } else {
10132            return "data_app";
10133        }
10134    }
10135
10136    /**
10137     * Write a description of an error (crash, WTF, ANR) to the drop box.
10138     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10139     * @param process which caused the error, null means the system server
10140     * @param activity which triggered the error, null if unknown
10141     * @param parent activity related to the error, null if unknown
10142     * @param subject line related to the error, null if absent
10143     * @param report in long form describing the error, null if absent
10144     * @param logFile to include in the report, null if none
10145     * @param crashInfo giving an application stack trace, null if absent
10146     */
10147    public void addErrorToDropBox(String eventType,
10148            ProcessRecord process, String processName, ActivityRecord activity,
10149            ActivityRecord parent, String subject,
10150            final String report, final File logFile,
10151            final ApplicationErrorReport.CrashInfo crashInfo) {
10152        // NOTE -- this must never acquire the ActivityManagerService lock,
10153        // otherwise the watchdog may be prevented from resetting the system.
10154
10155        final String dropboxTag = processClass(process) + "_" + eventType;
10156        final DropBoxManager dbox = (DropBoxManager)
10157                mContext.getSystemService(Context.DROPBOX_SERVICE);
10158
10159        // Exit early if the dropbox isn't configured to accept this report type.
10160        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10161
10162        final StringBuilder sb = new StringBuilder(1024);
10163        appendDropBoxProcessHeaders(process, processName, sb);
10164        if (activity != null) {
10165            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10166        }
10167        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10168            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10169        }
10170        if (parent != null && parent != activity) {
10171            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10172        }
10173        if (subject != null) {
10174            sb.append("Subject: ").append(subject).append("\n");
10175        }
10176        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10177        if (Debug.isDebuggerConnected()) {
10178            sb.append("Debugger: Connected\n");
10179        }
10180        sb.append("\n");
10181
10182        // Do the rest in a worker thread to avoid blocking the caller on I/O
10183        // (After this point, we shouldn't access AMS internal data structures.)
10184        Thread worker = new Thread("Error dump: " + dropboxTag) {
10185            @Override
10186            public void run() {
10187                if (report != null) {
10188                    sb.append(report);
10189                }
10190                if (logFile != null) {
10191                    try {
10192                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10193                                    "\n\n[[TRUNCATED]]"));
10194                    } catch (IOException e) {
10195                        Slog.e(TAG, "Error reading " + logFile, e);
10196                    }
10197                }
10198                if (crashInfo != null && crashInfo.stackTrace != null) {
10199                    sb.append(crashInfo.stackTrace);
10200                }
10201
10202                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10203                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10204                if (lines > 0) {
10205                    sb.append("\n");
10206
10207                    // Merge several logcat streams, and take the last N lines
10208                    InputStreamReader input = null;
10209                    try {
10210                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10211                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10212                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10213
10214                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10215                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10216                        input = new InputStreamReader(logcat.getInputStream());
10217
10218                        int num;
10219                        char[] buf = new char[8192];
10220                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10221                    } catch (IOException e) {
10222                        Slog.e(TAG, "Error running logcat", e);
10223                    } finally {
10224                        if (input != null) try { input.close(); } catch (IOException e) {}
10225                    }
10226                }
10227
10228                dbox.addText(dropboxTag, sb.toString());
10229            }
10230        };
10231
10232        if (process == null) {
10233            // If process is null, we are being called from some internal code
10234            // and may be about to die -- run this synchronously.
10235            worker.run();
10236        } else {
10237            worker.start();
10238        }
10239    }
10240
10241    /**
10242     * Bring up the "unexpected error" dialog box for a crashing app.
10243     * Deal with edge cases (intercepts from instrumented applications,
10244     * ActivityController, error intent receivers, that sort of thing).
10245     * @param r the application crashing
10246     * @param crashInfo describing the failure
10247     */
10248    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10249        long timeMillis = System.currentTimeMillis();
10250        String shortMsg = crashInfo.exceptionClassName;
10251        String longMsg = crashInfo.exceptionMessage;
10252        String stackTrace = crashInfo.stackTrace;
10253        if (shortMsg != null && longMsg != null) {
10254            longMsg = shortMsg + ": " + longMsg;
10255        } else if (shortMsg != null) {
10256            longMsg = shortMsg;
10257        }
10258
10259        AppErrorResult result = new AppErrorResult();
10260        synchronized (this) {
10261            if (mController != null) {
10262                try {
10263                    String name = r != null ? r.processName : null;
10264                    int pid = r != null ? r.pid : Binder.getCallingPid();
10265                    if (!mController.appCrashed(name, pid,
10266                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10267                        Slog.w(TAG, "Force-killing crashed app " + name
10268                                + " at watcher's request");
10269                        Process.killProcess(pid);
10270                        return;
10271                    }
10272                } catch (RemoteException e) {
10273                    mController = null;
10274                    Watchdog.getInstance().setActivityController(null);
10275                }
10276            }
10277
10278            final long origId = Binder.clearCallingIdentity();
10279
10280            // If this process is running instrumentation, finish it.
10281            if (r != null && r.instrumentationClass != null) {
10282                Slog.w(TAG, "Error in app " + r.processName
10283                      + " running instrumentation " + r.instrumentationClass + ":");
10284                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10285                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10286                Bundle info = new Bundle();
10287                info.putString("shortMsg", shortMsg);
10288                info.putString("longMsg", longMsg);
10289                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10290                Binder.restoreCallingIdentity(origId);
10291                return;
10292            }
10293
10294            // If we can't identify the process or it's already exceeded its crash quota,
10295            // quit right away without showing a crash dialog.
10296            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10297                Binder.restoreCallingIdentity(origId);
10298                return;
10299            }
10300
10301            Message msg = Message.obtain();
10302            msg.what = SHOW_ERROR_MSG;
10303            HashMap data = new HashMap();
10304            data.put("result", result);
10305            data.put("app", r);
10306            msg.obj = data;
10307            mHandler.sendMessage(msg);
10308
10309            Binder.restoreCallingIdentity(origId);
10310        }
10311
10312        int res = result.get();
10313
10314        Intent appErrorIntent = null;
10315        synchronized (this) {
10316            if (r != null && !r.isolated) {
10317                // XXX Can't keep track of crash time for isolated processes,
10318                // since they don't have a persistent identity.
10319                mProcessCrashTimes.put(r.info.processName, r.uid,
10320                        SystemClock.uptimeMillis());
10321            }
10322            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10323                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10324            }
10325        }
10326
10327        if (appErrorIntent != null) {
10328            try {
10329                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10330            } catch (ActivityNotFoundException e) {
10331                Slog.w(TAG, "bug report receiver dissappeared", e);
10332            }
10333        }
10334    }
10335
10336    Intent createAppErrorIntentLocked(ProcessRecord r,
10337            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10338        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10339        if (report == null) {
10340            return null;
10341        }
10342        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10343        result.setComponent(r.errorReportReceiver);
10344        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10345        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10346        return result;
10347    }
10348
10349    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10350            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10351        if (r.errorReportReceiver == null) {
10352            return null;
10353        }
10354
10355        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10356            return null;
10357        }
10358
10359        ApplicationErrorReport report = new ApplicationErrorReport();
10360        report.packageName = r.info.packageName;
10361        report.installerPackageName = r.errorReportReceiver.getPackageName();
10362        report.processName = r.processName;
10363        report.time = timeMillis;
10364        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10365
10366        if (r.crashing || r.forceCrashReport) {
10367            report.type = ApplicationErrorReport.TYPE_CRASH;
10368            report.crashInfo = crashInfo;
10369        } else if (r.notResponding) {
10370            report.type = ApplicationErrorReport.TYPE_ANR;
10371            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10372
10373            report.anrInfo.activity = r.notRespondingReport.tag;
10374            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10375            report.anrInfo.info = r.notRespondingReport.longMsg;
10376        }
10377
10378        return report;
10379    }
10380
10381    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10382        enforceNotIsolatedCaller("getProcessesInErrorState");
10383        // assume our apps are happy - lazy create the list
10384        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10385
10386        final boolean allUsers = ActivityManager.checkUidPermission(
10387                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10388                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10389        int userId = UserHandle.getUserId(Binder.getCallingUid());
10390
10391        synchronized (this) {
10392
10393            // iterate across all processes
10394            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10395                ProcessRecord app = mLruProcesses.get(i);
10396                if (!allUsers && app.userId != userId) {
10397                    continue;
10398                }
10399                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10400                    // This one's in trouble, so we'll generate a report for it
10401                    // crashes are higher priority (in case there's a crash *and* an anr)
10402                    ActivityManager.ProcessErrorStateInfo report = null;
10403                    if (app.crashing) {
10404                        report = app.crashingReport;
10405                    } else if (app.notResponding) {
10406                        report = app.notRespondingReport;
10407                    }
10408
10409                    if (report != null) {
10410                        if (errList == null) {
10411                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10412                        }
10413                        errList.add(report);
10414                    } else {
10415                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10416                                " crashing = " + app.crashing +
10417                                " notResponding = " + app.notResponding);
10418                    }
10419                }
10420            }
10421        }
10422
10423        return errList;
10424    }
10425
10426    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10427        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10428            if (currApp != null) {
10429                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10430            }
10431            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10432        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10433            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10434        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10435            if (currApp != null) {
10436                currApp.lru = 0;
10437            }
10438            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10439        } else if (adj >= ProcessList.SERVICE_ADJ) {
10440            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10441        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10442            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10443        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10444            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10445        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10446            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10447        } else {
10448            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10449        }
10450    }
10451
10452    private void fillInProcMemInfo(ProcessRecord app,
10453            ActivityManager.RunningAppProcessInfo outInfo) {
10454        outInfo.pid = app.pid;
10455        outInfo.uid = app.info.uid;
10456        if (mHeavyWeightProcess == app) {
10457            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10458        }
10459        if (app.persistent) {
10460            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10461        }
10462        if (app.activities.size() > 0) {
10463            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10464        }
10465        outInfo.lastTrimLevel = app.trimMemoryLevel;
10466        int adj = app.curAdj;
10467        outInfo.importance = oomAdjToImportance(adj, outInfo);
10468        outInfo.importanceReasonCode = app.adjTypeCode;
10469    }
10470
10471    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10472        enforceNotIsolatedCaller("getRunningAppProcesses");
10473        // Lazy instantiation of list
10474        List<ActivityManager.RunningAppProcessInfo> runList = null;
10475        final boolean allUsers = ActivityManager.checkUidPermission(
10476                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10477                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10478        int userId = UserHandle.getUserId(Binder.getCallingUid());
10479        synchronized (this) {
10480            // Iterate across all processes
10481            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10482                ProcessRecord app = mLruProcesses.get(i);
10483                if (!allUsers && app.userId != userId) {
10484                    continue;
10485                }
10486                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10487                    // Generate process state info for running application
10488                    ActivityManager.RunningAppProcessInfo currApp =
10489                        new ActivityManager.RunningAppProcessInfo(app.processName,
10490                                app.pid, app.getPackageList());
10491                    fillInProcMemInfo(app, currApp);
10492                    if (app.adjSource instanceof ProcessRecord) {
10493                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10494                        currApp.importanceReasonImportance = oomAdjToImportance(
10495                                app.adjSourceOom, null);
10496                    } else if (app.adjSource instanceof ActivityRecord) {
10497                        ActivityRecord r = (ActivityRecord)app.adjSource;
10498                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10499                    }
10500                    if (app.adjTarget instanceof ComponentName) {
10501                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10502                    }
10503                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10504                    //        + " lru=" + currApp.lru);
10505                    if (runList == null) {
10506                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10507                    }
10508                    runList.add(currApp);
10509                }
10510            }
10511        }
10512        return runList;
10513    }
10514
10515    public List<ApplicationInfo> getRunningExternalApplications() {
10516        enforceNotIsolatedCaller("getRunningExternalApplications");
10517        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10518        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10519        if (runningApps != null && runningApps.size() > 0) {
10520            Set<String> extList = new HashSet<String>();
10521            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10522                if (app.pkgList != null) {
10523                    for (String pkg : app.pkgList) {
10524                        extList.add(pkg);
10525                    }
10526                }
10527            }
10528            IPackageManager pm = AppGlobals.getPackageManager();
10529            for (String pkg : extList) {
10530                try {
10531                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10532                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10533                        retList.add(info);
10534                    }
10535                } catch (RemoteException e) {
10536                }
10537            }
10538        }
10539        return retList;
10540    }
10541
10542    @Override
10543    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10544        enforceNotIsolatedCaller("getMyMemoryState");
10545        synchronized (this) {
10546            ProcessRecord proc;
10547            synchronized (mPidsSelfLocked) {
10548                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10549            }
10550            fillInProcMemInfo(proc, outInfo);
10551        }
10552    }
10553
10554    @Override
10555    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10556        if (checkCallingPermission(android.Manifest.permission.DUMP)
10557                != PackageManager.PERMISSION_GRANTED) {
10558            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10559                    + Binder.getCallingPid()
10560                    + ", uid=" + Binder.getCallingUid()
10561                    + " without permission "
10562                    + android.Manifest.permission.DUMP);
10563            return;
10564        }
10565
10566        boolean dumpAll = false;
10567        boolean dumpClient = false;
10568        String dumpPackage = null;
10569
10570        int opti = 0;
10571        while (opti < args.length) {
10572            String opt = args[opti];
10573            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10574                break;
10575            }
10576            opti++;
10577            if ("-a".equals(opt)) {
10578                dumpAll = true;
10579            } else if ("-c".equals(opt)) {
10580                dumpClient = true;
10581            } else if ("-h".equals(opt)) {
10582                pw.println("Activity manager dump options:");
10583                pw.println("  [-a] [-c] [-h] [cmd] ...");
10584                pw.println("  cmd may be one of:");
10585                pw.println("    a[ctivities]: activity stack state");
10586                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10587                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10588                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10589                pw.println("    o[om]: out of memory management");
10590                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10591                pw.println("    provider [COMP_SPEC]: provider client-side state");
10592                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10593                pw.println("    service [COMP_SPEC]: service client-side state");
10594                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10595                pw.println("    all: dump all activities");
10596                pw.println("    top: dump the top activity");
10597                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10598                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10599                pw.println("    a partial substring in a component name, a");
10600                pw.println("    hex object identifier.");
10601                pw.println("  -a: include all available server state.");
10602                pw.println("  -c: include client state.");
10603                return;
10604            } else {
10605                pw.println("Unknown argument: " + opt + "; use -h for help");
10606            }
10607        }
10608
10609        long origId = Binder.clearCallingIdentity();
10610        boolean more = false;
10611        // Is the caller requesting to dump a particular piece of data?
10612        if (opti < args.length) {
10613            String cmd = args[opti];
10614            opti++;
10615            if ("activities".equals(cmd) || "a".equals(cmd)) {
10616                synchronized (this) {
10617                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10618                }
10619            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10620                String[] newArgs;
10621                String name;
10622                if (opti >= args.length) {
10623                    name = null;
10624                    newArgs = EMPTY_STRING_ARRAY;
10625                } else {
10626                    name = args[opti];
10627                    opti++;
10628                    newArgs = new String[args.length - opti];
10629                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10630                            args.length - opti);
10631                }
10632                synchronized (this) {
10633                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10634                }
10635            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10636                String[] newArgs;
10637                String name;
10638                if (opti >= args.length) {
10639                    name = null;
10640                    newArgs = EMPTY_STRING_ARRAY;
10641                } else {
10642                    name = args[opti];
10643                    opti++;
10644                    newArgs = new String[args.length - opti];
10645                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10646                            args.length - opti);
10647                }
10648                synchronized (this) {
10649                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10650                }
10651            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10652                String[] newArgs;
10653                String name;
10654                if (opti >= args.length) {
10655                    name = null;
10656                    newArgs = EMPTY_STRING_ARRAY;
10657                } else {
10658                    name = args[opti];
10659                    opti++;
10660                    newArgs = new String[args.length - opti];
10661                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10662                            args.length - opti);
10663                }
10664                synchronized (this) {
10665                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10666                }
10667            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10668                synchronized (this) {
10669                    dumpOomLocked(fd, pw, args, opti, true);
10670                }
10671            } else if ("provider".equals(cmd)) {
10672                String[] newArgs;
10673                String name;
10674                if (opti >= args.length) {
10675                    name = null;
10676                    newArgs = EMPTY_STRING_ARRAY;
10677                } else {
10678                    name = args[opti];
10679                    opti++;
10680                    newArgs = new String[args.length - opti];
10681                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10682                }
10683                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10684                    pw.println("No providers match: " + name);
10685                    pw.println("Use -h for help.");
10686                }
10687            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10688                synchronized (this) {
10689                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10690                }
10691            } else if ("service".equals(cmd)) {
10692                String[] newArgs;
10693                String name;
10694                if (opti >= args.length) {
10695                    name = null;
10696                    newArgs = EMPTY_STRING_ARRAY;
10697                } else {
10698                    name = args[opti];
10699                    opti++;
10700                    newArgs = new String[args.length - opti];
10701                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10702                            args.length - opti);
10703                }
10704                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10705                    pw.println("No services match: " + name);
10706                    pw.println("Use -h for help.");
10707                }
10708            } else if ("package".equals(cmd)) {
10709                String[] newArgs;
10710                if (opti >= args.length) {
10711                    pw.println("package: no package name specified");
10712                    pw.println("Use -h for help.");
10713                } else {
10714                    dumpPackage = args[opti];
10715                    opti++;
10716                    newArgs = new String[args.length - opti];
10717                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10718                            args.length - opti);
10719                    args = newArgs;
10720                    opti = 0;
10721                    more = true;
10722                }
10723            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10724                synchronized (this) {
10725                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10726                }
10727            } else {
10728                // Dumping a single activity?
10729                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10730                    pw.println("Bad activity command, or no activities match: " + cmd);
10731                    pw.println("Use -h for help.");
10732                }
10733            }
10734            if (!more) {
10735                Binder.restoreCallingIdentity(origId);
10736                return;
10737            }
10738        }
10739
10740        // No piece of data specified, dump everything.
10741        synchronized (this) {
10742            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10743            pw.println();
10744            if (dumpAll) {
10745                pw.println("-------------------------------------------------------------------------------");
10746            }
10747            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10748            pw.println();
10749            if (dumpAll) {
10750                pw.println("-------------------------------------------------------------------------------");
10751            }
10752            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10753            pw.println();
10754            if (dumpAll) {
10755                pw.println("-------------------------------------------------------------------------------");
10756            }
10757            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10758            pw.println();
10759            if (dumpAll) {
10760                pw.println("-------------------------------------------------------------------------------");
10761            }
10762            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10763            pw.println();
10764            if (dumpAll) {
10765                pw.println("-------------------------------------------------------------------------------");
10766            }
10767            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10768        }
10769        Binder.restoreCallingIdentity(origId);
10770    }
10771
10772    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10773            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10774        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10775
10776        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10777                dumpPackage);
10778        boolean needSep = printedAnything;
10779
10780        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10781                dumpPackage, needSep, "  mFocusedActivity: ");
10782        if (printed) {
10783            printedAnything = true;
10784            needSep = false;
10785        }
10786
10787        if (dumpPackage == null) {
10788            if (needSep) {
10789                pw.println();
10790            }
10791            needSep = true;
10792            printedAnything = true;
10793            mStackSupervisor.dump(pw, "  ");
10794        }
10795
10796        if (mRecentTasks.size() > 0) {
10797            boolean printedHeader = false;
10798
10799            final int N = mRecentTasks.size();
10800            for (int i=0; i<N; i++) {
10801                TaskRecord tr = mRecentTasks.get(i);
10802                if (dumpPackage != null) {
10803                    if (tr.realActivity == null ||
10804                            !dumpPackage.equals(tr.realActivity)) {
10805                        continue;
10806                    }
10807                }
10808                if (!printedHeader) {
10809                    if (needSep) {
10810                        pw.println();
10811                    }
10812                    pw.println("  Recent tasks:");
10813                    printedHeader = true;
10814                    printedAnything = true;
10815                }
10816                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10817                        pw.println(tr);
10818                if (dumpAll) {
10819                    mRecentTasks.get(i).dump(pw, "    ");
10820                }
10821            }
10822        }
10823
10824        if (!printedAnything) {
10825            pw.println("  (nothing)");
10826        }
10827    }
10828
10829    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10830            int opti, boolean dumpAll, String dumpPackage) {
10831        boolean needSep = false;
10832        boolean printedAnything = false;
10833        int numPers = 0;
10834
10835        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10836
10837        if (dumpAll) {
10838            final int NP = mProcessNames.getMap().size();
10839            for (int ip=0; ip<NP; ip++) {
10840                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10841                final int NA = procs.size();
10842                for (int ia=0; ia<NA; ia++) {
10843                    ProcessRecord r = procs.valueAt(ia);
10844                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10845                        continue;
10846                    }
10847                    if (!needSep) {
10848                        pw.println("  All known processes:");
10849                        needSep = true;
10850                        printedAnything = true;
10851                    }
10852                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10853                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10854                        pw.print(" "); pw.println(r);
10855                    r.dump(pw, "    ");
10856                    if (r.persistent) {
10857                        numPers++;
10858                    }
10859                }
10860            }
10861        }
10862
10863        if (mIsolatedProcesses.size() > 0) {
10864            boolean printed = false;
10865            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10866                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10867                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10868                    continue;
10869                }
10870                if (!printed) {
10871                    if (needSep) {
10872                        pw.println();
10873                    }
10874                    pw.println("  Isolated process list (sorted by uid):");
10875                    printedAnything = true;
10876                    printed = true;
10877                    needSep = true;
10878                }
10879                pw.println(String.format("%sIsolated #%2d: %s",
10880                        "    ", i, r.toString()));
10881            }
10882        }
10883
10884        if (mLruProcesses.size() > 0) {
10885            if (needSep) {
10886                pw.println();
10887            }
10888            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10889                    pw.print(" total, non-act at ");
10890                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10891                    pw.print(", non-svc at ");
10892                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10893                    pw.println("):");
10894            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10895            needSep = true;
10896            printedAnything = true;
10897        }
10898
10899        if (dumpAll || dumpPackage != null) {
10900            synchronized (mPidsSelfLocked) {
10901                boolean printed = false;
10902                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10903                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10904                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10905                        continue;
10906                    }
10907                    if (!printed) {
10908                        if (needSep) pw.println();
10909                        needSep = true;
10910                        pw.println("  PID mappings:");
10911                        printed = true;
10912                        printedAnything = true;
10913                    }
10914                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10915                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10916                }
10917            }
10918        }
10919
10920        if (mForegroundProcesses.size() > 0) {
10921            synchronized (mPidsSelfLocked) {
10922                boolean printed = false;
10923                for (int i=0; i<mForegroundProcesses.size(); i++) {
10924                    ProcessRecord r = mPidsSelfLocked.get(
10925                            mForegroundProcesses.valueAt(i).pid);
10926                    if (dumpPackage != null && (r == null
10927                            || !r.pkgList.containsKey(dumpPackage))) {
10928                        continue;
10929                    }
10930                    if (!printed) {
10931                        if (needSep) pw.println();
10932                        needSep = true;
10933                        pw.println("  Foreground Processes:");
10934                        printed = true;
10935                        printedAnything = true;
10936                    }
10937                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10938                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10939                }
10940            }
10941        }
10942
10943        if (mPersistentStartingProcesses.size() > 0) {
10944            if (needSep) pw.println();
10945            needSep = true;
10946            printedAnything = true;
10947            pw.println("  Persisent processes that are starting:");
10948            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10949                    "Starting Norm", "Restarting PERS", dumpPackage);
10950        }
10951
10952        if (mRemovedProcesses.size() > 0) {
10953            if (needSep) pw.println();
10954            needSep = true;
10955            printedAnything = true;
10956            pw.println("  Processes that are being removed:");
10957            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10958                    "Removed Norm", "Removed PERS", dumpPackage);
10959        }
10960
10961        if (mProcessesOnHold.size() > 0) {
10962            if (needSep) pw.println();
10963            needSep = true;
10964            printedAnything = true;
10965            pw.println("  Processes that are on old until the system is ready:");
10966            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10967                    "OnHold Norm", "OnHold PERS", dumpPackage);
10968        }
10969
10970        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10971
10972        if (mProcessCrashTimes.getMap().size() > 0) {
10973            boolean printed = false;
10974            long now = SystemClock.uptimeMillis();
10975            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10976            final int NP = pmap.size();
10977            for (int ip=0; ip<NP; ip++) {
10978                String pname = pmap.keyAt(ip);
10979                SparseArray<Long> uids = pmap.valueAt(ip);
10980                final int N = uids.size();
10981                for (int i=0; i<N; i++) {
10982                    int puid = uids.keyAt(i);
10983                    ProcessRecord r = mProcessNames.get(pname, puid);
10984                    if (dumpPackage != null && (r == null
10985                            || !r.pkgList.containsKey(dumpPackage))) {
10986                        continue;
10987                    }
10988                    if (!printed) {
10989                        if (needSep) pw.println();
10990                        needSep = true;
10991                        pw.println("  Time since processes crashed:");
10992                        printed = true;
10993                        printedAnything = true;
10994                    }
10995                    pw.print("    Process "); pw.print(pname);
10996                            pw.print(" uid "); pw.print(puid);
10997                            pw.print(": last crashed ");
10998                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10999                            pw.println(" ago");
11000                }
11001            }
11002        }
11003
11004        if (mBadProcesses.getMap().size() > 0) {
11005            boolean printed = false;
11006            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11007            final int NP = pmap.size();
11008            for (int ip=0; ip<NP; ip++) {
11009                String pname = pmap.keyAt(ip);
11010                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11011                final int N = uids.size();
11012                for (int i=0; i<N; i++) {
11013                    int puid = uids.keyAt(i);
11014                    ProcessRecord r = mProcessNames.get(pname, puid);
11015                    if (dumpPackage != null && (r == null
11016                            || !r.pkgList.containsKey(dumpPackage))) {
11017                        continue;
11018                    }
11019                    if (!printed) {
11020                        if (needSep) pw.println();
11021                        needSep = true;
11022                        pw.println("  Bad processes:");
11023                        printedAnything = true;
11024                    }
11025                    BadProcessInfo info = uids.valueAt(i);
11026                    pw.print("    Bad process "); pw.print(pname);
11027                            pw.print(" uid "); pw.print(puid);
11028                            pw.print(": crashed at time "); pw.println(info.time);
11029                    if (info.shortMsg != null) {
11030                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11031                    }
11032                    if (info.longMsg != null) {
11033                        pw.print("      Long msg: "); pw.println(info.longMsg);
11034                    }
11035                    if (info.stack != null) {
11036                        pw.println("      Stack:");
11037                        int lastPos = 0;
11038                        for (int pos=0; pos<info.stack.length(); pos++) {
11039                            if (info.stack.charAt(pos) == '\n') {
11040                                pw.print("        ");
11041                                pw.write(info.stack, lastPos, pos-lastPos);
11042                                pw.println();
11043                                lastPos = pos+1;
11044                            }
11045                        }
11046                        if (lastPos < info.stack.length()) {
11047                            pw.print("        ");
11048                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11049                            pw.println();
11050                        }
11051                    }
11052                }
11053            }
11054        }
11055
11056        if (dumpPackage == null) {
11057            pw.println();
11058            needSep = false;
11059            pw.println("  mStartedUsers:");
11060            for (int i=0; i<mStartedUsers.size(); i++) {
11061                UserStartedState uss = mStartedUsers.valueAt(i);
11062                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11063                        pw.print(": "); uss.dump("", pw);
11064            }
11065            pw.print("  mStartedUserArray: [");
11066            for (int i=0; i<mStartedUserArray.length; i++) {
11067                if (i > 0) pw.print(", ");
11068                pw.print(mStartedUserArray[i]);
11069            }
11070            pw.println("]");
11071            pw.print("  mUserLru: [");
11072            for (int i=0; i<mUserLru.size(); i++) {
11073                if (i > 0) pw.print(", ");
11074                pw.print(mUserLru.get(i));
11075            }
11076            pw.println("]");
11077            if (dumpAll) {
11078                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11079            }
11080        }
11081        if (mHomeProcess != null && (dumpPackage == null
11082                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11083            if (needSep) {
11084                pw.println();
11085                needSep = false;
11086            }
11087            pw.println("  mHomeProcess: " + mHomeProcess);
11088        }
11089        if (mPreviousProcess != null && (dumpPackage == null
11090                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11091            if (needSep) {
11092                pw.println();
11093                needSep = false;
11094            }
11095            pw.println("  mPreviousProcess: " + mPreviousProcess);
11096        }
11097        if (dumpAll) {
11098            StringBuilder sb = new StringBuilder(128);
11099            sb.append("  mPreviousProcessVisibleTime: ");
11100            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11101            pw.println(sb);
11102        }
11103        if (mHeavyWeightProcess != null && (dumpPackage == null
11104                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11105            if (needSep) {
11106                pw.println();
11107                needSep = false;
11108            }
11109            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11110        }
11111        if (dumpPackage == null) {
11112            pw.println("  mConfiguration: " + mConfiguration);
11113        }
11114        if (dumpAll) {
11115            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11116            if (mCompatModePackages.getPackages().size() > 0) {
11117                boolean printed = false;
11118                for (Map.Entry<String, Integer> entry
11119                        : mCompatModePackages.getPackages().entrySet()) {
11120                    String pkg = entry.getKey();
11121                    int mode = entry.getValue();
11122                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11123                        continue;
11124                    }
11125                    if (!printed) {
11126                        pw.println("  mScreenCompatPackages:");
11127                        printed = true;
11128                    }
11129                    pw.print("    "); pw.print(pkg); pw.print(": ");
11130                            pw.print(mode); pw.println();
11131                }
11132            }
11133        }
11134        if (dumpPackage == null) {
11135            if (mSleeping || mWentToSleep || mLockScreenShown) {
11136                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11137                        + " mLockScreenShown " + mLockScreenShown);
11138            }
11139            if (mShuttingDown) {
11140                pw.println("  mShuttingDown=" + mShuttingDown);
11141            }
11142        }
11143        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11144                || mOrigWaitForDebugger) {
11145            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11146                    || dumpPackage.equals(mOrigDebugApp)) {
11147                if (needSep) {
11148                    pw.println();
11149                    needSep = false;
11150                }
11151                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11152                        + " mDebugTransient=" + mDebugTransient
11153                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11154            }
11155        }
11156        if (mOpenGlTraceApp != null) {
11157            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11158                if (needSep) {
11159                    pw.println();
11160                    needSep = false;
11161                }
11162                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11163            }
11164        }
11165        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11166                || mProfileFd != null) {
11167            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11168                if (needSep) {
11169                    pw.println();
11170                    needSep = false;
11171                }
11172                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11173                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11174                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11175                        + mAutoStopProfiler);
11176            }
11177        }
11178        if (dumpPackage == null) {
11179            if (mAlwaysFinishActivities || mController != null) {
11180                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11181                        + " mController=" + mController);
11182            }
11183            if (dumpAll) {
11184                pw.println("  Total persistent processes: " + numPers);
11185                pw.println("  mProcessesReady=" + mProcessesReady
11186                        + " mSystemReady=" + mSystemReady);
11187                pw.println("  mBooting=" + mBooting
11188                        + " mBooted=" + mBooted
11189                        + " mFactoryTest=" + mFactoryTest);
11190                pw.print("  mLastPowerCheckRealtime=");
11191                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11192                        pw.println("");
11193                pw.print("  mLastPowerCheckUptime=");
11194                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11195                        pw.println("");
11196                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11197                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11198                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11199                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11200                        + " (" + mLruProcesses.size() + " total)"
11201                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11202                        + " mNumServiceProcs=" + mNumServiceProcs
11203                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11204                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11205                        + " mLastMemoryLevel" + mLastMemoryLevel
11206                        + " mLastNumProcesses" + mLastNumProcesses);
11207                long now = SystemClock.uptimeMillis();
11208                pw.print("  mLastIdleTime=");
11209                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11210                        pw.print(" mLowRamSinceLastIdle=");
11211                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11212                        pw.println();
11213            }
11214        }
11215
11216        if (!printedAnything) {
11217            pw.println("  (nothing)");
11218        }
11219    }
11220
11221    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11222            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11223        if (mProcessesToGc.size() > 0) {
11224            boolean printed = false;
11225            long now = SystemClock.uptimeMillis();
11226            for (int i=0; i<mProcessesToGc.size(); i++) {
11227                ProcessRecord proc = mProcessesToGc.get(i);
11228                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11229                    continue;
11230                }
11231                if (!printed) {
11232                    if (needSep) pw.println();
11233                    needSep = true;
11234                    pw.println("  Processes that are waiting to GC:");
11235                    printed = true;
11236                }
11237                pw.print("    Process "); pw.println(proc);
11238                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11239                        pw.print(", last gced=");
11240                        pw.print(now-proc.lastRequestedGc);
11241                        pw.print(" ms ago, last lowMem=");
11242                        pw.print(now-proc.lastLowMemory);
11243                        pw.println(" ms ago");
11244
11245            }
11246        }
11247        return needSep;
11248    }
11249
11250    void printOomLevel(PrintWriter pw, String name, int adj) {
11251        pw.print("    ");
11252        if (adj >= 0) {
11253            pw.print(' ');
11254            if (adj < 10) pw.print(' ');
11255        } else {
11256            if (adj > -10) pw.print(' ');
11257        }
11258        pw.print(adj);
11259        pw.print(": ");
11260        pw.print(name);
11261        pw.print(" (");
11262        pw.print(mProcessList.getMemLevel(adj)/1024);
11263        pw.println(" kB)");
11264    }
11265
11266    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11267            int opti, boolean dumpAll) {
11268        boolean needSep = false;
11269
11270        if (mLruProcesses.size() > 0) {
11271            if (needSep) pw.println();
11272            needSep = true;
11273            pw.println("  OOM levels:");
11274            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11275            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11276            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11277            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11278            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11279            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11280            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11281            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11282            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11283            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11284            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11285            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11286            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11287
11288            if (needSep) pw.println();
11289            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11290                    pw.print(" total, non-act at ");
11291                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11292                    pw.print(", non-svc at ");
11293                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11294                    pw.println("):");
11295            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11296            needSep = true;
11297        }
11298
11299        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11300
11301        pw.println();
11302        pw.println("  mHomeProcess: " + mHomeProcess);
11303        pw.println("  mPreviousProcess: " + mPreviousProcess);
11304        if (mHeavyWeightProcess != null) {
11305            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11306        }
11307
11308        return true;
11309    }
11310
11311    /**
11312     * There are three ways to call this:
11313     *  - no provider specified: dump all the providers
11314     *  - a flattened component name that matched an existing provider was specified as the
11315     *    first arg: dump that one provider
11316     *  - the first arg isn't the flattened component name of an existing provider:
11317     *    dump all providers whose component contains the first arg as a substring
11318     */
11319    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11320            int opti, boolean dumpAll) {
11321        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11322    }
11323
11324    static class ItemMatcher {
11325        ArrayList<ComponentName> components;
11326        ArrayList<String> strings;
11327        ArrayList<Integer> objects;
11328        boolean all;
11329
11330        ItemMatcher() {
11331            all = true;
11332        }
11333
11334        void build(String name) {
11335            ComponentName componentName = ComponentName.unflattenFromString(name);
11336            if (componentName != null) {
11337                if (components == null) {
11338                    components = new ArrayList<ComponentName>();
11339                }
11340                components.add(componentName);
11341                all = false;
11342            } else {
11343                int objectId = 0;
11344                // Not a '/' separated full component name; maybe an object ID?
11345                try {
11346                    objectId = Integer.parseInt(name, 16);
11347                    if (objects == null) {
11348                        objects = new ArrayList<Integer>();
11349                    }
11350                    objects.add(objectId);
11351                    all = false;
11352                } catch (RuntimeException e) {
11353                    // Not an integer; just do string match.
11354                    if (strings == null) {
11355                        strings = new ArrayList<String>();
11356                    }
11357                    strings.add(name);
11358                    all = false;
11359                }
11360            }
11361        }
11362
11363        int build(String[] args, int opti) {
11364            for (; opti<args.length; opti++) {
11365                String name = args[opti];
11366                if ("--".equals(name)) {
11367                    return opti+1;
11368                }
11369                build(name);
11370            }
11371            return opti;
11372        }
11373
11374        boolean match(Object object, ComponentName comp) {
11375            if (all) {
11376                return true;
11377            }
11378            if (components != null) {
11379                for (int i=0; i<components.size(); i++) {
11380                    if (components.get(i).equals(comp)) {
11381                        return true;
11382                    }
11383                }
11384            }
11385            if (objects != null) {
11386                for (int i=0; i<objects.size(); i++) {
11387                    if (System.identityHashCode(object) == objects.get(i)) {
11388                        return true;
11389                    }
11390                }
11391            }
11392            if (strings != null) {
11393                String flat = comp.flattenToString();
11394                for (int i=0; i<strings.size(); i++) {
11395                    if (flat.contains(strings.get(i))) {
11396                        return true;
11397                    }
11398                }
11399            }
11400            return false;
11401        }
11402    }
11403
11404    /**
11405     * There are three things that cmd can be:
11406     *  - a flattened component name that matches an existing activity
11407     *  - the cmd arg isn't the flattened component name of an existing activity:
11408     *    dump all activity whose component contains the cmd as a substring
11409     *  - A hex number of the ActivityRecord object instance.
11410     */
11411    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11412            int opti, boolean dumpAll) {
11413        ArrayList<ActivityRecord> activities;
11414
11415        synchronized (this) {
11416            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11417        }
11418
11419        if (activities.size() <= 0) {
11420            return false;
11421        }
11422
11423        String[] newArgs = new String[args.length - opti];
11424        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11425
11426        TaskRecord lastTask = null;
11427        boolean needSep = false;
11428        for (int i=activities.size()-1; i>=0; i--) {
11429            ActivityRecord r = activities.get(i);
11430            if (needSep) {
11431                pw.println();
11432            }
11433            needSep = true;
11434            synchronized (this) {
11435                if (lastTask != r.task) {
11436                    lastTask = r.task;
11437                    pw.print("TASK "); pw.print(lastTask.affinity);
11438                            pw.print(" id="); pw.println(lastTask.taskId);
11439                    if (dumpAll) {
11440                        lastTask.dump(pw, "  ");
11441                    }
11442                }
11443            }
11444            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11445        }
11446        return true;
11447    }
11448
11449    /**
11450     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11451     * there is a thread associated with the activity.
11452     */
11453    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11454            final ActivityRecord r, String[] args, boolean dumpAll) {
11455        String innerPrefix = prefix + "  ";
11456        synchronized (this) {
11457            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11458                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11459                    pw.print(" pid=");
11460                    if (r.app != null) pw.println(r.app.pid);
11461                    else pw.println("(not running)");
11462            if (dumpAll) {
11463                r.dump(pw, innerPrefix);
11464            }
11465        }
11466        if (r.app != null && r.app.thread != null) {
11467            // flush anything that is already in the PrintWriter since the thread is going
11468            // to write to the file descriptor directly
11469            pw.flush();
11470            try {
11471                TransferPipe tp = new TransferPipe();
11472                try {
11473                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11474                            r.appToken, innerPrefix, args);
11475                    tp.go(fd);
11476                } finally {
11477                    tp.kill();
11478                }
11479            } catch (IOException e) {
11480                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11481            } catch (RemoteException e) {
11482                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11483            }
11484        }
11485    }
11486
11487    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11488            int opti, boolean dumpAll, String dumpPackage) {
11489        boolean needSep = false;
11490        boolean onlyHistory = false;
11491        boolean printedAnything = false;
11492
11493        if ("history".equals(dumpPackage)) {
11494            if (opti < args.length && "-s".equals(args[opti])) {
11495                dumpAll = false;
11496            }
11497            onlyHistory = true;
11498            dumpPackage = null;
11499        }
11500
11501        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11502        if (!onlyHistory && dumpAll) {
11503            if (mRegisteredReceivers.size() > 0) {
11504                boolean printed = false;
11505                Iterator it = mRegisteredReceivers.values().iterator();
11506                while (it.hasNext()) {
11507                    ReceiverList r = (ReceiverList)it.next();
11508                    if (dumpPackage != null && (r.app == null ||
11509                            !dumpPackage.equals(r.app.info.packageName))) {
11510                        continue;
11511                    }
11512                    if (!printed) {
11513                        pw.println("  Registered Receivers:");
11514                        needSep = true;
11515                        printed = true;
11516                        printedAnything = true;
11517                    }
11518                    pw.print("  * "); pw.println(r);
11519                    r.dump(pw, "    ");
11520                }
11521            }
11522
11523            if (mReceiverResolver.dump(pw, needSep ?
11524                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11525                    "    ", dumpPackage, false)) {
11526                needSep = true;
11527                printedAnything = true;
11528            }
11529        }
11530
11531        for (BroadcastQueue q : mBroadcastQueues) {
11532            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11533            printedAnything |= needSep;
11534        }
11535
11536        needSep = true;
11537
11538        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11539            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11540                if (needSep) {
11541                    pw.println();
11542                }
11543                needSep = true;
11544                printedAnything = true;
11545                pw.print("  Sticky broadcasts for user ");
11546                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11547                StringBuilder sb = new StringBuilder(128);
11548                for (Map.Entry<String, ArrayList<Intent>> ent
11549                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11550                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11551                    if (dumpAll) {
11552                        pw.println(":");
11553                        ArrayList<Intent> intents = ent.getValue();
11554                        final int N = intents.size();
11555                        for (int i=0; i<N; i++) {
11556                            sb.setLength(0);
11557                            sb.append("    Intent: ");
11558                            intents.get(i).toShortString(sb, false, true, false, false);
11559                            pw.println(sb.toString());
11560                            Bundle bundle = intents.get(i).getExtras();
11561                            if (bundle != null) {
11562                                pw.print("      ");
11563                                pw.println(bundle.toString());
11564                            }
11565                        }
11566                    } else {
11567                        pw.println("");
11568                    }
11569                }
11570            }
11571        }
11572
11573        if (!onlyHistory && dumpAll) {
11574            pw.println();
11575            for (BroadcastQueue queue : mBroadcastQueues) {
11576                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11577                        + queue.mBroadcastsScheduled);
11578            }
11579            pw.println("  mHandler:");
11580            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11581            needSep = true;
11582            printedAnything = true;
11583        }
11584
11585        if (!printedAnything) {
11586            pw.println("  (nothing)");
11587        }
11588    }
11589
11590    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11591            int opti, boolean dumpAll, String dumpPackage) {
11592        boolean needSep;
11593        boolean printedAnything = false;
11594
11595        ItemMatcher matcher = new ItemMatcher();
11596        matcher.build(args, opti);
11597
11598        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11599
11600        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11601        printedAnything |= needSep;
11602
11603        if (mLaunchingProviders.size() > 0) {
11604            boolean printed = false;
11605            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11606                ContentProviderRecord r = mLaunchingProviders.get(i);
11607                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11608                    continue;
11609                }
11610                if (!printed) {
11611                    if (needSep) pw.println();
11612                    needSep = true;
11613                    pw.println("  Launching content providers:");
11614                    printed = true;
11615                    printedAnything = true;
11616                }
11617                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11618                        pw.println(r);
11619            }
11620        }
11621
11622        if (mGrantedUriPermissions.size() > 0) {
11623            boolean printed = false;
11624            int dumpUid = -2;
11625            if (dumpPackage != null) {
11626                try {
11627                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11628                } catch (NameNotFoundException e) {
11629                    dumpUid = -1;
11630                }
11631            }
11632            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11633                int uid = mGrantedUriPermissions.keyAt(i);
11634                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11635                    continue;
11636                }
11637                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11638                if (!printed) {
11639                    if (needSep) pw.println();
11640                    needSep = true;
11641                    pw.println("  Granted Uri Permissions:");
11642                    printed = true;
11643                    printedAnything = true;
11644                }
11645                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11646                for (UriPermission perm : perms.values()) {
11647                    pw.print("    "); pw.println(perm);
11648                    if (dumpAll) {
11649                        perm.dump(pw, "      ");
11650                    }
11651                }
11652            }
11653        }
11654
11655        if (!printedAnything) {
11656            pw.println("  (nothing)");
11657        }
11658    }
11659
11660    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11661            int opti, boolean dumpAll, String dumpPackage) {
11662        boolean printed = false;
11663
11664        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11665
11666        if (mIntentSenderRecords.size() > 0) {
11667            Iterator<WeakReference<PendingIntentRecord>> it
11668                    = mIntentSenderRecords.values().iterator();
11669            while (it.hasNext()) {
11670                WeakReference<PendingIntentRecord> ref = it.next();
11671                PendingIntentRecord rec = ref != null ? ref.get(): null;
11672                if (dumpPackage != null && (rec == null
11673                        || !dumpPackage.equals(rec.key.packageName))) {
11674                    continue;
11675                }
11676                printed = true;
11677                if (rec != null) {
11678                    pw.print("  * "); pw.println(rec);
11679                    if (dumpAll) {
11680                        rec.dump(pw, "    ");
11681                    }
11682                } else {
11683                    pw.print("  * "); pw.println(ref);
11684                }
11685            }
11686        }
11687
11688        if (!printed) {
11689            pw.println("  (nothing)");
11690        }
11691    }
11692
11693    private static final int dumpProcessList(PrintWriter pw,
11694            ActivityManagerService service, List list,
11695            String prefix, String normalLabel, String persistentLabel,
11696            String dumpPackage) {
11697        int numPers = 0;
11698        final int N = list.size()-1;
11699        for (int i=N; i>=0; i--) {
11700            ProcessRecord r = (ProcessRecord)list.get(i);
11701            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11702                continue;
11703            }
11704            pw.println(String.format("%s%s #%2d: %s",
11705                    prefix, (r.persistent ? persistentLabel : normalLabel),
11706                    i, r.toString()));
11707            if (r.persistent) {
11708                numPers++;
11709            }
11710        }
11711        return numPers;
11712    }
11713
11714    private static final boolean dumpProcessOomList(PrintWriter pw,
11715            ActivityManagerService service, List<ProcessRecord> origList,
11716            String prefix, String normalLabel, String persistentLabel,
11717            boolean inclDetails, String dumpPackage) {
11718
11719        ArrayList<Pair<ProcessRecord, Integer>> list
11720                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11721        for (int i=0; i<origList.size(); i++) {
11722            ProcessRecord r = origList.get(i);
11723            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11724                continue;
11725            }
11726            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11727        }
11728
11729        if (list.size() <= 0) {
11730            return false;
11731        }
11732
11733        Comparator<Pair<ProcessRecord, Integer>> comparator
11734                = new Comparator<Pair<ProcessRecord, Integer>>() {
11735            @Override
11736            public int compare(Pair<ProcessRecord, Integer> object1,
11737                    Pair<ProcessRecord, Integer> object2) {
11738                if (object1.first.setAdj != object2.first.setAdj) {
11739                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11740                }
11741                if (object1.second.intValue() != object2.second.intValue()) {
11742                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11743                }
11744                return 0;
11745            }
11746        };
11747
11748        Collections.sort(list, comparator);
11749
11750        final long curRealtime = SystemClock.elapsedRealtime();
11751        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11752        final long curUptime = SystemClock.uptimeMillis();
11753        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11754
11755        for (int i=list.size()-1; i>=0; i--) {
11756            ProcessRecord r = list.get(i).first;
11757            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11758            char schedGroup;
11759            switch (r.setSchedGroup) {
11760                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11761                    schedGroup = 'B';
11762                    break;
11763                case Process.THREAD_GROUP_DEFAULT:
11764                    schedGroup = 'F';
11765                    break;
11766                default:
11767                    schedGroup = '?';
11768                    break;
11769            }
11770            char foreground;
11771            if (r.foregroundActivities) {
11772                foreground = 'A';
11773            } else if (r.foregroundServices) {
11774                foreground = 'S';
11775            } else {
11776                foreground = ' ';
11777            }
11778            String procState = ProcessList.makeProcStateString(r.curProcState);
11779            pw.print(prefix);
11780            pw.print(r.persistent ? persistentLabel : normalLabel);
11781            pw.print(" #");
11782            int num = (origList.size()-1)-list.get(i).second;
11783            if (num < 10) pw.print(' ');
11784            pw.print(num);
11785            pw.print(": ");
11786            pw.print(oomAdj);
11787            pw.print(' ');
11788            pw.print(schedGroup);
11789            pw.print('/');
11790            pw.print(foreground);
11791            pw.print('/');
11792            pw.print(procState);
11793            pw.print(" trm:");
11794            if (r.trimMemoryLevel < 10) pw.print(' ');
11795            pw.print(r.trimMemoryLevel);
11796            pw.print(' ');
11797            pw.print(r.toShortString());
11798            pw.print(" (");
11799            pw.print(r.adjType);
11800            pw.println(')');
11801            if (r.adjSource != null || r.adjTarget != null) {
11802                pw.print(prefix);
11803                pw.print("    ");
11804                if (r.adjTarget instanceof ComponentName) {
11805                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11806                } else if (r.adjTarget != null) {
11807                    pw.print(r.adjTarget.toString());
11808                } else {
11809                    pw.print("{null}");
11810                }
11811                pw.print("<=");
11812                if (r.adjSource instanceof ProcessRecord) {
11813                    pw.print("Proc{");
11814                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11815                    pw.println("}");
11816                } else if (r.adjSource != null) {
11817                    pw.println(r.adjSource.toString());
11818                } else {
11819                    pw.println("{null}");
11820                }
11821            }
11822            if (inclDetails) {
11823                pw.print(prefix);
11824                pw.print("    ");
11825                pw.print("oom: max="); pw.print(r.maxAdj);
11826                pw.print(" curRaw="); pw.print(r.curRawAdj);
11827                pw.print(" setRaw="); pw.print(r.setRawAdj);
11828                pw.print(" cur="); pw.print(r.curAdj);
11829                pw.print(" set="); pw.println(r.setAdj);
11830                pw.print(prefix);
11831                pw.print("    ");
11832                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11833                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11834                pw.print(" lastPss="); pw.print(r.lastPss);
11835                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11836                pw.print(prefix);
11837                pw.print("    ");
11838                pw.print("keeping="); pw.print(r.keeping);
11839                pw.print(" cached="); pw.print(r.cached);
11840                pw.print(" empty="); pw.print(r.empty);
11841                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11842
11843                if (!r.keeping) {
11844                    if (r.lastWakeTime != 0) {
11845                        long wtime;
11846                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11847                        synchronized (stats) {
11848                            wtime = stats.getProcessWakeTime(r.info.uid,
11849                                    r.pid, curRealtime);
11850                        }
11851                        long timeUsed = wtime - r.lastWakeTime;
11852                        pw.print(prefix);
11853                        pw.print("    ");
11854                        pw.print("keep awake over ");
11855                        TimeUtils.formatDuration(realtimeSince, pw);
11856                        pw.print(" used ");
11857                        TimeUtils.formatDuration(timeUsed, pw);
11858                        pw.print(" (");
11859                        pw.print((timeUsed*100)/realtimeSince);
11860                        pw.println("%)");
11861                    }
11862                    if (r.lastCpuTime != 0) {
11863                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11864                        pw.print(prefix);
11865                        pw.print("    ");
11866                        pw.print("run cpu over ");
11867                        TimeUtils.formatDuration(uptimeSince, pw);
11868                        pw.print(" used ");
11869                        TimeUtils.formatDuration(timeUsed, pw);
11870                        pw.print(" (");
11871                        pw.print((timeUsed*100)/uptimeSince);
11872                        pw.println("%)");
11873                    }
11874                }
11875            }
11876        }
11877        return true;
11878    }
11879
11880    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11881        ArrayList<ProcessRecord> procs;
11882        synchronized (this) {
11883            if (args != null && args.length > start
11884                    && args[start].charAt(0) != '-') {
11885                procs = new ArrayList<ProcessRecord>();
11886                int pid = -1;
11887                try {
11888                    pid = Integer.parseInt(args[start]);
11889                } catch (NumberFormatException e) {
11890                }
11891                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11892                    ProcessRecord proc = mLruProcesses.get(i);
11893                    if (proc.pid == pid) {
11894                        procs.add(proc);
11895                    } else if (proc.processName.equals(args[start])) {
11896                        procs.add(proc);
11897                    }
11898                }
11899                if (procs.size() <= 0) {
11900                    return null;
11901                }
11902            } else {
11903                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11904            }
11905        }
11906        return procs;
11907    }
11908
11909    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11910            PrintWriter pw, String[] args) {
11911        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11912        if (procs == null) {
11913            pw.println("No process found for: " + args[0]);
11914            return;
11915        }
11916
11917        long uptime = SystemClock.uptimeMillis();
11918        long realtime = SystemClock.elapsedRealtime();
11919        pw.println("Applications Graphics Acceleration Info:");
11920        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11921
11922        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11923            ProcessRecord r = procs.get(i);
11924            if (r.thread != null) {
11925                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11926                pw.flush();
11927                try {
11928                    TransferPipe tp = new TransferPipe();
11929                    try {
11930                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11931                        tp.go(fd);
11932                    } finally {
11933                        tp.kill();
11934                    }
11935                } catch (IOException e) {
11936                    pw.println("Failure while dumping the app: " + r);
11937                    pw.flush();
11938                } catch (RemoteException e) {
11939                    pw.println("Got a RemoteException while dumping the app " + r);
11940                    pw.flush();
11941                }
11942            }
11943        }
11944    }
11945
11946    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11947        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11948        if (procs == null) {
11949            pw.println("No process found for: " + args[0]);
11950            return;
11951        }
11952
11953        pw.println("Applications Database Info:");
11954
11955        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11956            ProcessRecord r = procs.get(i);
11957            if (r.thread != null) {
11958                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11959                pw.flush();
11960                try {
11961                    TransferPipe tp = new TransferPipe();
11962                    try {
11963                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11964                        tp.go(fd);
11965                    } finally {
11966                        tp.kill();
11967                    }
11968                } catch (IOException e) {
11969                    pw.println("Failure while dumping the app: " + r);
11970                    pw.flush();
11971                } catch (RemoteException e) {
11972                    pw.println("Got a RemoteException while dumping the app " + r);
11973                    pw.flush();
11974                }
11975            }
11976        }
11977    }
11978
11979    final static class MemItem {
11980        final boolean isProc;
11981        final String label;
11982        final String shortLabel;
11983        final long pss;
11984        final int id;
11985        final boolean hasActivities;
11986        ArrayList<MemItem> subitems;
11987
11988        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11989                boolean _hasActivities) {
11990            isProc = true;
11991            label = _label;
11992            shortLabel = _shortLabel;
11993            pss = _pss;
11994            id = _id;
11995            hasActivities = _hasActivities;
11996        }
11997
11998        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11999            isProc = false;
12000            label = _label;
12001            shortLabel = _shortLabel;
12002            pss = _pss;
12003            id = _id;
12004            hasActivities = false;
12005        }
12006    }
12007
12008    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12009            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12010        if (sort && !isCompact) {
12011            Collections.sort(items, new Comparator<MemItem>() {
12012                @Override
12013                public int compare(MemItem lhs, MemItem rhs) {
12014                    if (lhs.pss < rhs.pss) {
12015                        return 1;
12016                    } else if (lhs.pss > rhs.pss) {
12017                        return -1;
12018                    }
12019                    return 0;
12020                }
12021            });
12022        }
12023
12024        for (int i=0; i<items.size(); i++) {
12025            MemItem mi = items.get(i);
12026            if (!isCompact) {
12027                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12028            } else if (mi.isProc) {
12029                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12030                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12031                pw.println(mi.hasActivities ? ",a" : ",e");
12032            } else {
12033                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12034                pw.println(mi.pss);
12035            }
12036            if (mi.subitems != null) {
12037                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12038                        true, isCompact);
12039            }
12040        }
12041    }
12042
12043    // These are in KB.
12044    static final long[] DUMP_MEM_BUCKETS = new long[] {
12045        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12046        120*1024, 160*1024, 200*1024,
12047        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12048        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12049    };
12050
12051    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12052            boolean stackLike) {
12053        int start = label.lastIndexOf('.');
12054        if (start >= 0) start++;
12055        else start = 0;
12056        int end = label.length();
12057        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12058            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12059                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12060                out.append(bucket);
12061                out.append(stackLike ? "MB." : "MB ");
12062                out.append(label, start, end);
12063                return;
12064            }
12065        }
12066        out.append(memKB/1024);
12067        out.append(stackLike ? "MB." : "MB ");
12068        out.append(label, start, end);
12069    }
12070
12071    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12072            ProcessList.NATIVE_ADJ,
12073            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12074            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12075            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12076            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12077            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12078    };
12079    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12080            "Native",
12081            "System", "Persistent", "Foreground",
12082            "Visible", "Perceptible",
12083            "Heavy Weight", "Backup",
12084            "A Services", "Home",
12085            "Previous", "B Services", "Cached"
12086    };
12087    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12088            "native",
12089            "sys", "pers", "fore",
12090            "vis", "percept",
12091            "heavy", "backup",
12092            "servicea", "home",
12093            "prev", "serviceb", "cached"
12094    };
12095
12096    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12097            long realtime, boolean isCheckinRequest, boolean isCompact) {
12098        if (isCheckinRequest || isCompact) {
12099            // short checkin version
12100            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12101        } else {
12102            pw.println("Applications Memory Usage (kB):");
12103            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12104        }
12105    }
12106
12107    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12108            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12109        boolean dumpDetails = false;
12110        boolean dumpFullDetails = false;
12111        boolean dumpDalvik = false;
12112        boolean oomOnly = false;
12113        boolean isCompact = false;
12114        boolean localOnly = false;
12115
12116        int opti = 0;
12117        while (opti < args.length) {
12118            String opt = args[opti];
12119            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12120                break;
12121            }
12122            opti++;
12123            if ("-a".equals(opt)) {
12124                dumpDetails = true;
12125                dumpFullDetails = true;
12126                dumpDalvik = true;
12127            } else if ("-d".equals(opt)) {
12128                dumpDalvik = true;
12129            } else if ("-c".equals(opt)) {
12130                isCompact = true;
12131            } else if ("--oom".equals(opt)) {
12132                oomOnly = true;
12133            } else if ("--local".equals(opt)) {
12134                localOnly = true;
12135            } else if ("-h".equals(opt)) {
12136                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12137                pw.println("  -a: include all available information for each process.");
12138                pw.println("  -d: include dalvik details when dumping process details.");
12139                pw.println("  -c: dump in a compact machine-parseable representation.");
12140                pw.println("  --oom: only show processes organized by oom adj.");
12141                pw.println("  --local: only collect details locally, don't call process.");
12142                pw.println("If [process] is specified it can be the name or ");
12143                pw.println("pid of a specific process to dump.");
12144                return;
12145            } else {
12146                pw.println("Unknown argument: " + opt + "; use -h for help");
12147            }
12148        }
12149
12150        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12151        long uptime = SystemClock.uptimeMillis();
12152        long realtime = SystemClock.elapsedRealtime();
12153        final long[] tmpLong = new long[1];
12154
12155        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12156        if (procs == null) {
12157            // No Java processes.  Maybe they want to print a native process.
12158            if (args != null && args.length > opti
12159                    && args[opti].charAt(0) != '-') {
12160                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12161                        = new ArrayList<ProcessCpuTracker.Stats>();
12162                updateCpuStatsNow();
12163                int findPid = -1;
12164                try {
12165                    findPid = Integer.parseInt(args[opti]);
12166                } catch (NumberFormatException e) {
12167                }
12168                synchronized (mProcessCpuThread) {
12169                    final int N = mProcessCpuTracker.countStats();
12170                    for (int i=0; i<N; i++) {
12171                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12172                        if (st.pid == findPid || (st.baseName != null
12173                                && st.baseName.equals(args[opti]))) {
12174                            nativeProcs.add(st);
12175                        }
12176                    }
12177                }
12178                if (nativeProcs.size() > 0) {
12179                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12180                            isCompact);
12181                    Debug.MemoryInfo mi = null;
12182                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12183                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12184                        final int pid = r.pid;
12185                        if (!isCheckinRequest && dumpDetails) {
12186                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12187                        }
12188                        if (mi == null) {
12189                            mi = new Debug.MemoryInfo();
12190                        }
12191                        if (dumpDetails || (!brief && !oomOnly)) {
12192                            Debug.getMemoryInfo(pid, mi);
12193                        } else {
12194                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12195                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12196                        }
12197                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12198                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12199                        if (isCheckinRequest) {
12200                            pw.println();
12201                        }
12202                    }
12203                    return;
12204                }
12205            }
12206            pw.println("No process found for: " + args[opti]);
12207            return;
12208        }
12209
12210        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12211            dumpDetails = true;
12212        }
12213
12214        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12215
12216        String[] innerArgs = new String[args.length-opti];
12217        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12218
12219        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12220        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12221        long nativePss=0, dalvikPss=0, otherPss=0;
12222        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12223
12224        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12225        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12226                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12227
12228        long totalPss = 0;
12229        long cachedPss = 0;
12230
12231        Debug.MemoryInfo mi = null;
12232        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12233            final ProcessRecord r = procs.get(i);
12234            final IApplicationThread thread;
12235            final int pid;
12236            final int oomAdj;
12237            final boolean hasActivities;
12238            synchronized (this) {
12239                thread = r.thread;
12240                pid = r.pid;
12241                oomAdj = r.getSetAdjWithServices();
12242                hasActivities = r.activities.size() > 0;
12243            }
12244            if (thread != null) {
12245                if (!isCheckinRequest && dumpDetails) {
12246                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12247                }
12248                if (mi == null) {
12249                    mi = new Debug.MemoryInfo();
12250                }
12251                if (dumpDetails || (!brief && !oomOnly)) {
12252                    Debug.getMemoryInfo(pid, mi);
12253                } else {
12254                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12255                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12256                }
12257                if (dumpDetails) {
12258                    if (localOnly) {
12259                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12260                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12261                        if (isCheckinRequest) {
12262                            pw.println();
12263                        }
12264                    } else {
12265                        try {
12266                            pw.flush();
12267                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12268                                    dumpDalvik, innerArgs);
12269                        } catch (RemoteException e) {
12270                            if (!isCheckinRequest) {
12271                                pw.println("Got RemoteException!");
12272                                pw.flush();
12273                            }
12274                        }
12275                    }
12276                }
12277
12278                final long myTotalPss = mi.getTotalPss();
12279                final long myTotalUss = mi.getTotalUss();
12280
12281                synchronized (this) {
12282                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12283                        // Record this for posterity if the process has been stable.
12284                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12285                    }
12286                }
12287
12288                if (!isCheckinRequest && mi != null) {
12289                    totalPss += myTotalPss;
12290                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12291                            (hasActivities ? " / activities)" : ")"),
12292                            r.processName, myTotalPss, pid, hasActivities);
12293                    procMems.add(pssItem);
12294                    procMemsMap.put(pid, pssItem);
12295
12296                    nativePss += mi.nativePss;
12297                    dalvikPss += mi.dalvikPss;
12298                    otherPss += mi.otherPss;
12299                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12300                        long mem = mi.getOtherPss(j);
12301                        miscPss[j] += mem;
12302                        otherPss -= mem;
12303                    }
12304
12305                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12306                        cachedPss += myTotalPss;
12307                    }
12308
12309                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12310                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12311                                || oomIndex == (oomPss.length-1)) {
12312                            oomPss[oomIndex] += myTotalPss;
12313                            if (oomProcs[oomIndex] == null) {
12314                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12315                            }
12316                            oomProcs[oomIndex].add(pssItem);
12317                            break;
12318                        }
12319                    }
12320                }
12321            }
12322        }
12323
12324        if (!isCheckinRequest && procs.size() > 1) {
12325            // If we are showing aggregations, also look for native processes to
12326            // include so that our aggregations are more accurate.
12327            updateCpuStatsNow();
12328            synchronized (mProcessCpuThread) {
12329                final int N = mProcessCpuTracker.countStats();
12330                for (int i=0; i<N; i++) {
12331                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12332                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12333                        if (mi == null) {
12334                            mi = new Debug.MemoryInfo();
12335                        }
12336                        if (!brief && !oomOnly) {
12337                            Debug.getMemoryInfo(st.pid, mi);
12338                        } else {
12339                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12340                            mi.nativePrivateDirty = (int)tmpLong[0];
12341                        }
12342
12343                        final long myTotalPss = mi.getTotalPss();
12344                        totalPss += myTotalPss;
12345
12346                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12347                                st.name, myTotalPss, st.pid, false);
12348                        procMems.add(pssItem);
12349
12350                        nativePss += mi.nativePss;
12351                        dalvikPss += mi.dalvikPss;
12352                        otherPss += mi.otherPss;
12353                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12354                            long mem = mi.getOtherPss(j);
12355                            miscPss[j] += mem;
12356                            otherPss -= mem;
12357                        }
12358                        oomPss[0] += myTotalPss;
12359                        if (oomProcs[0] == null) {
12360                            oomProcs[0] = new ArrayList<MemItem>();
12361                        }
12362                        oomProcs[0].add(pssItem);
12363                    }
12364                }
12365            }
12366
12367            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12368
12369            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12370            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12371            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12372            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12373                String label = Debug.MemoryInfo.getOtherLabel(j);
12374                catMems.add(new MemItem(label, label, miscPss[j], j));
12375            }
12376
12377            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12378            for (int j=0; j<oomPss.length; j++) {
12379                if (oomPss[j] != 0) {
12380                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12381                            : DUMP_MEM_OOM_LABEL[j];
12382                    MemItem item = new MemItem(label, label, oomPss[j],
12383                            DUMP_MEM_OOM_ADJ[j]);
12384                    item.subitems = oomProcs[j];
12385                    oomMems.add(item);
12386                }
12387            }
12388
12389            if (!brief && !oomOnly && !isCompact) {
12390                pw.println();
12391                pw.println("Total PSS by process:");
12392                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12393                pw.println();
12394            }
12395            if (!isCompact) {
12396                pw.println("Total PSS by OOM adjustment:");
12397            }
12398            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12399            if (!brief && !oomOnly) {
12400                PrintWriter out = categoryPw != null ? categoryPw : pw;
12401                if (!isCompact) {
12402                    out.println();
12403                    out.println("Total PSS by category:");
12404                }
12405                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12406            }
12407            if (!isCompact) {
12408                pw.println();
12409            }
12410            MemInfoReader memInfo = new MemInfoReader();
12411            memInfo.readMemInfo();
12412            if (!brief) {
12413                if (!isCompact) {
12414                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12415                    pw.print(" kB (status ");
12416                    switch (mLastMemoryLevel) {
12417                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12418                            pw.println("normal)");
12419                            break;
12420                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12421                            pw.println("moderate)");
12422                            break;
12423                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12424                            pw.println("low)");
12425                            break;
12426                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12427                            pw.println("critical)");
12428                            break;
12429                        default:
12430                            pw.print(mLastMemoryLevel);
12431                            pw.println(")");
12432                            break;
12433                    }
12434                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12435                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12436                            pw.print(cachedPss); pw.print(" cached pss + ");
12437                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12438                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12439                } else {
12440                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12441                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12442                            + memInfo.getFreeSizeKb()); pw.print(",");
12443                    pw.println(totalPss - cachedPss);
12444                }
12445            }
12446            if (!isCompact) {
12447                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12448                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12449                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12450                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12451                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12452                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12453                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12454                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12455                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12456                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12457                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12458            }
12459            if (!brief) {
12460                if (memInfo.getZramTotalSizeKb() != 0) {
12461                    if (!isCompact) {
12462                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12463                                pw.print(" kB physical used for ");
12464                                pw.print(memInfo.getSwapTotalSizeKb()
12465                                        - memInfo.getSwapFreeSizeKb());
12466                                pw.print(" kB in swap (");
12467                                pw.print(memInfo.getSwapTotalSizeKb());
12468                                pw.println(" kB total swap)");
12469                    } else {
12470                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12471                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12472                                pw.println(memInfo.getSwapFreeSizeKb());
12473                    }
12474                }
12475                final int[] SINGLE_LONG_FORMAT = new int[] {
12476                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12477                };
12478                long[] longOut = new long[1];
12479                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12480                        SINGLE_LONG_FORMAT, null, longOut, null);
12481                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12482                longOut[0] = 0;
12483                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12484                        SINGLE_LONG_FORMAT, null, longOut, null);
12485                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12486                longOut[0] = 0;
12487                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12488                        SINGLE_LONG_FORMAT, null, longOut, null);
12489                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12490                longOut[0] = 0;
12491                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12492                        SINGLE_LONG_FORMAT, null, longOut, null);
12493                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12494                if (!isCompact) {
12495                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12496                        pw.print("      KSM: "); pw.print(sharing);
12497                                pw.print(" kB saved from shared ");
12498                                pw.print(shared); pw.println(" kB");
12499                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12500                                pw.print(voltile); pw.println(" kB volatile");
12501                    }
12502                    pw.print("   Tuning: ");
12503                    pw.print(ActivityManager.staticGetMemoryClass());
12504                    pw.print(" (large ");
12505                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12506                    pw.print("), oom ");
12507                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12508                    pw.print(" kB");
12509                    pw.print(", restore limit ");
12510                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12511                    pw.print(" kB");
12512                    if (ActivityManager.isLowRamDeviceStatic()) {
12513                        pw.print(" (low-ram)");
12514                    }
12515                    if (ActivityManager.isHighEndGfx()) {
12516                        pw.print(" (high-end-gfx)");
12517                    }
12518                    pw.println();
12519                } else {
12520                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12521                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12522                    pw.println(voltile);
12523                    pw.print("tuning,");
12524                    pw.print(ActivityManager.staticGetMemoryClass());
12525                    pw.print(',');
12526                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12527                    pw.print(',');
12528                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12529                    if (ActivityManager.isLowRamDeviceStatic()) {
12530                        pw.print(",low-ram");
12531                    }
12532                    if (ActivityManager.isHighEndGfx()) {
12533                        pw.print(",high-end-gfx");
12534                    }
12535                    pw.println();
12536                }
12537            }
12538        }
12539    }
12540
12541    /**
12542     * Searches array of arguments for the specified string
12543     * @param args array of argument strings
12544     * @param value value to search for
12545     * @return true if the value is contained in the array
12546     */
12547    private static boolean scanArgs(String[] args, String value) {
12548        if (args != null) {
12549            for (String arg : args) {
12550                if (value.equals(arg)) {
12551                    return true;
12552                }
12553            }
12554        }
12555        return false;
12556    }
12557
12558    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12559            ContentProviderRecord cpr, boolean always) {
12560        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12561
12562        if (!inLaunching || always) {
12563            synchronized (cpr) {
12564                cpr.launchingApp = null;
12565                cpr.notifyAll();
12566            }
12567            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12568            String names[] = cpr.info.authority.split(";");
12569            for (int j = 0; j < names.length; j++) {
12570                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12571            }
12572        }
12573
12574        for (int i=0; i<cpr.connections.size(); i++) {
12575            ContentProviderConnection conn = cpr.connections.get(i);
12576            if (conn.waiting) {
12577                // If this connection is waiting for the provider, then we don't
12578                // need to mess with its process unless we are always removing
12579                // or for some reason the provider is not currently launching.
12580                if (inLaunching && !always) {
12581                    continue;
12582                }
12583            }
12584            ProcessRecord capp = conn.client;
12585            conn.dead = true;
12586            if (conn.stableCount > 0) {
12587                if (!capp.persistent && capp.thread != null
12588                        && capp.pid != 0
12589                        && capp.pid != MY_PID) {
12590                    killUnneededProcessLocked(capp, "depends on provider "
12591                            + cpr.name.flattenToShortString()
12592                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12593                }
12594            } else if (capp.thread != null && conn.provider.provider != null) {
12595                try {
12596                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12597                } catch (RemoteException e) {
12598                }
12599                // In the protocol here, we don't expect the client to correctly
12600                // clean up this connection, we'll just remove it.
12601                cpr.connections.remove(i);
12602                conn.client.conProviders.remove(conn);
12603            }
12604        }
12605
12606        if (inLaunching && always) {
12607            mLaunchingProviders.remove(cpr);
12608        }
12609        return inLaunching;
12610    }
12611
12612    /**
12613     * Main code for cleaning up a process when it has gone away.  This is
12614     * called both as a result of the process dying, or directly when stopping
12615     * a process when running in single process mode.
12616     */
12617    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12618            boolean restarting, boolean allowRestart, int index) {
12619        if (index >= 0) {
12620            removeLruProcessLocked(app);
12621            ProcessList.remove(app.pid);
12622        }
12623
12624        mProcessesToGc.remove(app);
12625        mPendingPssProcesses.remove(app);
12626
12627        // Dismiss any open dialogs.
12628        if (app.crashDialog != null && !app.forceCrashReport) {
12629            app.crashDialog.dismiss();
12630            app.crashDialog = null;
12631        }
12632        if (app.anrDialog != null) {
12633            app.anrDialog.dismiss();
12634            app.anrDialog = null;
12635        }
12636        if (app.waitDialog != null) {
12637            app.waitDialog.dismiss();
12638            app.waitDialog = null;
12639        }
12640
12641        app.crashing = false;
12642        app.notResponding = false;
12643
12644        app.resetPackageList(mProcessStats);
12645        app.unlinkDeathRecipient();
12646        app.makeInactive(mProcessStats);
12647        app.forcingToForeground = null;
12648        updateProcessForegroundLocked(app, false, false);
12649        app.foregroundActivities = false;
12650        app.hasShownUi = false;
12651        app.treatLikeActivity = false;
12652        app.hasAboveClient = false;
12653        app.hasClientActivities = false;
12654
12655        mServices.killServicesLocked(app, allowRestart);
12656
12657        boolean restart = false;
12658
12659        // Remove published content providers.
12660        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12661            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12662            final boolean always = app.bad || !allowRestart;
12663            if (removeDyingProviderLocked(app, cpr, always) || always) {
12664                // We left the provider in the launching list, need to
12665                // restart it.
12666                restart = true;
12667            }
12668
12669            cpr.provider = null;
12670            cpr.proc = null;
12671        }
12672        app.pubProviders.clear();
12673
12674        // Take care of any launching providers waiting for this process.
12675        if (checkAppInLaunchingProvidersLocked(app, false)) {
12676            restart = true;
12677        }
12678
12679        // Unregister from connected content providers.
12680        if (!app.conProviders.isEmpty()) {
12681            for (int i=0; i<app.conProviders.size(); i++) {
12682                ContentProviderConnection conn = app.conProviders.get(i);
12683                conn.provider.connections.remove(conn);
12684            }
12685            app.conProviders.clear();
12686        }
12687
12688        // At this point there may be remaining entries in mLaunchingProviders
12689        // where we were the only one waiting, so they are no longer of use.
12690        // Look for these and clean up if found.
12691        // XXX Commented out for now.  Trying to figure out a way to reproduce
12692        // the actual situation to identify what is actually going on.
12693        if (false) {
12694            for (int i=0; i<mLaunchingProviders.size(); i++) {
12695                ContentProviderRecord cpr = (ContentProviderRecord)
12696                        mLaunchingProviders.get(i);
12697                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12698                    synchronized (cpr) {
12699                        cpr.launchingApp = null;
12700                        cpr.notifyAll();
12701                    }
12702                }
12703            }
12704        }
12705
12706        skipCurrentReceiverLocked(app);
12707
12708        // Unregister any receivers.
12709        for (int i=app.receivers.size()-1; i>=0; i--) {
12710            removeReceiverLocked(app.receivers.valueAt(i));
12711        }
12712        app.receivers.clear();
12713
12714        // If the app is undergoing backup, tell the backup manager about it
12715        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12716            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12717                    + mBackupTarget.appInfo + " died during backup");
12718            try {
12719                IBackupManager bm = IBackupManager.Stub.asInterface(
12720                        ServiceManager.getService(Context.BACKUP_SERVICE));
12721                bm.agentDisconnected(app.info.packageName);
12722            } catch (RemoteException e) {
12723                // can't happen; backup manager is local
12724            }
12725        }
12726
12727        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12728            ProcessChangeItem item = mPendingProcessChanges.get(i);
12729            if (item.pid == app.pid) {
12730                mPendingProcessChanges.remove(i);
12731                mAvailProcessChanges.add(item);
12732            }
12733        }
12734        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12735
12736        // If the caller is restarting this app, then leave it in its
12737        // current lists and let the caller take care of it.
12738        if (restarting) {
12739            return;
12740        }
12741
12742        if (!app.persistent || app.isolated) {
12743            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12744                    "Removing non-persistent process during cleanup: " + app);
12745            mProcessNames.remove(app.processName, app.uid);
12746            mIsolatedProcesses.remove(app.uid);
12747            if (mHeavyWeightProcess == app) {
12748                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12749                        mHeavyWeightProcess.userId, 0));
12750                mHeavyWeightProcess = null;
12751            }
12752        } else if (!app.removed) {
12753            // This app is persistent, so we need to keep its record around.
12754            // If it is not already on the pending app list, add it there
12755            // and start a new process for it.
12756            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12757                mPersistentStartingProcesses.add(app);
12758                restart = true;
12759            }
12760        }
12761        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12762                "Clean-up removing on hold: " + app);
12763        mProcessesOnHold.remove(app);
12764
12765        if (app == mHomeProcess) {
12766            mHomeProcess = null;
12767        }
12768        if (app == mPreviousProcess) {
12769            mPreviousProcess = null;
12770        }
12771
12772        if (restart && !app.isolated) {
12773            // We have components that still need to be running in the
12774            // process, so re-launch it.
12775            mProcessNames.put(app.processName, app.uid, app);
12776            startProcessLocked(app, "restart", app.processName);
12777        } else if (app.pid > 0 && app.pid != MY_PID) {
12778            // Goodbye!
12779            boolean removed;
12780            synchronized (mPidsSelfLocked) {
12781                mPidsSelfLocked.remove(app.pid);
12782                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12783            }
12784            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12785                    app.processName, app.info.uid);
12786            if (app.isolated) {
12787                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12788            }
12789            app.setPid(0);
12790        }
12791    }
12792
12793    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12794        // Look through the content providers we are waiting to have launched,
12795        // and if any run in this process then either schedule a restart of
12796        // the process or kill the client waiting for it if this process has
12797        // gone bad.
12798        int NL = mLaunchingProviders.size();
12799        boolean restart = false;
12800        for (int i=0; i<NL; i++) {
12801            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12802            if (cpr.launchingApp == app) {
12803                if (!alwaysBad && !app.bad) {
12804                    restart = true;
12805                } else {
12806                    removeDyingProviderLocked(app, cpr, true);
12807                    // cpr should have been removed from mLaunchingProviders
12808                    NL = mLaunchingProviders.size();
12809                    i--;
12810                }
12811            }
12812        }
12813        return restart;
12814    }
12815
12816    // =========================================================
12817    // SERVICES
12818    // =========================================================
12819
12820    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12821            int flags) {
12822        enforceNotIsolatedCaller("getServices");
12823        synchronized (this) {
12824            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12825        }
12826    }
12827
12828    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12829        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12830        synchronized (this) {
12831            return mServices.getRunningServiceControlPanelLocked(name);
12832        }
12833    }
12834
12835    public ComponentName startService(IApplicationThread caller, Intent service,
12836            String resolvedType, int userId) {
12837        enforceNotIsolatedCaller("startService");
12838        // Refuse possible leaked file descriptors
12839        if (service != null && service.hasFileDescriptors() == true) {
12840            throw new IllegalArgumentException("File descriptors passed in Intent");
12841        }
12842
12843        if (DEBUG_SERVICE)
12844            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12845        synchronized(this) {
12846            final int callingPid = Binder.getCallingPid();
12847            final int callingUid = Binder.getCallingUid();
12848            final long origId = Binder.clearCallingIdentity();
12849            ComponentName res = mServices.startServiceLocked(caller, service,
12850                    resolvedType, callingPid, callingUid, userId);
12851            Binder.restoreCallingIdentity(origId);
12852            return res;
12853        }
12854    }
12855
12856    ComponentName startServiceInPackage(int uid,
12857            Intent service, String resolvedType, int userId) {
12858        synchronized(this) {
12859            if (DEBUG_SERVICE)
12860                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12861            final long origId = Binder.clearCallingIdentity();
12862            ComponentName res = mServices.startServiceLocked(null, service,
12863                    resolvedType, -1, uid, userId);
12864            Binder.restoreCallingIdentity(origId);
12865            return res;
12866        }
12867    }
12868
12869    public int stopService(IApplicationThread caller, Intent service,
12870            String resolvedType, int userId) {
12871        enforceNotIsolatedCaller("stopService");
12872        // Refuse possible leaked file descriptors
12873        if (service != null && service.hasFileDescriptors() == true) {
12874            throw new IllegalArgumentException("File descriptors passed in Intent");
12875        }
12876
12877        synchronized(this) {
12878            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12879        }
12880    }
12881
12882    public IBinder peekService(Intent service, String resolvedType) {
12883        enforceNotIsolatedCaller("peekService");
12884        // Refuse possible leaked file descriptors
12885        if (service != null && service.hasFileDescriptors() == true) {
12886            throw new IllegalArgumentException("File descriptors passed in Intent");
12887        }
12888        synchronized(this) {
12889            return mServices.peekServiceLocked(service, resolvedType);
12890        }
12891    }
12892
12893    public boolean stopServiceToken(ComponentName className, IBinder token,
12894            int startId) {
12895        synchronized(this) {
12896            return mServices.stopServiceTokenLocked(className, token, startId);
12897        }
12898    }
12899
12900    public void setServiceForeground(ComponentName className, IBinder token,
12901            int id, Notification notification, boolean removeNotification) {
12902        synchronized(this) {
12903            mServices.setServiceForegroundLocked(className, token, id, notification,
12904                    removeNotification);
12905        }
12906    }
12907
12908    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12909            boolean requireFull, String name, String callerPackage) {
12910        final int callingUserId = UserHandle.getUserId(callingUid);
12911        if (callingUserId != userId) {
12912            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12913                if ((requireFull || checkComponentPermission(
12914                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12915                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12916                        && checkComponentPermission(
12917                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12918                                callingPid, callingUid, -1, true)
12919                                != PackageManager.PERMISSION_GRANTED) {
12920                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12921                        // In this case, they would like to just execute as their
12922                        // owner user instead of failing.
12923                        userId = callingUserId;
12924                    } else {
12925                        StringBuilder builder = new StringBuilder(128);
12926                        builder.append("Permission Denial: ");
12927                        builder.append(name);
12928                        if (callerPackage != null) {
12929                            builder.append(" from ");
12930                            builder.append(callerPackage);
12931                        }
12932                        builder.append(" asks to run as user ");
12933                        builder.append(userId);
12934                        builder.append(" but is calling from user ");
12935                        builder.append(UserHandle.getUserId(callingUid));
12936                        builder.append("; this requires ");
12937                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12938                        if (!requireFull) {
12939                            builder.append(" or ");
12940                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12941                        }
12942                        String msg = builder.toString();
12943                        Slog.w(TAG, msg);
12944                        throw new SecurityException(msg);
12945                    }
12946                }
12947            }
12948            if (userId == UserHandle.USER_CURRENT
12949                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12950                // Note that we may be accessing this outside of a lock...
12951                // shouldn't be a big deal, if this is being called outside
12952                // of a locked context there is intrinsically a race with
12953                // the value the caller will receive and someone else changing it.
12954                userId = mCurrentUserId;
12955            }
12956            if (!allowAll && userId < 0) {
12957                throw new IllegalArgumentException(
12958                        "Call does not support special user #" + userId);
12959            }
12960        }
12961        return userId;
12962    }
12963
12964    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12965            String className, int flags) {
12966        boolean result = false;
12967        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12968            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12969                if (ActivityManager.checkUidPermission(
12970                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12971                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12972                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12973                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12974                            + " requests FLAG_SINGLE_USER, but app does not hold "
12975                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12976                    Slog.w(TAG, msg);
12977                    throw new SecurityException(msg);
12978                }
12979                result = true;
12980            }
12981        } else if (componentProcessName == aInfo.packageName) {
12982            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12983        } else if ("system".equals(componentProcessName)) {
12984            result = true;
12985        }
12986        if (DEBUG_MU) {
12987            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12988                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12989        }
12990        return result;
12991    }
12992
12993    public int bindService(IApplicationThread caller, IBinder token,
12994            Intent service, String resolvedType,
12995            IServiceConnection connection, int flags, int userId) {
12996        enforceNotIsolatedCaller("bindService");
12997        // Refuse possible leaked file descriptors
12998        if (service != null && service.hasFileDescriptors() == true) {
12999            throw new IllegalArgumentException("File descriptors passed in Intent");
13000        }
13001
13002        synchronized(this) {
13003            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13004                    connection, flags, userId);
13005        }
13006    }
13007
13008    public boolean unbindService(IServiceConnection connection) {
13009        synchronized (this) {
13010            return mServices.unbindServiceLocked(connection);
13011        }
13012    }
13013
13014    public void publishService(IBinder token, Intent intent, IBinder service) {
13015        // Refuse possible leaked file descriptors
13016        if (intent != null && intent.hasFileDescriptors() == true) {
13017            throw new IllegalArgumentException("File descriptors passed in Intent");
13018        }
13019
13020        synchronized(this) {
13021            if (!(token instanceof ServiceRecord)) {
13022                throw new IllegalArgumentException("Invalid service token");
13023            }
13024            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13025        }
13026    }
13027
13028    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13029        // Refuse possible leaked file descriptors
13030        if (intent != null && intent.hasFileDescriptors() == true) {
13031            throw new IllegalArgumentException("File descriptors passed in Intent");
13032        }
13033
13034        synchronized(this) {
13035            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13036        }
13037    }
13038
13039    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13040        synchronized(this) {
13041            if (!(token instanceof ServiceRecord)) {
13042                throw new IllegalArgumentException("Invalid service token");
13043            }
13044            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13045        }
13046    }
13047
13048    // =========================================================
13049    // BACKUP AND RESTORE
13050    // =========================================================
13051
13052    // Cause the target app to be launched if necessary and its backup agent
13053    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13054    // activity manager to announce its creation.
13055    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13056        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13057        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13058
13059        synchronized(this) {
13060            // !!! TODO: currently no check here that we're already bound
13061            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13062            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13063            synchronized (stats) {
13064                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13065            }
13066
13067            // Backup agent is now in use, its package can't be stopped.
13068            try {
13069                AppGlobals.getPackageManager().setPackageStoppedState(
13070                        app.packageName, false, UserHandle.getUserId(app.uid));
13071            } catch (RemoteException e) {
13072            } catch (IllegalArgumentException e) {
13073                Slog.w(TAG, "Failed trying to unstop package "
13074                        + app.packageName + ": " + e);
13075            }
13076
13077            BackupRecord r = new BackupRecord(ss, app, backupMode);
13078            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13079                    ? new ComponentName(app.packageName, app.backupAgentName)
13080                    : new ComponentName("android", "FullBackupAgent");
13081            // startProcessLocked() returns existing proc's record if it's already running
13082            ProcessRecord proc = startProcessLocked(app.processName, app,
13083                    false, 0, "backup", hostingName, false, false, false);
13084            if (proc == null) {
13085                Slog.e(TAG, "Unable to start backup agent process " + r);
13086                return false;
13087            }
13088
13089            r.app = proc;
13090            mBackupTarget = r;
13091            mBackupAppName = app.packageName;
13092
13093            // Try not to kill the process during backup
13094            updateOomAdjLocked(proc);
13095
13096            // If the process is already attached, schedule the creation of the backup agent now.
13097            // If it is not yet live, this will be done when it attaches to the framework.
13098            if (proc.thread != null) {
13099                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13100                try {
13101                    proc.thread.scheduleCreateBackupAgent(app,
13102                            compatibilityInfoForPackageLocked(app), backupMode);
13103                } catch (RemoteException e) {
13104                    // Will time out on the backup manager side
13105                }
13106            } else {
13107                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13108            }
13109            // Invariants: at this point, the target app process exists and the application
13110            // is either already running or in the process of coming up.  mBackupTarget and
13111            // mBackupAppName describe the app, so that when it binds back to the AM we
13112            // know that it's scheduled for a backup-agent operation.
13113        }
13114
13115        return true;
13116    }
13117
13118    @Override
13119    public void clearPendingBackup() {
13120        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13121        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13122
13123        synchronized (this) {
13124            mBackupTarget = null;
13125            mBackupAppName = null;
13126        }
13127    }
13128
13129    // A backup agent has just come up
13130    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13131        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13132                + " = " + agent);
13133
13134        synchronized(this) {
13135            if (!agentPackageName.equals(mBackupAppName)) {
13136                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13137                return;
13138            }
13139        }
13140
13141        long oldIdent = Binder.clearCallingIdentity();
13142        try {
13143            IBackupManager bm = IBackupManager.Stub.asInterface(
13144                    ServiceManager.getService(Context.BACKUP_SERVICE));
13145            bm.agentConnected(agentPackageName, agent);
13146        } catch (RemoteException e) {
13147            // can't happen; the backup manager service is local
13148        } catch (Exception e) {
13149            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13150            e.printStackTrace();
13151        } finally {
13152            Binder.restoreCallingIdentity(oldIdent);
13153        }
13154    }
13155
13156    // done with this agent
13157    public void unbindBackupAgent(ApplicationInfo appInfo) {
13158        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13159        if (appInfo == null) {
13160            Slog.w(TAG, "unbind backup agent for null app");
13161            return;
13162        }
13163
13164        synchronized(this) {
13165            try {
13166                if (mBackupAppName == null) {
13167                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13168                    return;
13169                }
13170
13171                if (!mBackupAppName.equals(appInfo.packageName)) {
13172                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13173                    return;
13174                }
13175
13176                // Not backing this app up any more; reset its OOM adjustment
13177                final ProcessRecord proc = mBackupTarget.app;
13178                updateOomAdjLocked(proc);
13179
13180                // If the app crashed during backup, 'thread' will be null here
13181                if (proc.thread != null) {
13182                    try {
13183                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13184                                compatibilityInfoForPackageLocked(appInfo));
13185                    } catch (Exception e) {
13186                        Slog.e(TAG, "Exception when unbinding backup agent:");
13187                        e.printStackTrace();
13188                    }
13189                }
13190            } finally {
13191                mBackupTarget = null;
13192                mBackupAppName = null;
13193            }
13194        }
13195    }
13196    // =========================================================
13197    // BROADCASTS
13198    // =========================================================
13199
13200    private final List getStickiesLocked(String action, IntentFilter filter,
13201            List cur, int userId) {
13202        final ContentResolver resolver = mContext.getContentResolver();
13203        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13204        if (stickies == null) {
13205            return cur;
13206        }
13207        final ArrayList<Intent> list = stickies.get(action);
13208        if (list == null) {
13209            return cur;
13210        }
13211        int N = list.size();
13212        for (int i=0; i<N; i++) {
13213            Intent intent = list.get(i);
13214            if (filter.match(resolver, intent, true, TAG) >= 0) {
13215                if (cur == null) {
13216                    cur = new ArrayList<Intent>();
13217                }
13218                cur.add(intent);
13219            }
13220        }
13221        return cur;
13222    }
13223
13224    boolean isPendingBroadcastProcessLocked(int pid) {
13225        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13226                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13227    }
13228
13229    void skipPendingBroadcastLocked(int pid) {
13230            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13231            for (BroadcastQueue queue : mBroadcastQueues) {
13232                queue.skipPendingBroadcastLocked(pid);
13233            }
13234    }
13235
13236    // The app just attached; send any pending broadcasts that it should receive
13237    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13238        boolean didSomething = false;
13239        for (BroadcastQueue queue : mBroadcastQueues) {
13240            didSomething |= queue.sendPendingBroadcastsLocked(app);
13241        }
13242        return didSomething;
13243    }
13244
13245    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13246            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13247        enforceNotIsolatedCaller("registerReceiver");
13248        int callingUid;
13249        int callingPid;
13250        synchronized(this) {
13251            ProcessRecord callerApp = null;
13252            if (caller != null) {
13253                callerApp = getRecordForAppLocked(caller);
13254                if (callerApp == null) {
13255                    throw new SecurityException(
13256                            "Unable to find app for caller " + caller
13257                            + " (pid=" + Binder.getCallingPid()
13258                            + ") when registering receiver " + receiver);
13259                }
13260                if (callerApp.info.uid != Process.SYSTEM_UID &&
13261                        !callerApp.pkgList.containsKey(callerPackage) &&
13262                        !"android".equals(callerPackage)) {
13263                    throw new SecurityException("Given caller package " + callerPackage
13264                            + " is not running in process " + callerApp);
13265                }
13266                callingUid = callerApp.info.uid;
13267                callingPid = callerApp.pid;
13268            } else {
13269                callerPackage = null;
13270                callingUid = Binder.getCallingUid();
13271                callingPid = Binder.getCallingPid();
13272            }
13273
13274            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13275                    true, true, "registerReceiver", callerPackage);
13276
13277            List allSticky = null;
13278
13279            // Look for any matching sticky broadcasts...
13280            Iterator actions = filter.actionsIterator();
13281            if (actions != null) {
13282                while (actions.hasNext()) {
13283                    String action = (String)actions.next();
13284                    allSticky = getStickiesLocked(action, filter, allSticky,
13285                            UserHandle.USER_ALL);
13286                    allSticky = getStickiesLocked(action, filter, allSticky,
13287                            UserHandle.getUserId(callingUid));
13288                }
13289            } else {
13290                allSticky = getStickiesLocked(null, filter, allSticky,
13291                        UserHandle.USER_ALL);
13292                allSticky = getStickiesLocked(null, filter, allSticky,
13293                        UserHandle.getUserId(callingUid));
13294            }
13295
13296            // The first sticky in the list is returned directly back to
13297            // the client.
13298            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13299
13300            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13301                    + ": " + sticky);
13302
13303            if (receiver == null) {
13304                return sticky;
13305            }
13306
13307            ReceiverList rl
13308                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13309            if (rl == null) {
13310                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13311                        userId, receiver);
13312                if (rl.app != null) {
13313                    rl.app.receivers.add(rl);
13314                } else {
13315                    try {
13316                        receiver.asBinder().linkToDeath(rl, 0);
13317                    } catch (RemoteException e) {
13318                        return sticky;
13319                    }
13320                    rl.linkedToDeath = true;
13321                }
13322                mRegisteredReceivers.put(receiver.asBinder(), rl);
13323            } else if (rl.uid != callingUid) {
13324                throw new IllegalArgumentException(
13325                        "Receiver requested to register for uid " + callingUid
13326                        + " was previously registered for uid " + rl.uid);
13327            } else if (rl.pid != callingPid) {
13328                throw new IllegalArgumentException(
13329                        "Receiver requested to register for pid " + callingPid
13330                        + " was previously registered for pid " + rl.pid);
13331            } else if (rl.userId != userId) {
13332                throw new IllegalArgumentException(
13333                        "Receiver requested to register for user " + userId
13334                        + " was previously registered for user " + rl.userId);
13335            }
13336            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13337                    permission, callingUid, userId);
13338            rl.add(bf);
13339            if (!bf.debugCheck()) {
13340                Slog.w(TAG, "==> For Dynamic broadast");
13341            }
13342            mReceiverResolver.addFilter(bf);
13343
13344            // Enqueue broadcasts for all existing stickies that match
13345            // this filter.
13346            if (allSticky != null) {
13347                ArrayList receivers = new ArrayList();
13348                receivers.add(bf);
13349
13350                int N = allSticky.size();
13351                for (int i=0; i<N; i++) {
13352                    Intent intent = (Intent)allSticky.get(i);
13353                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13354                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13355                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13356                            null, null, false, true, true, -1);
13357                    queue.enqueueParallelBroadcastLocked(r);
13358                    queue.scheduleBroadcastsLocked();
13359                }
13360            }
13361
13362            return sticky;
13363        }
13364    }
13365
13366    public void unregisterReceiver(IIntentReceiver receiver) {
13367        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13368
13369        final long origId = Binder.clearCallingIdentity();
13370        try {
13371            boolean doTrim = false;
13372
13373            synchronized(this) {
13374                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13375                if (rl != null) {
13376                    if (rl.curBroadcast != null) {
13377                        BroadcastRecord r = rl.curBroadcast;
13378                        final boolean doNext = finishReceiverLocked(
13379                                receiver.asBinder(), r.resultCode, r.resultData,
13380                                r.resultExtras, r.resultAbort);
13381                        if (doNext) {
13382                            doTrim = true;
13383                            r.queue.processNextBroadcast(false);
13384                        }
13385                    }
13386
13387                    if (rl.app != null) {
13388                        rl.app.receivers.remove(rl);
13389                    }
13390                    removeReceiverLocked(rl);
13391                    if (rl.linkedToDeath) {
13392                        rl.linkedToDeath = false;
13393                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13394                    }
13395                }
13396            }
13397
13398            // If we actually concluded any broadcasts, we might now be able
13399            // to trim the recipients' apps from our working set
13400            if (doTrim) {
13401                trimApplications();
13402                return;
13403            }
13404
13405        } finally {
13406            Binder.restoreCallingIdentity(origId);
13407        }
13408    }
13409
13410    void removeReceiverLocked(ReceiverList rl) {
13411        mRegisteredReceivers.remove(rl.receiver.asBinder());
13412        int N = rl.size();
13413        for (int i=0; i<N; i++) {
13414            mReceiverResolver.removeFilter(rl.get(i));
13415        }
13416    }
13417
13418    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13419        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13420            ProcessRecord r = mLruProcesses.get(i);
13421            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13422                try {
13423                    r.thread.dispatchPackageBroadcast(cmd, packages);
13424                } catch (RemoteException ex) {
13425                }
13426            }
13427        }
13428    }
13429
13430    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13431            int[] users) {
13432        List<ResolveInfo> receivers = null;
13433        try {
13434            HashSet<ComponentName> singleUserReceivers = null;
13435            boolean scannedFirstReceivers = false;
13436            for (int user : users) {
13437                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13438                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13439                if (user != 0 && newReceivers != null) {
13440                    // If this is not the primary user, we need to check for
13441                    // any receivers that should be filtered out.
13442                    for (int i=0; i<newReceivers.size(); i++) {
13443                        ResolveInfo ri = newReceivers.get(i);
13444                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13445                            newReceivers.remove(i);
13446                            i--;
13447                        }
13448                    }
13449                }
13450                if (newReceivers != null && newReceivers.size() == 0) {
13451                    newReceivers = null;
13452                }
13453                if (receivers == null) {
13454                    receivers = newReceivers;
13455                } else if (newReceivers != null) {
13456                    // We need to concatenate the additional receivers
13457                    // found with what we have do far.  This would be easy,
13458                    // but we also need to de-dup any receivers that are
13459                    // singleUser.
13460                    if (!scannedFirstReceivers) {
13461                        // Collect any single user receivers we had already retrieved.
13462                        scannedFirstReceivers = true;
13463                        for (int i=0; i<receivers.size(); i++) {
13464                            ResolveInfo ri = receivers.get(i);
13465                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13466                                ComponentName cn = new ComponentName(
13467                                        ri.activityInfo.packageName, ri.activityInfo.name);
13468                                if (singleUserReceivers == null) {
13469                                    singleUserReceivers = new HashSet<ComponentName>();
13470                                }
13471                                singleUserReceivers.add(cn);
13472                            }
13473                        }
13474                    }
13475                    // Add the new results to the existing results, tracking
13476                    // and de-dupping single user receivers.
13477                    for (int i=0; i<newReceivers.size(); i++) {
13478                        ResolveInfo ri = newReceivers.get(i);
13479                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13480                            ComponentName cn = new ComponentName(
13481                                    ri.activityInfo.packageName, ri.activityInfo.name);
13482                            if (singleUserReceivers == null) {
13483                                singleUserReceivers = new HashSet<ComponentName>();
13484                            }
13485                            if (!singleUserReceivers.contains(cn)) {
13486                                singleUserReceivers.add(cn);
13487                                receivers.add(ri);
13488                            }
13489                        } else {
13490                            receivers.add(ri);
13491                        }
13492                    }
13493                }
13494            }
13495        } catch (RemoteException ex) {
13496            // pm is in same process, this will never happen.
13497        }
13498        return receivers;
13499    }
13500
13501    private final int broadcastIntentLocked(ProcessRecord callerApp,
13502            String callerPackage, Intent intent, String resolvedType,
13503            IIntentReceiver resultTo, int resultCode, String resultData,
13504            Bundle map, String requiredPermission, int appOp,
13505            boolean ordered, boolean sticky, int callingPid, int callingUid,
13506            int userId) {
13507        intent = new Intent(intent);
13508
13509        // By default broadcasts do not go to stopped apps.
13510        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13511
13512        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13513            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13514            + " ordered=" + ordered + " userid=" + userId);
13515        if ((resultTo != null) && !ordered) {
13516            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13517        }
13518
13519        userId = handleIncomingUser(callingPid, callingUid, userId,
13520                true, false, "broadcast", callerPackage);
13521
13522        // Make sure that the user who is receiving this broadcast is started.
13523        // If not, we will just skip it.
13524        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13525            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13526                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13527                Slog.w(TAG, "Skipping broadcast of " + intent
13528                        + ": user " + userId + " is stopped");
13529                return ActivityManager.BROADCAST_SUCCESS;
13530            }
13531        }
13532
13533        /*
13534         * Prevent non-system code (defined here to be non-persistent
13535         * processes) from sending protected broadcasts.
13536         */
13537        int callingAppId = UserHandle.getAppId(callingUid);
13538        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13539            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13540            callingUid == 0) {
13541            // Always okay.
13542        } else if (callerApp == null || !callerApp.persistent) {
13543            try {
13544                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13545                        intent.getAction())) {
13546                    String msg = "Permission Denial: not allowed to send broadcast "
13547                            + intent.getAction() + " from pid="
13548                            + callingPid + ", uid=" + callingUid;
13549                    Slog.w(TAG, msg);
13550                    throw new SecurityException(msg);
13551                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13552                    // Special case for compatibility: we don't want apps to send this,
13553                    // but historically it has not been protected and apps may be using it
13554                    // to poke their own app widget.  So, instead of making it protected,
13555                    // just limit it to the caller.
13556                    if (callerApp == null) {
13557                        String msg = "Permission Denial: not allowed to send broadcast "
13558                                + intent.getAction() + " from unknown caller.";
13559                        Slog.w(TAG, msg);
13560                        throw new SecurityException(msg);
13561                    } else if (intent.getComponent() != null) {
13562                        // They are good enough to send to an explicit component...  verify
13563                        // it is being sent to the calling app.
13564                        if (!intent.getComponent().getPackageName().equals(
13565                                callerApp.info.packageName)) {
13566                            String msg = "Permission Denial: not allowed to send broadcast "
13567                                    + intent.getAction() + " to "
13568                                    + intent.getComponent().getPackageName() + " from "
13569                                    + callerApp.info.packageName;
13570                            Slog.w(TAG, msg);
13571                            throw new SecurityException(msg);
13572                        }
13573                    } else {
13574                        // Limit broadcast to their own package.
13575                        intent.setPackage(callerApp.info.packageName);
13576                    }
13577                }
13578            } catch (RemoteException e) {
13579                Slog.w(TAG, "Remote exception", e);
13580                return ActivityManager.BROADCAST_SUCCESS;
13581            }
13582        }
13583
13584        // Handle special intents: if this broadcast is from the package
13585        // manager about a package being removed, we need to remove all of
13586        // its activities from the history stack.
13587        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13588                intent.getAction());
13589        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13590                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13591                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13592                || uidRemoved) {
13593            if (checkComponentPermission(
13594                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13595                    callingPid, callingUid, -1, true)
13596                    == PackageManager.PERMISSION_GRANTED) {
13597                if (uidRemoved) {
13598                    final Bundle intentExtras = intent.getExtras();
13599                    final int uid = intentExtras != null
13600                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13601                    if (uid >= 0) {
13602                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13603                        synchronized (bs) {
13604                            bs.removeUidStatsLocked(uid);
13605                        }
13606                        mAppOpsService.uidRemoved(uid);
13607                    }
13608                } else {
13609                    // If resources are unavailable just force stop all
13610                    // those packages and flush the attribute cache as well.
13611                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13612                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13613                        if (list != null && (list.length > 0)) {
13614                            for (String pkg : list) {
13615                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13616                                        "storage unmount");
13617                            }
13618                            sendPackageBroadcastLocked(
13619                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13620                        }
13621                    } else {
13622                        Uri data = intent.getData();
13623                        String ssp;
13624                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13625                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13626                                    intent.getAction());
13627                            boolean fullUninstall = removed &&
13628                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13629                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13630                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13631                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13632                                        false, fullUninstall, userId,
13633                                        removed ? "pkg removed" : "pkg changed");
13634                            }
13635                            if (removed) {
13636                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13637                                        new String[] {ssp}, userId);
13638                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13639                                    mAppOpsService.packageRemoved(
13640                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13641
13642                                    // Remove all permissions granted from/to this package
13643                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13644                                }
13645                            }
13646                        }
13647                    }
13648                }
13649            } else {
13650                String msg = "Permission Denial: " + intent.getAction()
13651                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13652                        + ", uid=" + callingUid + ")"
13653                        + " requires "
13654                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13655                Slog.w(TAG, msg);
13656                throw new SecurityException(msg);
13657            }
13658
13659        // Special case for adding a package: by default turn on compatibility
13660        // mode.
13661        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13662            Uri data = intent.getData();
13663            String ssp;
13664            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13665                mCompatModePackages.handlePackageAddedLocked(ssp,
13666                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13667            }
13668        }
13669
13670        /*
13671         * If this is the time zone changed action, queue up a message that will reset the timezone
13672         * of all currently running processes. This message will get queued up before the broadcast
13673         * happens.
13674         */
13675        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13676            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13677        }
13678
13679        /*
13680         * If the user set the time, let all running processes know.
13681         */
13682        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13683            final int is24Hour = intent.getBooleanExtra(
13684                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13685            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13686        }
13687
13688        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13689            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13690        }
13691
13692        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13693            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13694            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13695        }
13696
13697        // Add to the sticky list if requested.
13698        if (sticky) {
13699            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13700                    callingPid, callingUid)
13701                    != PackageManager.PERMISSION_GRANTED) {
13702                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13703                        + callingPid + ", uid=" + callingUid
13704                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13705                Slog.w(TAG, msg);
13706                throw new SecurityException(msg);
13707            }
13708            if (requiredPermission != null) {
13709                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13710                        + " and enforce permission " + requiredPermission);
13711                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13712            }
13713            if (intent.getComponent() != null) {
13714                throw new SecurityException(
13715                        "Sticky broadcasts can't target a specific component");
13716            }
13717            // We use userId directly here, since the "all" target is maintained
13718            // as a separate set of sticky broadcasts.
13719            if (userId != UserHandle.USER_ALL) {
13720                // But first, if this is not a broadcast to all users, then
13721                // make sure it doesn't conflict with an existing broadcast to
13722                // all users.
13723                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13724                        UserHandle.USER_ALL);
13725                if (stickies != null) {
13726                    ArrayList<Intent> list = stickies.get(intent.getAction());
13727                    if (list != null) {
13728                        int N = list.size();
13729                        int i;
13730                        for (i=0; i<N; i++) {
13731                            if (intent.filterEquals(list.get(i))) {
13732                                throw new IllegalArgumentException(
13733                                        "Sticky broadcast " + intent + " for user "
13734                                        + userId + " conflicts with existing global broadcast");
13735                            }
13736                        }
13737                    }
13738                }
13739            }
13740            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13741            if (stickies == null) {
13742                stickies = new ArrayMap<String, ArrayList<Intent>>();
13743                mStickyBroadcasts.put(userId, stickies);
13744            }
13745            ArrayList<Intent> list = stickies.get(intent.getAction());
13746            if (list == null) {
13747                list = new ArrayList<Intent>();
13748                stickies.put(intent.getAction(), list);
13749            }
13750            int N = list.size();
13751            int i;
13752            for (i=0; i<N; i++) {
13753                if (intent.filterEquals(list.get(i))) {
13754                    // This sticky already exists, replace it.
13755                    list.set(i, new Intent(intent));
13756                    break;
13757                }
13758            }
13759            if (i >= N) {
13760                list.add(new Intent(intent));
13761            }
13762        }
13763
13764        int[] users;
13765        if (userId == UserHandle.USER_ALL) {
13766            // Caller wants broadcast to go to all started users.
13767            users = mStartedUserArray;
13768        } else {
13769            // Caller wants broadcast to go to one specific user.
13770            users = new int[] {userId};
13771        }
13772
13773        // Figure out who all will receive this broadcast.
13774        List receivers = null;
13775        List<BroadcastFilter> registeredReceivers = null;
13776        // Need to resolve the intent to interested receivers...
13777        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13778                 == 0) {
13779            receivers = collectReceiverComponents(intent, resolvedType, users);
13780        }
13781        if (intent.getComponent() == null) {
13782            registeredReceivers = mReceiverResolver.queryIntent(intent,
13783                    resolvedType, false, userId);
13784        }
13785
13786        final boolean replacePending =
13787                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13788
13789        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13790                + " replacePending=" + replacePending);
13791
13792        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13793        if (!ordered && NR > 0) {
13794            // If we are not serializing this broadcast, then send the
13795            // registered receivers separately so they don't wait for the
13796            // components to be launched.
13797            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13798            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13799                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13800                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13801                    ordered, sticky, false, userId);
13802            if (DEBUG_BROADCAST) Slog.v(
13803                    TAG, "Enqueueing parallel broadcast " + r);
13804            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13805            if (!replaced) {
13806                queue.enqueueParallelBroadcastLocked(r);
13807                queue.scheduleBroadcastsLocked();
13808            }
13809            registeredReceivers = null;
13810            NR = 0;
13811        }
13812
13813        // Merge into one list.
13814        int ir = 0;
13815        if (receivers != null) {
13816            // A special case for PACKAGE_ADDED: do not allow the package
13817            // being added to see this broadcast.  This prevents them from
13818            // using this as a back door to get run as soon as they are
13819            // installed.  Maybe in the future we want to have a special install
13820            // broadcast or such for apps, but we'd like to deliberately make
13821            // this decision.
13822            String skipPackages[] = null;
13823            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13824                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13825                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13826                Uri data = intent.getData();
13827                if (data != null) {
13828                    String pkgName = data.getSchemeSpecificPart();
13829                    if (pkgName != null) {
13830                        skipPackages = new String[] { pkgName };
13831                    }
13832                }
13833            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13834                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13835            }
13836            if (skipPackages != null && (skipPackages.length > 0)) {
13837                for (String skipPackage : skipPackages) {
13838                    if (skipPackage != null) {
13839                        int NT = receivers.size();
13840                        for (int it=0; it<NT; it++) {
13841                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13842                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13843                                receivers.remove(it);
13844                                it--;
13845                                NT--;
13846                            }
13847                        }
13848                    }
13849                }
13850            }
13851
13852            int NT = receivers != null ? receivers.size() : 0;
13853            int it = 0;
13854            ResolveInfo curt = null;
13855            BroadcastFilter curr = null;
13856            while (it < NT && ir < NR) {
13857                if (curt == null) {
13858                    curt = (ResolveInfo)receivers.get(it);
13859                }
13860                if (curr == null) {
13861                    curr = registeredReceivers.get(ir);
13862                }
13863                if (curr.getPriority() >= curt.priority) {
13864                    // Insert this broadcast record into the final list.
13865                    receivers.add(it, curr);
13866                    ir++;
13867                    curr = null;
13868                    it++;
13869                    NT++;
13870                } else {
13871                    // Skip to the next ResolveInfo in the final list.
13872                    it++;
13873                    curt = null;
13874                }
13875            }
13876        }
13877        while (ir < NR) {
13878            if (receivers == null) {
13879                receivers = new ArrayList();
13880            }
13881            receivers.add(registeredReceivers.get(ir));
13882            ir++;
13883        }
13884
13885        if ((receivers != null && receivers.size() > 0)
13886                || resultTo != null) {
13887            BroadcastQueue queue = broadcastQueueForIntent(intent);
13888            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13889                    callerPackage, callingPid, callingUid, resolvedType,
13890                    requiredPermission, appOp, receivers, resultTo, resultCode,
13891                    resultData, map, ordered, sticky, false, userId);
13892            if (DEBUG_BROADCAST) Slog.v(
13893                    TAG, "Enqueueing ordered broadcast " + r
13894                    + ": prev had " + queue.mOrderedBroadcasts.size());
13895            if (DEBUG_BROADCAST) {
13896                int seq = r.intent.getIntExtra("seq", -1);
13897                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13898            }
13899            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13900            if (!replaced) {
13901                queue.enqueueOrderedBroadcastLocked(r);
13902                queue.scheduleBroadcastsLocked();
13903            }
13904        }
13905
13906        return ActivityManager.BROADCAST_SUCCESS;
13907    }
13908
13909    final Intent verifyBroadcastLocked(Intent intent) {
13910        // Refuse possible leaked file descriptors
13911        if (intent != null && intent.hasFileDescriptors() == true) {
13912            throw new IllegalArgumentException("File descriptors passed in Intent");
13913        }
13914
13915        int flags = intent.getFlags();
13916
13917        if (!mProcessesReady) {
13918            // if the caller really truly claims to know what they're doing, go
13919            // ahead and allow the broadcast without launching any receivers
13920            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13921                intent = new Intent(intent);
13922                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13923            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13924                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13925                        + " before boot completion");
13926                throw new IllegalStateException("Cannot broadcast before boot completed");
13927            }
13928        }
13929
13930        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13931            throw new IllegalArgumentException(
13932                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13933        }
13934
13935        return intent;
13936    }
13937
13938    public final int broadcastIntent(IApplicationThread caller,
13939            Intent intent, String resolvedType, IIntentReceiver resultTo,
13940            int resultCode, String resultData, Bundle map,
13941            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13942        enforceNotIsolatedCaller("broadcastIntent");
13943        synchronized(this) {
13944            intent = verifyBroadcastLocked(intent);
13945
13946            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13947            final int callingPid = Binder.getCallingPid();
13948            final int callingUid = Binder.getCallingUid();
13949            final long origId = Binder.clearCallingIdentity();
13950            int res = broadcastIntentLocked(callerApp,
13951                    callerApp != null ? callerApp.info.packageName : null,
13952                    intent, resolvedType, resultTo,
13953                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13954                    callingPid, callingUid, userId);
13955            Binder.restoreCallingIdentity(origId);
13956            return res;
13957        }
13958    }
13959
13960    int broadcastIntentInPackage(String packageName, int uid,
13961            Intent intent, String resolvedType, IIntentReceiver resultTo,
13962            int resultCode, String resultData, Bundle map,
13963            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13964        synchronized(this) {
13965            intent = verifyBroadcastLocked(intent);
13966
13967            final long origId = Binder.clearCallingIdentity();
13968            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13969                    resultTo, resultCode, resultData, map, requiredPermission,
13970                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13971            Binder.restoreCallingIdentity(origId);
13972            return res;
13973        }
13974    }
13975
13976    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13977        // Refuse possible leaked file descriptors
13978        if (intent != null && intent.hasFileDescriptors() == true) {
13979            throw new IllegalArgumentException("File descriptors passed in Intent");
13980        }
13981
13982        userId = handleIncomingUser(Binder.getCallingPid(),
13983                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13984
13985        synchronized(this) {
13986            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13987                    != PackageManager.PERMISSION_GRANTED) {
13988                String msg = "Permission Denial: unbroadcastIntent() from pid="
13989                        + Binder.getCallingPid()
13990                        + ", uid=" + Binder.getCallingUid()
13991                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13992                Slog.w(TAG, msg);
13993                throw new SecurityException(msg);
13994            }
13995            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13996            if (stickies != null) {
13997                ArrayList<Intent> list = stickies.get(intent.getAction());
13998                if (list != null) {
13999                    int N = list.size();
14000                    int i;
14001                    for (i=0; i<N; i++) {
14002                        if (intent.filterEquals(list.get(i))) {
14003                            list.remove(i);
14004                            break;
14005                        }
14006                    }
14007                    if (list.size() <= 0) {
14008                        stickies.remove(intent.getAction());
14009                    }
14010                }
14011                if (stickies.size() <= 0) {
14012                    mStickyBroadcasts.remove(userId);
14013                }
14014            }
14015        }
14016    }
14017
14018    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14019            String resultData, Bundle resultExtras, boolean resultAbort) {
14020        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14021        if (r == null) {
14022            Slog.w(TAG, "finishReceiver called but not found on queue");
14023            return false;
14024        }
14025
14026        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14027    }
14028
14029    void backgroundServicesFinishedLocked(int userId) {
14030        for (BroadcastQueue queue : mBroadcastQueues) {
14031            queue.backgroundServicesFinishedLocked(userId);
14032        }
14033    }
14034
14035    public void finishReceiver(IBinder who, int resultCode, String resultData,
14036            Bundle resultExtras, boolean resultAbort) {
14037        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14038
14039        // Refuse possible leaked file descriptors
14040        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14041            throw new IllegalArgumentException("File descriptors passed in Bundle");
14042        }
14043
14044        final long origId = Binder.clearCallingIdentity();
14045        try {
14046            boolean doNext = false;
14047            BroadcastRecord r;
14048
14049            synchronized(this) {
14050                r = broadcastRecordForReceiverLocked(who);
14051                if (r != null) {
14052                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14053                        resultData, resultExtras, resultAbort, true);
14054                }
14055            }
14056
14057            if (doNext) {
14058                r.queue.processNextBroadcast(false);
14059            }
14060            trimApplications();
14061        } finally {
14062            Binder.restoreCallingIdentity(origId);
14063        }
14064    }
14065
14066    // =========================================================
14067    // INSTRUMENTATION
14068    // =========================================================
14069
14070    public boolean startInstrumentation(ComponentName className,
14071            String profileFile, int flags, Bundle arguments,
14072            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14073            int userId) {
14074        enforceNotIsolatedCaller("startInstrumentation");
14075        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14076                userId, false, true, "startInstrumentation", null);
14077        // Refuse possible leaked file descriptors
14078        if (arguments != null && arguments.hasFileDescriptors()) {
14079            throw new IllegalArgumentException("File descriptors passed in Bundle");
14080        }
14081
14082        synchronized(this) {
14083            InstrumentationInfo ii = null;
14084            ApplicationInfo ai = null;
14085            try {
14086                ii = mContext.getPackageManager().getInstrumentationInfo(
14087                    className, STOCK_PM_FLAGS);
14088                ai = AppGlobals.getPackageManager().getApplicationInfo(
14089                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14090            } catch (PackageManager.NameNotFoundException e) {
14091            } catch (RemoteException e) {
14092            }
14093            if (ii == null) {
14094                reportStartInstrumentationFailure(watcher, className,
14095                        "Unable to find instrumentation info for: " + className);
14096                return false;
14097            }
14098            if (ai == null) {
14099                reportStartInstrumentationFailure(watcher, className,
14100                        "Unable to find instrumentation target package: " + ii.targetPackage);
14101                return false;
14102            }
14103
14104            int match = mContext.getPackageManager().checkSignatures(
14105                    ii.targetPackage, ii.packageName);
14106            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14107                String msg = "Permission Denial: starting instrumentation "
14108                        + className + " from pid="
14109                        + Binder.getCallingPid()
14110                        + ", uid=" + Binder.getCallingPid()
14111                        + " not allowed because package " + ii.packageName
14112                        + " does not have a signature matching the target "
14113                        + ii.targetPackage;
14114                reportStartInstrumentationFailure(watcher, className, msg);
14115                throw new SecurityException(msg);
14116            }
14117
14118            final long origId = Binder.clearCallingIdentity();
14119            // Instrumentation can kill and relaunch even persistent processes
14120            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14121                    "start instr");
14122            ProcessRecord app = addAppLocked(ai, false);
14123            app.instrumentationClass = className;
14124            app.instrumentationInfo = ai;
14125            app.instrumentationProfileFile = profileFile;
14126            app.instrumentationArguments = arguments;
14127            app.instrumentationWatcher = watcher;
14128            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14129            app.instrumentationResultClass = className;
14130            Binder.restoreCallingIdentity(origId);
14131        }
14132
14133        return true;
14134    }
14135
14136    /**
14137     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14138     * error to the logs, but if somebody is watching, send the report there too.  This enables
14139     * the "am" command to report errors with more information.
14140     *
14141     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14142     * @param cn The component name of the instrumentation.
14143     * @param report The error report.
14144     */
14145    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14146            ComponentName cn, String report) {
14147        Slog.w(TAG, report);
14148        try {
14149            if (watcher != null) {
14150                Bundle results = new Bundle();
14151                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14152                results.putString("Error", report);
14153                watcher.instrumentationStatus(cn, -1, results);
14154            }
14155        } catch (RemoteException e) {
14156            Slog.w(TAG, e);
14157        }
14158    }
14159
14160    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14161        if (app.instrumentationWatcher != null) {
14162            try {
14163                // NOTE:  IInstrumentationWatcher *must* be oneway here
14164                app.instrumentationWatcher.instrumentationFinished(
14165                    app.instrumentationClass,
14166                    resultCode,
14167                    results);
14168            } catch (RemoteException e) {
14169            }
14170        }
14171        if (app.instrumentationUiAutomationConnection != null) {
14172            try {
14173                app.instrumentationUiAutomationConnection.shutdown();
14174            } catch (RemoteException re) {
14175                /* ignore */
14176            }
14177            // Only a UiAutomation can set this flag and now that
14178            // it is finished we make sure it is reset to its default.
14179            mUserIsMonkey = false;
14180        }
14181        app.instrumentationWatcher = null;
14182        app.instrumentationUiAutomationConnection = null;
14183        app.instrumentationClass = null;
14184        app.instrumentationInfo = null;
14185        app.instrumentationProfileFile = null;
14186        app.instrumentationArguments = null;
14187
14188        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14189                "finished inst");
14190    }
14191
14192    public void finishInstrumentation(IApplicationThread target,
14193            int resultCode, Bundle results) {
14194        int userId = UserHandle.getCallingUserId();
14195        // Refuse possible leaked file descriptors
14196        if (results != null && results.hasFileDescriptors()) {
14197            throw new IllegalArgumentException("File descriptors passed in Intent");
14198        }
14199
14200        synchronized(this) {
14201            ProcessRecord app = getRecordForAppLocked(target);
14202            if (app == null) {
14203                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14204                return;
14205            }
14206            final long origId = Binder.clearCallingIdentity();
14207            finishInstrumentationLocked(app, resultCode, results);
14208            Binder.restoreCallingIdentity(origId);
14209        }
14210    }
14211
14212    // =========================================================
14213    // CONFIGURATION
14214    // =========================================================
14215
14216    public ConfigurationInfo getDeviceConfigurationInfo() {
14217        ConfigurationInfo config = new ConfigurationInfo();
14218        synchronized (this) {
14219            config.reqTouchScreen = mConfiguration.touchscreen;
14220            config.reqKeyboardType = mConfiguration.keyboard;
14221            config.reqNavigation = mConfiguration.navigation;
14222            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14223                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14224                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14225            }
14226            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14227                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14228                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14229            }
14230            config.reqGlEsVersion = GL_ES_VERSION;
14231        }
14232        return config;
14233    }
14234
14235    ActivityStack getFocusedStack() {
14236        return mStackSupervisor.getFocusedStack();
14237    }
14238
14239    public Configuration getConfiguration() {
14240        Configuration ci;
14241        synchronized(this) {
14242            ci = new Configuration(mConfiguration);
14243        }
14244        return ci;
14245    }
14246
14247    public void updatePersistentConfiguration(Configuration values) {
14248        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14249                "updateConfiguration()");
14250        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14251                "updateConfiguration()");
14252        if (values == null) {
14253            throw new NullPointerException("Configuration must not be null");
14254        }
14255
14256        synchronized(this) {
14257            final long origId = Binder.clearCallingIdentity();
14258            updateConfigurationLocked(values, null, true, false);
14259            Binder.restoreCallingIdentity(origId);
14260        }
14261    }
14262
14263    public void updateConfiguration(Configuration values) {
14264        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14265                "updateConfiguration()");
14266
14267        synchronized(this) {
14268            if (values == null && mWindowManager != null) {
14269                // sentinel: fetch the current configuration from the window manager
14270                values = mWindowManager.computeNewConfiguration();
14271            }
14272
14273            if (mWindowManager != null) {
14274                mProcessList.applyDisplaySize(mWindowManager);
14275            }
14276
14277            final long origId = Binder.clearCallingIdentity();
14278            if (values != null) {
14279                Settings.System.clearConfiguration(values);
14280            }
14281            updateConfigurationLocked(values, null, false, false);
14282            Binder.restoreCallingIdentity(origId);
14283        }
14284    }
14285
14286    /**
14287     * Do either or both things: (1) change the current configuration, and (2)
14288     * make sure the given activity is running with the (now) current
14289     * configuration.  Returns true if the activity has been left running, or
14290     * false if <var>starting</var> is being destroyed to match the new
14291     * configuration.
14292     * @param persistent TODO
14293     */
14294    boolean updateConfigurationLocked(Configuration values,
14295            ActivityRecord starting, boolean persistent, boolean initLocale) {
14296        int changes = 0;
14297
14298        if (values != null) {
14299            Configuration newConfig = new Configuration(mConfiguration);
14300            changes = newConfig.updateFrom(values);
14301            if (changes != 0) {
14302                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14303                    Slog.i(TAG, "Updating configuration to: " + values);
14304                }
14305
14306                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14307
14308                if (values.locale != null && !initLocale) {
14309                    saveLocaleLocked(values.locale,
14310                                     !values.locale.equals(mConfiguration.locale),
14311                                     values.userSetLocale);
14312                }
14313
14314                mConfigurationSeq++;
14315                if (mConfigurationSeq <= 0) {
14316                    mConfigurationSeq = 1;
14317                }
14318                newConfig.seq = mConfigurationSeq;
14319                mConfiguration = newConfig;
14320                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14321
14322                final Configuration configCopy = new Configuration(mConfiguration);
14323
14324                // TODO: If our config changes, should we auto dismiss any currently
14325                // showing dialogs?
14326                mShowDialogs = shouldShowDialogs(newConfig);
14327
14328                AttributeCache ac = AttributeCache.instance();
14329                if (ac != null) {
14330                    ac.updateConfiguration(configCopy);
14331                }
14332
14333                // Make sure all resources in our process are updated
14334                // right now, so that anyone who is going to retrieve
14335                // resource values after we return will be sure to get
14336                // the new ones.  This is especially important during
14337                // boot, where the first config change needs to guarantee
14338                // all resources have that config before following boot
14339                // code is executed.
14340                mSystemThread.applyConfigurationToResources(configCopy);
14341
14342                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14343                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14344                    msg.obj = new Configuration(configCopy);
14345                    mHandler.sendMessage(msg);
14346                }
14347
14348                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14349                    ProcessRecord app = mLruProcesses.get(i);
14350                    try {
14351                        if (app.thread != null) {
14352                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14353                                    + app.processName + " new config " + mConfiguration);
14354                            app.thread.scheduleConfigurationChanged(configCopy);
14355                        }
14356                    } catch (Exception e) {
14357                    }
14358                }
14359                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14360                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14361                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14362                        | Intent.FLAG_RECEIVER_FOREGROUND);
14363                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14364                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14365                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14366                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14367                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14368                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14369                    broadcastIntentLocked(null, null, intent,
14370                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14371                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14372                }
14373            }
14374        }
14375
14376        boolean kept = true;
14377        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14378        // mainStack is null during startup.
14379        if (mainStack != null) {
14380            if (changes != 0 && starting == null) {
14381                // If the configuration changed, and the caller is not already
14382                // in the process of starting an activity, then find the top
14383                // activity to check if its configuration needs to change.
14384                starting = mainStack.topRunningActivityLocked(null);
14385            }
14386
14387            if (starting != null) {
14388                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14389                // And we need to make sure at this point that all other activities
14390                // are made visible with the correct configuration.
14391                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14392            }
14393        }
14394
14395        if (values != null && mWindowManager != null) {
14396            mWindowManager.setNewConfiguration(mConfiguration);
14397        }
14398
14399        return kept;
14400    }
14401
14402    /**
14403     * Decide based on the configuration whether we should shouw the ANR,
14404     * crash, etc dialogs.  The idea is that if there is no affordnace to
14405     * press the on-screen buttons, we shouldn't show the dialog.
14406     *
14407     * A thought: SystemUI might also want to get told about this, the Power
14408     * dialog / global actions also might want different behaviors.
14409     */
14410    private static final boolean shouldShowDialogs(Configuration config) {
14411        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14412                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14413    }
14414
14415    /**
14416     * Save the locale.  You must be inside a synchronized (this) block.
14417     */
14418    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14419        if(isDiff) {
14420            SystemProperties.set("user.language", l.getLanguage());
14421            SystemProperties.set("user.region", l.getCountry());
14422        }
14423
14424        if(isPersist) {
14425            SystemProperties.set("persist.sys.language", l.getLanguage());
14426            SystemProperties.set("persist.sys.country", l.getCountry());
14427            SystemProperties.set("persist.sys.localevar", l.getVariant());
14428        }
14429    }
14430
14431    @Override
14432    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14433        ActivityRecord srec = ActivityRecord.forToken(token);
14434        return srec != null && srec.task.affinity != null &&
14435                srec.task.affinity.equals(destAffinity);
14436    }
14437
14438    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14439            Intent resultData) {
14440
14441        synchronized (this) {
14442            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14443            if (stack != null) {
14444                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14445            }
14446            return false;
14447        }
14448    }
14449
14450    public int getLaunchedFromUid(IBinder activityToken) {
14451        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14452        if (srec == null) {
14453            return -1;
14454        }
14455        return srec.launchedFromUid;
14456    }
14457
14458    public String getLaunchedFromPackage(IBinder activityToken) {
14459        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14460        if (srec == null) {
14461            return null;
14462        }
14463        return srec.launchedFromPackage;
14464    }
14465
14466    // =========================================================
14467    // LIFETIME MANAGEMENT
14468    // =========================================================
14469
14470    // Returns which broadcast queue the app is the current [or imminent] receiver
14471    // on, or 'null' if the app is not an active broadcast recipient.
14472    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14473        BroadcastRecord r = app.curReceiver;
14474        if (r != null) {
14475            return r.queue;
14476        }
14477
14478        // It's not the current receiver, but it might be starting up to become one
14479        synchronized (this) {
14480            for (BroadcastQueue queue : mBroadcastQueues) {
14481                r = queue.mPendingBroadcast;
14482                if (r != null && r.curApp == app) {
14483                    // found it; report which queue it's in
14484                    return queue;
14485                }
14486            }
14487        }
14488
14489        return null;
14490    }
14491
14492    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14493            boolean doingAll, long now) {
14494        if (mAdjSeq == app.adjSeq) {
14495            // This adjustment has already been computed.
14496            return app.curRawAdj;
14497        }
14498
14499        if (app.thread == null) {
14500            app.adjSeq = mAdjSeq;
14501            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14502            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14503            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14504        }
14505
14506        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14507        app.adjSource = null;
14508        app.adjTarget = null;
14509        app.empty = false;
14510        app.cached = false;
14511
14512        final int activitiesSize = app.activities.size();
14513
14514        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14515            // The max adjustment doesn't allow this app to be anything
14516            // below foreground, so it is not worth doing work for it.
14517            app.adjType = "fixed";
14518            app.adjSeq = mAdjSeq;
14519            app.curRawAdj = app.maxAdj;
14520            app.foregroundActivities = false;
14521            app.keeping = true;
14522            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14523            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14524            // System process can do UI, and when they do we want to have
14525            // them trim their memory after the user leaves the UI.  To
14526            // facilitate this, here we need to determine whether or not it
14527            // is currently showing UI.
14528            app.systemNoUi = true;
14529            if (app == TOP_APP) {
14530                app.systemNoUi = false;
14531            } else if (activitiesSize > 0) {
14532                for (int j = 0; j < activitiesSize; j++) {
14533                    final ActivityRecord r = app.activities.get(j);
14534                    if (r.visible) {
14535                        app.systemNoUi = false;
14536                    }
14537                }
14538            }
14539            if (!app.systemNoUi) {
14540                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14541            }
14542            return (app.curAdj=app.maxAdj);
14543        }
14544
14545        app.keeping = false;
14546        app.systemNoUi = false;
14547
14548        // Determine the importance of the process, starting with most
14549        // important to least, and assign an appropriate OOM adjustment.
14550        int adj;
14551        int schedGroup;
14552        int procState;
14553        boolean foregroundActivities = false;
14554        boolean interesting = false;
14555        BroadcastQueue queue;
14556        if (app == TOP_APP) {
14557            // The last app on the list is the foreground app.
14558            adj = ProcessList.FOREGROUND_APP_ADJ;
14559            schedGroup = Process.THREAD_GROUP_DEFAULT;
14560            app.adjType = "top-activity";
14561            foregroundActivities = true;
14562            interesting = true;
14563            procState = ActivityManager.PROCESS_STATE_TOP;
14564        } else if (app.instrumentationClass != null) {
14565            // Don't want to kill running instrumentation.
14566            adj = ProcessList.FOREGROUND_APP_ADJ;
14567            schedGroup = Process.THREAD_GROUP_DEFAULT;
14568            app.adjType = "instrumentation";
14569            interesting = true;
14570            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14571        } else if ((queue = isReceivingBroadcast(app)) != null) {
14572            // An app that is currently receiving a broadcast also
14573            // counts as being in the foreground for OOM killer purposes.
14574            // It's placed in a sched group based on the nature of the
14575            // broadcast as reflected by which queue it's active in.
14576            adj = ProcessList.FOREGROUND_APP_ADJ;
14577            schedGroup = (queue == mFgBroadcastQueue)
14578                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14579            app.adjType = "broadcast";
14580            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14581        } else if (app.executingServices.size() > 0) {
14582            // An app that is currently executing a service callback also
14583            // counts as being in the foreground.
14584            adj = ProcessList.FOREGROUND_APP_ADJ;
14585            schedGroup = app.execServicesFg ?
14586                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14587            app.adjType = "exec-service";
14588            procState = ActivityManager.PROCESS_STATE_SERVICE;
14589            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14590        } else {
14591            // As far as we know the process is empty.  We may change our mind later.
14592            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14593            // At this point we don't actually know the adjustment.  Use the cached adj
14594            // value that the caller wants us to.
14595            adj = cachedAdj;
14596            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14597            app.cached = true;
14598            app.empty = true;
14599            app.adjType = "cch-empty";
14600        }
14601
14602        // Examine all activities if not already foreground.
14603        if (!foregroundActivities && activitiesSize > 0) {
14604            for (int j = 0; j < activitiesSize; j++) {
14605                final ActivityRecord r = app.activities.get(j);
14606                if (r.app != app) {
14607                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14608                            + app + "?!?");
14609                    continue;
14610                }
14611                if (r.visible) {
14612                    // App has a visible activity; only upgrade adjustment.
14613                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14614                        adj = ProcessList.VISIBLE_APP_ADJ;
14615                        app.adjType = "visible";
14616                    }
14617                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14618                        procState = ActivityManager.PROCESS_STATE_TOP;
14619                    }
14620                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14621                    app.cached = false;
14622                    app.empty = false;
14623                    foregroundActivities = true;
14624                    break;
14625                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14626                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14627                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14628                        app.adjType = "pausing";
14629                    }
14630                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14631                        procState = ActivityManager.PROCESS_STATE_TOP;
14632                    }
14633                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14634                    app.cached = false;
14635                    app.empty = false;
14636                    foregroundActivities = true;
14637                } else if (r.state == ActivityState.STOPPING) {
14638                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14639                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14640                        app.adjType = "stopping";
14641                    }
14642                    // For the process state, we will at this point consider the
14643                    // process to be cached.  It will be cached either as an activity
14644                    // or empty depending on whether the activity is finishing.  We do
14645                    // this so that we can treat the process as cached for purposes of
14646                    // memory trimming (determing current memory level, trim command to
14647                    // send to process) since there can be an arbitrary number of stopping
14648                    // processes and they should soon all go into the cached state.
14649                    if (!r.finishing) {
14650                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14651                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14652                        }
14653                    }
14654                    app.cached = false;
14655                    app.empty = false;
14656                    foregroundActivities = true;
14657                } else {
14658                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14659                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14660                        app.adjType = "cch-act";
14661                    }
14662                }
14663            }
14664        }
14665
14666        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14667            if (app.foregroundServices) {
14668                // The user is aware of this app, so make it visible.
14669                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14670                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14671                app.cached = false;
14672                app.adjType = "fg-service";
14673                schedGroup = Process.THREAD_GROUP_DEFAULT;
14674            } else if (app.forcingToForeground != null) {
14675                // The user is aware of this app, so make it visible.
14676                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14677                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14678                app.cached = false;
14679                app.adjType = "force-fg";
14680                app.adjSource = app.forcingToForeground;
14681                schedGroup = Process.THREAD_GROUP_DEFAULT;
14682            }
14683        }
14684
14685        if (app.foregroundServices) {
14686            interesting = true;
14687        }
14688
14689        if (app == mHeavyWeightProcess) {
14690            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14691                // We don't want to kill the current heavy-weight process.
14692                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14693                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14694                app.cached = false;
14695                app.adjType = "heavy";
14696            }
14697            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14698                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14699            }
14700        }
14701
14702        if (app == mHomeProcess) {
14703            if (adj > ProcessList.HOME_APP_ADJ) {
14704                // This process is hosting what we currently consider to be the
14705                // home app, so we don't want to let it go into the background.
14706                adj = ProcessList.HOME_APP_ADJ;
14707                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14708                app.cached = false;
14709                app.adjType = "home";
14710            }
14711            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14712                procState = ActivityManager.PROCESS_STATE_HOME;
14713            }
14714        }
14715
14716        if (app == mPreviousProcess && app.activities.size() > 0) {
14717            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14718                // This was the previous process that showed UI to the user.
14719                // We want to try to keep it around more aggressively, to give
14720                // a good experience around switching between two apps.
14721                adj = ProcessList.PREVIOUS_APP_ADJ;
14722                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14723                app.cached = false;
14724                app.adjType = "previous";
14725            }
14726            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14727                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14728            }
14729        }
14730
14731        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14732                + " reason=" + app.adjType);
14733
14734        // By default, we use the computed adjustment.  It may be changed if
14735        // there are applications dependent on our services or providers, but
14736        // this gives us a baseline and makes sure we don't get into an
14737        // infinite recursion.
14738        app.adjSeq = mAdjSeq;
14739        app.curRawAdj = adj;
14740        app.hasStartedServices = false;
14741
14742        if (mBackupTarget != null && app == mBackupTarget.app) {
14743            // If possible we want to avoid killing apps while they're being backed up
14744            if (adj > ProcessList.BACKUP_APP_ADJ) {
14745                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14746                adj = ProcessList.BACKUP_APP_ADJ;
14747                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14748                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14749                }
14750                app.adjType = "backup";
14751                app.cached = false;
14752            }
14753            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14754                procState = ActivityManager.PROCESS_STATE_BACKUP;
14755            }
14756        }
14757
14758        boolean mayBeTop = false;
14759
14760        for (int is = app.services.size()-1;
14761                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14762                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14763                        || procState > ActivityManager.PROCESS_STATE_TOP);
14764                is--) {
14765            ServiceRecord s = app.services.valueAt(is);
14766            if (s.startRequested) {
14767                app.hasStartedServices = true;
14768                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14769                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14770                }
14771                if (app.hasShownUi && app != mHomeProcess) {
14772                    // If this process has shown some UI, let it immediately
14773                    // go to the LRU list because it may be pretty heavy with
14774                    // UI stuff.  We'll tag it with a label just to help
14775                    // debug and understand what is going on.
14776                    if (adj > ProcessList.SERVICE_ADJ) {
14777                        app.adjType = "cch-started-ui-services";
14778                    }
14779                } else {
14780                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14781                        // This service has seen some activity within
14782                        // recent memory, so we will keep its process ahead
14783                        // of the background processes.
14784                        if (adj > ProcessList.SERVICE_ADJ) {
14785                            adj = ProcessList.SERVICE_ADJ;
14786                            app.adjType = "started-services";
14787                            app.cached = false;
14788                        }
14789                    }
14790                    // If we have let the service slide into the background
14791                    // state, still have some text describing what it is doing
14792                    // even though the service no longer has an impact.
14793                    if (adj > ProcessList.SERVICE_ADJ) {
14794                        app.adjType = "cch-started-services";
14795                    }
14796                }
14797                // Don't kill this process because it is doing work; it
14798                // has said it is doing work.
14799                app.keeping = true;
14800            }
14801            for (int conni = s.connections.size()-1;
14802                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14803                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14804                            || procState > ActivityManager.PROCESS_STATE_TOP);
14805                    conni--) {
14806                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14807                for (int i = 0;
14808                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14809                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14810                                || procState > ActivityManager.PROCESS_STATE_TOP);
14811                        i++) {
14812                    // XXX should compute this based on the max of
14813                    // all connected clients.
14814                    ConnectionRecord cr = clist.get(i);
14815                    if (cr.binding.client == app) {
14816                        // Binding to ourself is not interesting.
14817                        continue;
14818                    }
14819                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14820                        ProcessRecord client = cr.binding.client;
14821                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14822                                TOP_APP, doingAll, now);
14823                        int clientProcState = client.curProcState;
14824                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14825                            // If the other app is cached for any reason, for purposes here
14826                            // we are going to consider it empty.  The specific cached state
14827                            // doesn't propagate except under certain conditions.
14828                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14829                        }
14830                        String adjType = null;
14831                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14832                            // Not doing bind OOM management, so treat
14833                            // this guy more like a started service.
14834                            if (app.hasShownUi && app != mHomeProcess) {
14835                                // If this process has shown some UI, let it immediately
14836                                // go to the LRU list because it may be pretty heavy with
14837                                // UI stuff.  We'll tag it with a label just to help
14838                                // debug and understand what is going on.
14839                                if (adj > clientAdj) {
14840                                    adjType = "cch-bound-ui-services";
14841                                }
14842                                app.cached = false;
14843                                clientAdj = adj;
14844                                clientProcState = procState;
14845                            } else {
14846                                if (now >= (s.lastActivity
14847                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14848                                    // This service has not seen activity within
14849                                    // recent memory, so allow it to drop to the
14850                                    // LRU list if there is no other reason to keep
14851                                    // it around.  We'll also tag it with a label just
14852                                    // to help debug and undertand what is going on.
14853                                    if (adj > clientAdj) {
14854                                        adjType = "cch-bound-services";
14855                                    }
14856                                    clientAdj = adj;
14857                                }
14858                            }
14859                        }
14860                        if (adj > clientAdj) {
14861                            // If this process has recently shown UI, and
14862                            // the process that is binding to it is less
14863                            // important than being visible, then we don't
14864                            // care about the binding as much as we care
14865                            // about letting this process get into the LRU
14866                            // list to be killed and restarted if needed for
14867                            // memory.
14868                            if (app.hasShownUi && app != mHomeProcess
14869                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14870                                adjType = "cch-bound-ui-services";
14871                            } else {
14872                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14873                                        |Context.BIND_IMPORTANT)) != 0) {
14874                                    adj = clientAdj;
14875                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14876                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14877                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14878                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14879                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14880                                    adj = clientAdj;
14881                                } else {
14882                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14883                                        adj = ProcessList.VISIBLE_APP_ADJ;
14884                                    }
14885                                }
14886                                if (!client.cached) {
14887                                    app.cached = false;
14888                                }
14889                                if (client.keeping) {
14890                                    app.keeping = true;
14891                                }
14892                                adjType = "service";
14893                            }
14894                        }
14895                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14896                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14897                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14898                            }
14899                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14900                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14901                                    // Special handling of clients who are in the top state.
14902                                    // We *may* want to consider this process to be in the
14903                                    // top state as well, but only if there is not another
14904                                    // reason for it to be running.  Being on the top is a
14905                                    // special state, meaning you are specifically running
14906                                    // for the current top app.  If the process is already
14907                                    // running in the background for some other reason, it
14908                                    // is more important to continue considering it to be
14909                                    // in the background state.
14910                                    mayBeTop = true;
14911                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14912                                } else {
14913                                    // Special handling for above-top states (persistent
14914                                    // processes).  These should not bring the current process
14915                                    // into the top state, since they are not on top.  Instead
14916                                    // give them the best state after that.
14917                                    clientProcState =
14918                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14919                                }
14920                            }
14921                        } else {
14922                            if (clientProcState <
14923                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14924                                clientProcState =
14925                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14926                            }
14927                        }
14928                        if (procState > clientProcState) {
14929                            procState = clientProcState;
14930                        }
14931                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14932                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14933                            app.pendingUiClean = true;
14934                        }
14935                        if (adjType != null) {
14936                            app.adjType = adjType;
14937                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14938                                    .REASON_SERVICE_IN_USE;
14939                            app.adjSource = cr.binding.client;
14940                            app.adjSourceOom = clientAdj;
14941                            app.adjTarget = s.name;
14942                        }
14943                    }
14944                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
14945                        app.treatLikeActivity = true;
14946                    }
14947                    final ActivityRecord a = cr.activity;
14948                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14949                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14950                                (a.visible || a.state == ActivityState.RESUMED
14951                                 || a.state == ActivityState.PAUSING)) {
14952                            adj = ProcessList.FOREGROUND_APP_ADJ;
14953                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14954                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14955                            }
14956                            app.cached = false;
14957                            app.adjType = "service";
14958                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14959                                    .REASON_SERVICE_IN_USE;
14960                            app.adjSource = a;
14961                            app.adjSourceOom = adj;
14962                            app.adjTarget = s.name;
14963                        }
14964                    }
14965                }
14966            }
14967        }
14968
14969        for (int provi = app.pubProviders.size()-1;
14970                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14971                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14972                        || procState > ActivityManager.PROCESS_STATE_TOP);
14973                provi--) {
14974            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14975            for (int i = cpr.connections.size()-1;
14976                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14977                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14978                            || procState > ActivityManager.PROCESS_STATE_TOP);
14979                    i--) {
14980                ContentProviderConnection conn = cpr.connections.get(i);
14981                ProcessRecord client = conn.client;
14982                if (client == app) {
14983                    // Being our own client is not interesting.
14984                    continue;
14985                }
14986                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14987                int clientProcState = client.curProcState;
14988                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14989                    // If the other app is cached for any reason, for purposes here
14990                    // we are going to consider it empty.
14991                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14992                }
14993                if (adj > clientAdj) {
14994                    if (app.hasShownUi && app != mHomeProcess
14995                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14996                        app.adjType = "cch-ui-provider";
14997                    } else {
14998                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14999                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15000                        app.adjType = "provider";
15001                    }
15002                    app.cached &= client.cached;
15003                    app.keeping |= client.keeping;
15004                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15005                            .REASON_PROVIDER_IN_USE;
15006                    app.adjSource = client;
15007                    app.adjSourceOom = clientAdj;
15008                    app.adjTarget = cpr.name;
15009                }
15010                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15011                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15012                        // Special handling of clients who are in the top state.
15013                        // We *may* want to consider this process to be in the
15014                        // top state as well, but only if there is not another
15015                        // reason for it to be running.  Being on the top is a
15016                        // special state, meaning you are specifically running
15017                        // for the current top app.  If the process is already
15018                        // running in the background for some other reason, it
15019                        // is more important to continue considering it to be
15020                        // in the background state.
15021                        mayBeTop = true;
15022                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15023                    } else {
15024                        // Special handling for above-top states (persistent
15025                        // processes).  These should not bring the current process
15026                        // into the top state, since they are not on top.  Instead
15027                        // give them the best state after that.
15028                        clientProcState =
15029                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15030                    }
15031                }
15032                if (procState > clientProcState) {
15033                    procState = clientProcState;
15034                }
15035                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15036                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15037                }
15038            }
15039            // If the provider has external (non-framework) process
15040            // dependencies, ensure that its adjustment is at least
15041            // FOREGROUND_APP_ADJ.
15042            if (cpr.hasExternalProcessHandles()) {
15043                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15044                    adj = ProcessList.FOREGROUND_APP_ADJ;
15045                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15046                    app.cached = false;
15047                    app.keeping = true;
15048                    app.adjType = "provider";
15049                    app.adjTarget = cpr.name;
15050                }
15051                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15052                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15053                }
15054            }
15055        }
15056
15057        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15058            // A client of one of our services or providers is in the top state.  We
15059            // *may* want to be in the top state, but not if we are already running in
15060            // the background for some other reason.  For the decision here, we are going
15061            // to pick out a few specific states that we want to remain in when a client
15062            // is top (states that tend to be longer-term) and otherwise allow it to go
15063            // to the top state.
15064            switch (procState) {
15065                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15066                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15067                case ActivityManager.PROCESS_STATE_SERVICE:
15068                    // These all are longer-term states, so pull them up to the top
15069                    // of the background states, but not all the way to the top state.
15070                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15071                    break;
15072                default:
15073                    // Otherwise, top is a better choice, so take it.
15074                    procState = ActivityManager.PROCESS_STATE_TOP;
15075                    break;
15076            }
15077        }
15078
15079        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15080            if (app.hasClientActivities) {
15081                // This is a cached process, but with client activities.  Mark it so.
15082                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15083                app.adjType = "cch-client-act";
15084            } else if (app.treatLikeActivity) {
15085                // This is a cached process, but somebody wants us to treat it like it has
15086                // an activity, okay!
15087                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15088                app.adjType = "cch-as-act";
15089            }
15090        }
15091
15092        if (adj == ProcessList.SERVICE_ADJ) {
15093            if (doingAll) {
15094                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15095                mNewNumServiceProcs++;
15096                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15097                if (!app.serviceb) {
15098                    // This service isn't far enough down on the LRU list to
15099                    // normally be a B service, but if we are low on RAM and it
15100                    // is large we want to force it down since we would prefer to
15101                    // keep launcher over it.
15102                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15103                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15104                        app.serviceHighRam = true;
15105                        app.serviceb = true;
15106                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15107                    } else {
15108                        mNewNumAServiceProcs++;
15109                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15110                    }
15111                } else {
15112                    app.serviceHighRam = false;
15113                }
15114            }
15115            if (app.serviceb) {
15116                adj = ProcessList.SERVICE_B_ADJ;
15117            }
15118        }
15119
15120        app.curRawAdj = adj;
15121
15122        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15123        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15124        if (adj > app.maxAdj) {
15125            adj = app.maxAdj;
15126            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15127                schedGroup = Process.THREAD_GROUP_DEFAULT;
15128            }
15129        }
15130        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15131            app.keeping = true;
15132        }
15133
15134        // Do final modification to adj.  Everything we do between here and applying
15135        // the final setAdj must be done in this function, because we will also use
15136        // it when computing the final cached adj later.  Note that we don't need to
15137        // worry about this for max adj above, since max adj will always be used to
15138        // keep it out of the cached vaues.
15139        adj = app.modifyRawOomAdj(adj);
15140
15141        app.curProcState = procState;
15142
15143        int importance = app.memImportance;
15144        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
15145            app.curAdj = adj;
15146            app.curSchedGroup = schedGroup;
15147            if (!interesting) {
15148                // For this reporting, if there is not something explicitly
15149                // interesting in this process then we will push it to the
15150                // background importance.
15151                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15152            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
15153                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15154            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
15155                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15156            } else if (adj >= ProcessList.HOME_APP_ADJ) {
15157                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15158            } else if (adj >= ProcessList.SERVICE_ADJ) {
15159                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15160            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15161                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
15162            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
15163                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
15164            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
15165                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
15166            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
15167                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
15168            } else {
15169                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
15170            }
15171        }
15172
15173        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
15174        if (foregroundActivities != app.foregroundActivities) {
15175            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15176        }
15177        if (changes != 0) {
15178            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15179            app.memImportance = importance;
15180            app.foregroundActivities = foregroundActivities;
15181            int i = mPendingProcessChanges.size()-1;
15182            ProcessChangeItem item = null;
15183            while (i >= 0) {
15184                item = mPendingProcessChanges.get(i);
15185                if (item.pid == app.pid) {
15186                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15187                    break;
15188                }
15189                i--;
15190            }
15191            if (i < 0) {
15192                // No existing item in pending changes; need a new one.
15193                final int NA = mAvailProcessChanges.size();
15194                if (NA > 0) {
15195                    item = mAvailProcessChanges.remove(NA-1);
15196                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15197                } else {
15198                    item = new ProcessChangeItem();
15199                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15200                }
15201                item.changes = 0;
15202                item.pid = app.pid;
15203                item.uid = app.info.uid;
15204                if (mPendingProcessChanges.size() == 0) {
15205                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15206                            "*** Enqueueing dispatch processes changed!");
15207                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15208                }
15209                mPendingProcessChanges.add(item);
15210            }
15211            item.changes |= changes;
15212            item.importance = importance;
15213            item.foregroundActivities = foregroundActivities;
15214            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15215                    + Integer.toHexString(System.identityHashCode(item))
15216                    + " " + app.toShortString() + ": changes=" + item.changes
15217                    + " importance=" + item.importance
15218                    + " foreground=" + item.foregroundActivities
15219                    + " type=" + app.adjType + " source=" + app.adjSource
15220                    + " target=" + app.adjTarget);
15221        }
15222
15223        return app.curRawAdj;
15224    }
15225
15226    /**
15227     * Schedule PSS collection of a process.
15228     */
15229    void requestPssLocked(ProcessRecord proc, int procState) {
15230        if (mPendingPssProcesses.contains(proc)) {
15231            return;
15232        }
15233        if (mPendingPssProcesses.size() == 0) {
15234            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15235        }
15236        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15237        proc.pssProcState = procState;
15238        mPendingPssProcesses.add(proc);
15239    }
15240
15241    /**
15242     * Schedule PSS collection of all processes.
15243     */
15244    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15245        if (!always) {
15246            if (now < (mLastFullPssTime +
15247                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15248                return;
15249            }
15250        }
15251        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15252        mLastFullPssTime = now;
15253        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15254        mPendingPssProcesses.clear();
15255        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15256            ProcessRecord app = mLruProcesses.get(i);
15257            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15258                app.pssProcState = app.setProcState;
15259                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15260                        mSleeping, now);
15261                mPendingPssProcesses.add(app);
15262            }
15263        }
15264        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15265    }
15266
15267    /**
15268     * Ask a given process to GC right now.
15269     */
15270    final void performAppGcLocked(ProcessRecord app) {
15271        try {
15272            app.lastRequestedGc = SystemClock.uptimeMillis();
15273            if (app.thread != null) {
15274                if (app.reportLowMemory) {
15275                    app.reportLowMemory = false;
15276                    app.thread.scheduleLowMemory();
15277                } else {
15278                    app.thread.processInBackground();
15279                }
15280            }
15281        } catch (Exception e) {
15282            // whatever.
15283        }
15284    }
15285
15286    /**
15287     * Returns true if things are idle enough to perform GCs.
15288     */
15289    private final boolean canGcNowLocked() {
15290        boolean processingBroadcasts = false;
15291        for (BroadcastQueue q : mBroadcastQueues) {
15292            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15293                processingBroadcasts = true;
15294            }
15295        }
15296        return !processingBroadcasts
15297                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15298    }
15299
15300    /**
15301     * Perform GCs on all processes that are waiting for it, but only
15302     * if things are idle.
15303     */
15304    final void performAppGcsLocked() {
15305        final int N = mProcessesToGc.size();
15306        if (N <= 0) {
15307            return;
15308        }
15309        if (canGcNowLocked()) {
15310            while (mProcessesToGc.size() > 0) {
15311                ProcessRecord proc = mProcessesToGc.remove(0);
15312                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15313                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15314                            <= SystemClock.uptimeMillis()) {
15315                        // To avoid spamming the system, we will GC processes one
15316                        // at a time, waiting a few seconds between each.
15317                        performAppGcLocked(proc);
15318                        scheduleAppGcsLocked();
15319                        return;
15320                    } else {
15321                        // It hasn't been long enough since we last GCed this
15322                        // process...  put it in the list to wait for its time.
15323                        addProcessToGcListLocked(proc);
15324                        break;
15325                    }
15326                }
15327            }
15328
15329            scheduleAppGcsLocked();
15330        }
15331    }
15332
15333    /**
15334     * If all looks good, perform GCs on all processes waiting for them.
15335     */
15336    final void performAppGcsIfAppropriateLocked() {
15337        if (canGcNowLocked()) {
15338            performAppGcsLocked();
15339            return;
15340        }
15341        // Still not idle, wait some more.
15342        scheduleAppGcsLocked();
15343    }
15344
15345    /**
15346     * Schedule the execution of all pending app GCs.
15347     */
15348    final void scheduleAppGcsLocked() {
15349        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15350
15351        if (mProcessesToGc.size() > 0) {
15352            // Schedule a GC for the time to the next process.
15353            ProcessRecord proc = mProcessesToGc.get(0);
15354            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15355
15356            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15357            long now = SystemClock.uptimeMillis();
15358            if (when < (now+GC_TIMEOUT)) {
15359                when = now + GC_TIMEOUT;
15360            }
15361            mHandler.sendMessageAtTime(msg, when);
15362        }
15363    }
15364
15365    /**
15366     * Add a process to the array of processes waiting to be GCed.  Keeps the
15367     * list in sorted order by the last GC time.  The process can't already be
15368     * on the list.
15369     */
15370    final void addProcessToGcListLocked(ProcessRecord proc) {
15371        boolean added = false;
15372        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15373            if (mProcessesToGc.get(i).lastRequestedGc <
15374                    proc.lastRequestedGc) {
15375                added = true;
15376                mProcessesToGc.add(i+1, proc);
15377                break;
15378            }
15379        }
15380        if (!added) {
15381            mProcessesToGc.add(0, proc);
15382        }
15383    }
15384
15385    /**
15386     * Set up to ask a process to GC itself.  This will either do it
15387     * immediately, or put it on the list of processes to gc the next
15388     * time things are idle.
15389     */
15390    final void scheduleAppGcLocked(ProcessRecord app) {
15391        long now = SystemClock.uptimeMillis();
15392        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15393            return;
15394        }
15395        if (!mProcessesToGc.contains(app)) {
15396            addProcessToGcListLocked(app);
15397            scheduleAppGcsLocked();
15398        }
15399    }
15400
15401    final void checkExcessivePowerUsageLocked(boolean doKills) {
15402        updateCpuStatsNow();
15403
15404        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15405        boolean doWakeKills = doKills;
15406        boolean doCpuKills = doKills;
15407        if (mLastPowerCheckRealtime == 0) {
15408            doWakeKills = false;
15409        }
15410        if (mLastPowerCheckUptime == 0) {
15411            doCpuKills = false;
15412        }
15413        if (stats.isScreenOn()) {
15414            doWakeKills = false;
15415        }
15416        final long curRealtime = SystemClock.elapsedRealtime();
15417        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15418        final long curUptime = SystemClock.uptimeMillis();
15419        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15420        mLastPowerCheckRealtime = curRealtime;
15421        mLastPowerCheckUptime = curUptime;
15422        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15423            doWakeKills = false;
15424        }
15425        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15426            doCpuKills = false;
15427        }
15428        int i = mLruProcesses.size();
15429        while (i > 0) {
15430            i--;
15431            ProcessRecord app = mLruProcesses.get(i);
15432            if (!app.keeping) {
15433                long wtime;
15434                synchronized (stats) {
15435                    wtime = stats.getProcessWakeTime(app.info.uid,
15436                            app.pid, curRealtime);
15437                }
15438                long wtimeUsed = wtime - app.lastWakeTime;
15439                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15440                if (DEBUG_POWER) {
15441                    StringBuilder sb = new StringBuilder(128);
15442                    sb.append("Wake for ");
15443                    app.toShortString(sb);
15444                    sb.append(": over ");
15445                    TimeUtils.formatDuration(realtimeSince, sb);
15446                    sb.append(" used ");
15447                    TimeUtils.formatDuration(wtimeUsed, sb);
15448                    sb.append(" (");
15449                    sb.append((wtimeUsed*100)/realtimeSince);
15450                    sb.append("%)");
15451                    Slog.i(TAG, sb.toString());
15452                    sb.setLength(0);
15453                    sb.append("CPU for ");
15454                    app.toShortString(sb);
15455                    sb.append(": over ");
15456                    TimeUtils.formatDuration(uptimeSince, sb);
15457                    sb.append(" used ");
15458                    TimeUtils.formatDuration(cputimeUsed, sb);
15459                    sb.append(" (");
15460                    sb.append((cputimeUsed*100)/uptimeSince);
15461                    sb.append("%)");
15462                    Slog.i(TAG, sb.toString());
15463                }
15464                // If a process has held a wake lock for more
15465                // than 50% of the time during this period,
15466                // that sounds bad.  Kill!
15467                if (doWakeKills && realtimeSince > 0
15468                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15469                    synchronized (stats) {
15470                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15471                                realtimeSince, wtimeUsed);
15472                    }
15473                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15474                            + " during " + realtimeSince);
15475                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15476                } else if (doCpuKills && uptimeSince > 0
15477                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15478                    synchronized (stats) {
15479                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15480                                uptimeSince, cputimeUsed);
15481                    }
15482                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15483                            + " during " + uptimeSince);
15484                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15485                } else {
15486                    app.lastWakeTime = wtime;
15487                    app.lastCpuTime = app.curCpuTime;
15488                }
15489            }
15490        }
15491    }
15492
15493    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15494            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15495        boolean success = true;
15496
15497        if (app.curRawAdj != app.setRawAdj) {
15498            if (wasKeeping && !app.keeping) {
15499                // This app is no longer something we want to keep.  Note
15500                // its current wake lock time to later know to kill it if
15501                // it is not behaving well.
15502                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15503                synchronized (stats) {
15504                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15505                            app.pid, SystemClock.elapsedRealtime());
15506                }
15507                app.lastCpuTime = app.curCpuTime;
15508            }
15509
15510            app.setRawAdj = app.curRawAdj;
15511        }
15512
15513        if (app.curAdj != app.setAdj) {
15514            ProcessList.setOomAdj(app.pid, app.curAdj);
15515            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15516                TAG, "Set " + app.pid + " " + app.processName +
15517                " adj " + app.curAdj + ": " + app.adjType);
15518            app.setAdj = app.curAdj;
15519        }
15520
15521        if (app.setSchedGroup != app.curSchedGroup) {
15522            app.setSchedGroup = app.curSchedGroup;
15523            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15524                    "Setting process group of " + app.processName
15525                    + " to " + app.curSchedGroup);
15526            if (app.waitingToKill != null &&
15527                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15528                killUnneededProcessLocked(app, app.waitingToKill);
15529                success = false;
15530            } else {
15531                if (true) {
15532                    long oldId = Binder.clearCallingIdentity();
15533                    try {
15534                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15535                    } catch (Exception e) {
15536                        Slog.w(TAG, "Failed setting process group of " + app.pid
15537                                + " to " + app.curSchedGroup);
15538                        e.printStackTrace();
15539                    } finally {
15540                        Binder.restoreCallingIdentity(oldId);
15541                    }
15542                } else {
15543                    if (app.thread != null) {
15544                        try {
15545                            app.thread.setSchedulingGroup(app.curSchedGroup);
15546                        } catch (RemoteException e) {
15547                        }
15548                    }
15549                }
15550                Process.setSwappiness(app.pid,
15551                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15552            }
15553        }
15554        if (app.repProcState != app.curProcState) {
15555            app.repProcState = app.curProcState;
15556            if (!reportingProcessState && app.thread != null) {
15557                try {
15558                    if (false) {
15559                        //RuntimeException h = new RuntimeException("here");
15560                        Slog.i(TAG, "Sending new process state " + app.repProcState
15561                                + " to " + app /*, h*/);
15562                    }
15563                    app.thread.setProcessState(app.repProcState);
15564                } catch (RemoteException e) {
15565                }
15566            }
15567        }
15568        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15569                app.setProcState)) {
15570            app.lastStateTime = now;
15571            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15572                    mSleeping, now);
15573            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15574                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15575                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15576                    + (app.nextPssTime-now) + ": " + app);
15577        } else {
15578            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15579                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15580                requestPssLocked(app, app.setProcState);
15581                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15582                        mSleeping, now);
15583            } else if (false && DEBUG_PSS) {
15584                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15585            }
15586        }
15587        if (app.setProcState != app.curProcState) {
15588            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15589                    "Proc state change of " + app.processName
15590                    + " to " + app.curProcState);
15591            app.setProcState = app.curProcState;
15592            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15593                app.notCachedSinceIdle = false;
15594            }
15595            if (!doingAll) {
15596                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15597            } else {
15598                app.procStateChanged = true;
15599            }
15600        }
15601        return success;
15602    }
15603
15604    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15605        if (proc.thread != null && proc.baseProcessTracker != null) {
15606            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15607        }
15608    }
15609
15610    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15611            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15612        if (app.thread == null) {
15613            return false;
15614        }
15615
15616        final boolean wasKeeping = app.keeping;
15617
15618        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15619
15620        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15621                reportingProcessState, now);
15622    }
15623
15624    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15625            boolean oomAdj) {
15626        if (isForeground != proc.foregroundServices) {
15627            proc.foregroundServices = isForeground;
15628            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15629                    proc.info.uid);
15630            if (isForeground) {
15631                if (curProcs == null) {
15632                    curProcs = new ArrayList<ProcessRecord>();
15633                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15634                }
15635                if (!curProcs.contains(proc)) {
15636                    curProcs.add(proc);
15637                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15638                            proc.info.packageName, proc.info.uid);
15639                }
15640            } else {
15641                if (curProcs != null) {
15642                    if (curProcs.remove(proc)) {
15643                        mBatteryStatsService.noteEvent(
15644                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15645                                proc.info.packageName, proc.info.uid);
15646                        if (curProcs.size() <= 0) {
15647                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15648                        }
15649                    }
15650                }
15651            }
15652            if (oomAdj) {
15653                updateOomAdjLocked();
15654            }
15655        }
15656    }
15657
15658    private final ActivityRecord resumedAppLocked() {
15659        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15660        String pkg;
15661        int uid;
15662        if (act != null && !act.sleeping) {
15663            pkg = act.packageName;
15664            uid = act.info.applicationInfo.uid;
15665        } else {
15666            pkg = null;
15667            uid = -1;
15668        }
15669        // Has the UID or resumed package name changed?
15670        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15671                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15672            if (mCurResumedPackage != null) {
15673                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15674                        mCurResumedPackage, mCurResumedUid);
15675            }
15676            mCurResumedPackage = pkg;
15677            mCurResumedUid = uid;
15678            if (mCurResumedPackage != null) {
15679                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15680                        mCurResumedPackage, mCurResumedUid);
15681            }
15682        }
15683        return act;
15684    }
15685
15686    final boolean updateOomAdjLocked(ProcessRecord app) {
15687        return updateOomAdjLocked(app, false);
15688    }
15689
15690    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15691        final ActivityRecord TOP_ACT = resumedAppLocked();
15692        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15693        final boolean wasCached = app.cached;
15694
15695        mAdjSeq++;
15696
15697        // This is the desired cached adjusment we want to tell it to use.
15698        // If our app is currently cached, we know it, and that is it.  Otherwise,
15699        // we don't know it yet, and it needs to now be cached we will then
15700        // need to do a complete oom adj.
15701        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15702                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15703        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15704                SystemClock.uptimeMillis());
15705        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15706            // Changed to/from cached state, so apps after it in the LRU
15707            // list may also be changed.
15708            updateOomAdjLocked();
15709        }
15710        return success;
15711    }
15712
15713    final void updateOomAdjLocked() {
15714        final ActivityRecord TOP_ACT = resumedAppLocked();
15715        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15716        final long now = SystemClock.uptimeMillis();
15717        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15718        final int N = mLruProcesses.size();
15719
15720        if (false) {
15721            RuntimeException e = new RuntimeException();
15722            e.fillInStackTrace();
15723            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15724        }
15725
15726        mAdjSeq++;
15727        mNewNumServiceProcs = 0;
15728        mNewNumAServiceProcs = 0;
15729
15730        final int emptyProcessLimit;
15731        final int cachedProcessLimit;
15732        if (mProcessLimit <= 0) {
15733            emptyProcessLimit = cachedProcessLimit = 0;
15734        } else if (mProcessLimit == 1) {
15735            emptyProcessLimit = 1;
15736            cachedProcessLimit = 0;
15737        } else {
15738            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15739            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15740        }
15741
15742        // Let's determine how many processes we have running vs.
15743        // how many slots we have for background processes; we may want
15744        // to put multiple processes in a slot of there are enough of
15745        // them.
15746        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15747                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15748        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15749        if (numEmptyProcs > cachedProcessLimit) {
15750            // If there are more empty processes than our limit on cached
15751            // processes, then use the cached process limit for the factor.
15752            // This ensures that the really old empty processes get pushed
15753            // down to the bottom, so if we are running low on memory we will
15754            // have a better chance at keeping around more cached processes
15755            // instead of a gazillion empty processes.
15756            numEmptyProcs = cachedProcessLimit;
15757        }
15758        int emptyFactor = numEmptyProcs/numSlots;
15759        if (emptyFactor < 1) emptyFactor = 1;
15760        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15761        if (cachedFactor < 1) cachedFactor = 1;
15762        int stepCached = 0;
15763        int stepEmpty = 0;
15764        int numCached = 0;
15765        int numEmpty = 0;
15766        int numTrimming = 0;
15767
15768        mNumNonCachedProcs = 0;
15769        mNumCachedHiddenProcs = 0;
15770
15771        // First update the OOM adjustment for each of the
15772        // application processes based on their current state.
15773        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15774        int nextCachedAdj = curCachedAdj+1;
15775        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15776        int nextEmptyAdj = curEmptyAdj+2;
15777        for (int i=N-1; i>=0; i--) {
15778            ProcessRecord app = mLruProcesses.get(i);
15779            if (!app.killedByAm && app.thread != null) {
15780                app.procStateChanged = false;
15781                final boolean wasKeeping = app.keeping;
15782                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15783
15784                // If we haven't yet assigned the final cached adj
15785                // to the process, do that now.
15786                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15787                    switch (app.curProcState) {
15788                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15789                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15790                            // This process is a cached process holding activities...
15791                            // assign it the next cached value for that type, and then
15792                            // step that cached level.
15793                            app.curRawAdj = curCachedAdj;
15794                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15795                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15796                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15797                                    + ")");
15798                            if (curCachedAdj != nextCachedAdj) {
15799                                stepCached++;
15800                                if (stepCached >= cachedFactor) {
15801                                    stepCached = 0;
15802                                    curCachedAdj = nextCachedAdj;
15803                                    nextCachedAdj += 2;
15804                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15805                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15806                                    }
15807                                }
15808                            }
15809                            break;
15810                        default:
15811                            // For everything else, assign next empty cached process
15812                            // level and bump that up.  Note that this means that
15813                            // long-running services that have dropped down to the
15814                            // cached level will be treated as empty (since their process
15815                            // state is still as a service), which is what we want.
15816                            app.curRawAdj = curEmptyAdj;
15817                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15818                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15819                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15820                                    + ")");
15821                            if (curEmptyAdj != nextEmptyAdj) {
15822                                stepEmpty++;
15823                                if (stepEmpty >= emptyFactor) {
15824                                    stepEmpty = 0;
15825                                    curEmptyAdj = nextEmptyAdj;
15826                                    nextEmptyAdj += 2;
15827                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15828                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15829                                    }
15830                                }
15831                            }
15832                            break;
15833                    }
15834                }
15835
15836                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15837
15838                // Count the number of process types.
15839                switch (app.curProcState) {
15840                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15841                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15842                        mNumCachedHiddenProcs++;
15843                        numCached++;
15844                        if (numCached > cachedProcessLimit) {
15845                            killUnneededProcessLocked(app, "cached #" + numCached);
15846                        }
15847                        break;
15848                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15849                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15850                                && app.lastActivityTime < oldTime) {
15851                            killUnneededProcessLocked(app, "empty for "
15852                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15853                                    / 1000) + "s");
15854                        } else {
15855                            numEmpty++;
15856                            if (numEmpty > emptyProcessLimit) {
15857                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15858                            }
15859                        }
15860                        break;
15861                    default:
15862                        mNumNonCachedProcs++;
15863                        break;
15864                }
15865
15866                if (app.isolated && app.services.size() <= 0) {
15867                    // If this is an isolated process, and there are no
15868                    // services running in it, then the process is no longer
15869                    // needed.  We agressively kill these because we can by
15870                    // definition not re-use the same process again, and it is
15871                    // good to avoid having whatever code was running in them
15872                    // left sitting around after no longer needed.
15873                    killUnneededProcessLocked(app, "isolated not needed");
15874                }
15875
15876                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15877                        && !app.killedByAm) {
15878                    numTrimming++;
15879                }
15880            }
15881        }
15882
15883        mNumServiceProcs = mNewNumServiceProcs;
15884
15885        // Now determine the memory trimming level of background processes.
15886        // Unfortunately we need to start at the back of the list to do this
15887        // properly.  We only do this if the number of background apps we
15888        // are managing to keep around is less than half the maximum we desire;
15889        // if we are keeping a good number around, we'll let them use whatever
15890        // memory they want.
15891        final int numCachedAndEmpty = numCached + numEmpty;
15892        int memFactor;
15893        if (numCached <= ProcessList.TRIM_CACHED_APPS
15894                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15895            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15896                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15897            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15898                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15899            } else {
15900                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15901            }
15902        } else {
15903            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15904        }
15905        // We always allow the memory level to go up (better).  We only allow it to go
15906        // down if we are in a state where that is allowed, *and* the total number of processes
15907        // has gone down since last time.
15908        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15909                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15910                + " last=" + mLastNumProcesses);
15911        if (memFactor > mLastMemoryLevel) {
15912            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15913                memFactor = mLastMemoryLevel;
15914                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15915            }
15916        }
15917        mLastMemoryLevel = memFactor;
15918        mLastNumProcesses = mLruProcesses.size();
15919        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15920        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15921        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15922            if (mLowRamStartTime == 0) {
15923                mLowRamStartTime = now;
15924            }
15925            int step = 0;
15926            int fgTrimLevel;
15927            switch (memFactor) {
15928                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15929                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15930                    break;
15931                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15932                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15933                    break;
15934                default:
15935                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15936                    break;
15937            }
15938            int factor = numTrimming/3;
15939            int minFactor = 2;
15940            if (mHomeProcess != null) minFactor++;
15941            if (mPreviousProcess != null) minFactor++;
15942            if (factor < minFactor) factor = minFactor;
15943            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15944            for (int i=N-1; i>=0; i--) {
15945                ProcessRecord app = mLruProcesses.get(i);
15946                if (allChanged || app.procStateChanged) {
15947                    setProcessTrackerState(app, trackerMemFactor, now);
15948                    app.procStateChanged = false;
15949                }
15950                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15951                        && !app.killedByAm) {
15952                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15953                        try {
15954                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15955                                    "Trimming memory of " + app.processName
15956                                    + " to " + curLevel);
15957                            app.thread.scheduleTrimMemory(curLevel);
15958                        } catch (RemoteException e) {
15959                        }
15960                        if (false) {
15961                            // For now we won't do this; our memory trimming seems
15962                            // to be good enough at this point that destroying
15963                            // activities causes more harm than good.
15964                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15965                                    && app != mHomeProcess && app != mPreviousProcess) {
15966                                // Need to do this on its own message because the stack may not
15967                                // be in a consistent state at this point.
15968                                // For these apps we will also finish their activities
15969                                // to help them free memory.
15970                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15971                            }
15972                        }
15973                    }
15974                    app.trimMemoryLevel = curLevel;
15975                    step++;
15976                    if (step >= factor) {
15977                        step = 0;
15978                        switch (curLevel) {
15979                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15980                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15981                                break;
15982                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15983                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15984                                break;
15985                        }
15986                    }
15987                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15988                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15989                            && app.thread != null) {
15990                        try {
15991                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15992                                    "Trimming memory of heavy-weight " + app.processName
15993                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15994                            app.thread.scheduleTrimMemory(
15995                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15996                        } catch (RemoteException e) {
15997                        }
15998                    }
15999                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16000                } else {
16001                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16002                            || app.systemNoUi) && app.pendingUiClean) {
16003                        // If this application is now in the background and it
16004                        // had done UI, then give it the special trim level to
16005                        // have it free UI resources.
16006                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16007                        if (app.trimMemoryLevel < level && app.thread != null) {
16008                            try {
16009                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16010                                        "Trimming memory of bg-ui " + app.processName
16011                                        + " to " + level);
16012                                app.thread.scheduleTrimMemory(level);
16013                            } catch (RemoteException e) {
16014                            }
16015                        }
16016                        app.pendingUiClean = false;
16017                    }
16018                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16019                        try {
16020                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16021                                    "Trimming memory of fg " + app.processName
16022                                    + " to " + fgTrimLevel);
16023                            app.thread.scheduleTrimMemory(fgTrimLevel);
16024                        } catch (RemoteException e) {
16025                        }
16026                    }
16027                    app.trimMemoryLevel = fgTrimLevel;
16028                }
16029            }
16030        } else {
16031            if (mLowRamStartTime != 0) {
16032                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16033                mLowRamStartTime = 0;
16034            }
16035            for (int i=N-1; i>=0; i--) {
16036                ProcessRecord app = mLruProcesses.get(i);
16037                if (allChanged || app.procStateChanged) {
16038                    setProcessTrackerState(app, trackerMemFactor, now);
16039                    app.procStateChanged = false;
16040                }
16041                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16042                        || app.systemNoUi) && app.pendingUiClean) {
16043                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16044                            && app.thread != null) {
16045                        try {
16046                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16047                                    "Trimming memory of ui hidden " + app.processName
16048                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16049                            app.thread.scheduleTrimMemory(
16050                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16051                        } catch (RemoteException e) {
16052                        }
16053                    }
16054                    app.pendingUiClean = false;
16055                }
16056                app.trimMemoryLevel = 0;
16057            }
16058        }
16059
16060        if (mAlwaysFinishActivities) {
16061            // Need to do this on its own message because the stack may not
16062            // be in a consistent state at this point.
16063            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16064        }
16065
16066        if (allChanged) {
16067            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16068        }
16069
16070        if (mProcessStats.shouldWriteNowLocked(now)) {
16071            mHandler.post(new Runnable() {
16072                @Override public void run() {
16073                    synchronized (ActivityManagerService.this) {
16074                        mProcessStats.writeStateAsyncLocked();
16075                    }
16076                }
16077            });
16078        }
16079
16080        if (DEBUG_OOM_ADJ) {
16081            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16082        }
16083    }
16084
16085    final void trimApplications() {
16086        synchronized (this) {
16087            int i;
16088
16089            // First remove any unused application processes whose package
16090            // has been removed.
16091            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16092                final ProcessRecord app = mRemovedProcesses.get(i);
16093                if (app.activities.size() == 0
16094                        && app.curReceiver == null && app.services.size() == 0) {
16095                    Slog.i(
16096                        TAG, "Exiting empty application process "
16097                        + app.processName + " ("
16098                        + (app.thread != null ? app.thread.asBinder() : null)
16099                        + ")\n");
16100                    if (app.pid > 0 && app.pid != MY_PID) {
16101                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16102                                app.processName, app.setAdj, "empty");
16103                        app.killedByAm = true;
16104                        Process.killProcessQuiet(app.pid);
16105                    } else {
16106                        try {
16107                            app.thread.scheduleExit();
16108                        } catch (Exception e) {
16109                            // Ignore exceptions.
16110                        }
16111                    }
16112                    cleanUpApplicationRecordLocked(app, false, true, -1);
16113                    mRemovedProcesses.remove(i);
16114
16115                    if (app.persistent) {
16116                        if (app.persistent) {
16117                            addAppLocked(app.info, false);
16118                        }
16119                    }
16120                }
16121            }
16122
16123            // Now update the oom adj for all processes.
16124            updateOomAdjLocked();
16125        }
16126    }
16127
16128    /** This method sends the specified signal to each of the persistent apps */
16129    public void signalPersistentProcesses(int sig) throws RemoteException {
16130        if (sig != Process.SIGNAL_USR1) {
16131            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16132        }
16133
16134        synchronized (this) {
16135            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16136                    != PackageManager.PERMISSION_GRANTED) {
16137                throw new SecurityException("Requires permission "
16138                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16139            }
16140
16141            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16142                ProcessRecord r = mLruProcesses.get(i);
16143                if (r.thread != null && r.persistent) {
16144                    Process.sendSignal(r.pid, sig);
16145                }
16146            }
16147        }
16148    }
16149
16150    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16151        if (proc == null || proc == mProfileProc) {
16152            proc = mProfileProc;
16153            path = mProfileFile;
16154            profileType = mProfileType;
16155            clearProfilerLocked();
16156        }
16157        if (proc == null) {
16158            return;
16159        }
16160        try {
16161            proc.thread.profilerControl(false, path, null, profileType);
16162        } catch (RemoteException e) {
16163            throw new IllegalStateException("Process disappeared");
16164        }
16165    }
16166
16167    private void clearProfilerLocked() {
16168        if (mProfileFd != null) {
16169            try {
16170                mProfileFd.close();
16171            } catch (IOException e) {
16172            }
16173        }
16174        mProfileApp = null;
16175        mProfileProc = null;
16176        mProfileFile = null;
16177        mProfileType = 0;
16178        mAutoStopProfiler = false;
16179    }
16180
16181    public boolean profileControl(String process, int userId, boolean start,
16182            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16183
16184        try {
16185            synchronized (this) {
16186                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16187                // its own permission.
16188                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16189                        != PackageManager.PERMISSION_GRANTED) {
16190                    throw new SecurityException("Requires permission "
16191                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16192                }
16193
16194                if (start && fd == null) {
16195                    throw new IllegalArgumentException("null fd");
16196                }
16197
16198                ProcessRecord proc = null;
16199                if (process != null) {
16200                    proc = findProcessLocked(process, userId, "profileControl");
16201                }
16202
16203                if (start && (proc == null || proc.thread == null)) {
16204                    throw new IllegalArgumentException("Unknown process: " + process);
16205                }
16206
16207                if (start) {
16208                    stopProfilerLocked(null, null, 0);
16209                    setProfileApp(proc.info, proc.processName, path, fd, false);
16210                    mProfileProc = proc;
16211                    mProfileType = profileType;
16212                    try {
16213                        fd = fd.dup();
16214                    } catch (IOException e) {
16215                        fd = null;
16216                    }
16217                    proc.thread.profilerControl(start, path, fd, profileType);
16218                    fd = null;
16219                    mProfileFd = null;
16220                } else {
16221                    stopProfilerLocked(proc, path, profileType);
16222                    if (fd != null) {
16223                        try {
16224                            fd.close();
16225                        } catch (IOException e) {
16226                        }
16227                    }
16228                }
16229
16230                return true;
16231            }
16232        } catch (RemoteException e) {
16233            throw new IllegalStateException("Process disappeared");
16234        } finally {
16235            if (fd != null) {
16236                try {
16237                    fd.close();
16238                } catch (IOException e) {
16239                }
16240            }
16241        }
16242    }
16243
16244    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16245        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16246                userId, true, true, callName, null);
16247        ProcessRecord proc = null;
16248        try {
16249            int pid = Integer.parseInt(process);
16250            synchronized (mPidsSelfLocked) {
16251                proc = mPidsSelfLocked.get(pid);
16252            }
16253        } catch (NumberFormatException e) {
16254        }
16255
16256        if (proc == null) {
16257            ArrayMap<String, SparseArray<ProcessRecord>> all
16258                    = mProcessNames.getMap();
16259            SparseArray<ProcessRecord> procs = all.get(process);
16260            if (procs != null && procs.size() > 0) {
16261                proc = procs.valueAt(0);
16262                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16263                    for (int i=1; i<procs.size(); i++) {
16264                        ProcessRecord thisProc = procs.valueAt(i);
16265                        if (thisProc.userId == userId) {
16266                            proc = thisProc;
16267                            break;
16268                        }
16269                    }
16270                }
16271            }
16272        }
16273
16274        return proc;
16275    }
16276
16277    public boolean dumpHeap(String process, int userId, boolean managed,
16278            String path, ParcelFileDescriptor fd) throws RemoteException {
16279
16280        try {
16281            synchronized (this) {
16282                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16283                // its own permission (same as profileControl).
16284                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16285                        != PackageManager.PERMISSION_GRANTED) {
16286                    throw new SecurityException("Requires permission "
16287                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16288                }
16289
16290                if (fd == null) {
16291                    throw new IllegalArgumentException("null fd");
16292                }
16293
16294                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16295                if (proc == null || proc.thread == null) {
16296                    throw new IllegalArgumentException("Unknown process: " + process);
16297                }
16298
16299                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16300                if (!isDebuggable) {
16301                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16302                        throw new SecurityException("Process not debuggable: " + proc);
16303                    }
16304                }
16305
16306                proc.thread.dumpHeap(managed, path, fd);
16307                fd = null;
16308                return true;
16309            }
16310        } catch (RemoteException e) {
16311            throw new IllegalStateException("Process disappeared");
16312        } finally {
16313            if (fd != null) {
16314                try {
16315                    fd.close();
16316                } catch (IOException e) {
16317                }
16318            }
16319        }
16320    }
16321
16322    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16323    public void monitor() {
16324        synchronized (this) { }
16325    }
16326
16327    void onCoreSettingsChange(Bundle settings) {
16328        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16329            ProcessRecord processRecord = mLruProcesses.get(i);
16330            try {
16331                if (processRecord.thread != null) {
16332                    processRecord.thread.setCoreSettings(settings);
16333                }
16334            } catch (RemoteException re) {
16335                /* ignore */
16336            }
16337        }
16338    }
16339
16340    // Multi-user methods
16341
16342    /**
16343     * Start user, if its not already running, but don't bring it to foreground.
16344     */
16345    @Override
16346    public boolean startUserInBackground(final int userId) {
16347        return startUser(userId, /* foreground */ false);
16348    }
16349
16350    /**
16351     * Refreshes the list of users related to the current user when either a
16352     * user switch happens or when a new related user is started in the
16353     * background.
16354     */
16355    private void updateCurrentProfileIdsLocked() {
16356        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId);
16357        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16358        for (int i = 0; i < currentProfileIds.length; i++) {
16359            currentProfileIds[i] = profiles.get(i).id;
16360        }
16361        mCurrentProfileIds = currentProfileIds;
16362    }
16363
16364    private Set getProfileIdsLocked(int userId) {
16365        Set userIds = new HashSet<Integer>();
16366        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(userId);
16367        for (UserInfo user : profiles) {
16368            userIds.add(Integer.valueOf(user.id));
16369        }
16370        return userIds;
16371    }
16372
16373    @Override
16374    public boolean switchUser(final int userId) {
16375        return startUser(userId, /* foregound */ true);
16376    }
16377
16378    private boolean startUser(final int userId, boolean foreground) {
16379        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16380                != PackageManager.PERMISSION_GRANTED) {
16381            String msg = "Permission Denial: switchUser() from pid="
16382                    + Binder.getCallingPid()
16383                    + ", uid=" + Binder.getCallingUid()
16384                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16385            Slog.w(TAG, msg);
16386            throw new SecurityException(msg);
16387        }
16388
16389        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16390
16391        final long ident = Binder.clearCallingIdentity();
16392        try {
16393            synchronized (this) {
16394                final int oldUserId = mCurrentUserId;
16395                if (oldUserId == userId) {
16396                    return true;
16397                }
16398
16399                mStackSupervisor.setLockTaskModeLocked(null);
16400
16401                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16402                if (userInfo == null) {
16403                    Slog.w(TAG, "No user info for user #" + userId);
16404                    return false;
16405                }
16406
16407                if (foreground) {
16408                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16409                            R.anim.screen_user_enter);
16410                }
16411
16412                boolean needStart = false;
16413
16414                // If the user we are switching to is not currently started, then
16415                // we need to start it now.
16416                if (mStartedUsers.get(userId) == null) {
16417                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16418                    updateStartedUserArrayLocked();
16419                    needStart = true;
16420                }
16421
16422                final Integer userIdInt = Integer.valueOf(userId);
16423                mUserLru.remove(userIdInt);
16424                mUserLru.add(userIdInt);
16425
16426                if (foreground) {
16427                    mCurrentUserId = userId;
16428                    updateCurrentProfileIdsLocked();
16429                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16430                    // Once the internal notion of the active user has switched, we lock the device
16431                    // with the option to show the user switcher on the keyguard.
16432                    mWindowManager.lockNow(null);
16433                } else {
16434                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16435                    updateCurrentProfileIdsLocked();
16436                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16437                    mUserLru.remove(currentUserIdInt);
16438                    mUserLru.add(currentUserIdInt);
16439                }
16440
16441                final UserStartedState uss = mStartedUsers.get(userId);
16442
16443                // Make sure user is in the started state.  If it is currently
16444                // stopping, we need to knock that off.
16445                if (uss.mState == UserStartedState.STATE_STOPPING) {
16446                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16447                    // so we can just fairly silently bring the user back from
16448                    // the almost-dead.
16449                    uss.mState = UserStartedState.STATE_RUNNING;
16450                    updateStartedUserArrayLocked();
16451                    needStart = true;
16452                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16453                    // This means ACTION_SHUTDOWN has been sent, so we will
16454                    // need to treat this as a new boot of the user.
16455                    uss.mState = UserStartedState.STATE_BOOTING;
16456                    updateStartedUserArrayLocked();
16457                    needStart = true;
16458                }
16459
16460                if (foreground) {
16461                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16462                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16463                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16464                            oldUserId, userId, uss));
16465                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16466                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16467                }
16468
16469                if (needStart) {
16470                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16471                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16472                            | Intent.FLAG_RECEIVER_FOREGROUND);
16473                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16474                    broadcastIntentLocked(null, null, intent,
16475                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16476                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16477                }
16478
16479                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16480                    if (userId != 0) {
16481                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16482                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16483                        broadcastIntentLocked(null, null, intent, null,
16484                                new IIntentReceiver.Stub() {
16485                                    public void performReceive(Intent intent, int resultCode,
16486                                            String data, Bundle extras, boolean ordered,
16487                                            boolean sticky, int sendingUser) {
16488                                        userInitialized(uss, userId);
16489                                    }
16490                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16491                                true, false, MY_PID, Process.SYSTEM_UID,
16492                                userId);
16493                        uss.initializing = true;
16494                    } else {
16495                        getUserManagerLocked().makeInitialized(userInfo.id);
16496                    }
16497                }
16498
16499                if (foreground) {
16500                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16501                    if (homeInFront) {
16502                        startHomeActivityLocked(userId);
16503                    } else {
16504                        mStackSupervisor.resumeTopActivitiesLocked();
16505                    }
16506                    EventLogTags.writeAmSwitchUser(userId);
16507                    getUserManagerLocked().userForeground(userId);
16508                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16509                }
16510
16511                if (needStart) {
16512                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16513                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16514                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16515                    broadcastIntentLocked(null, null, intent,
16516                            null, new IIntentReceiver.Stub() {
16517                                @Override
16518                                public void performReceive(Intent intent, int resultCode, String data,
16519                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16520                                        throws RemoteException {
16521                                }
16522                            }, 0, null, null,
16523                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16524                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16525                }
16526            }
16527        } finally {
16528            Binder.restoreCallingIdentity(ident);
16529        }
16530
16531        return true;
16532    }
16533
16534    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16535        long ident = Binder.clearCallingIdentity();
16536        try {
16537            Intent intent;
16538            if (oldUserId >= 0) {
16539                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16540                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16541                        | Intent.FLAG_RECEIVER_FOREGROUND);
16542                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16543                broadcastIntentLocked(null, null, intent,
16544                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16545                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16546            }
16547            if (newUserId >= 0) {
16548                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16549                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16550                        | Intent.FLAG_RECEIVER_FOREGROUND);
16551                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16552                broadcastIntentLocked(null, null, intent,
16553                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16554                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16555                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16556                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16557                        | Intent.FLAG_RECEIVER_FOREGROUND);
16558                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16559                broadcastIntentLocked(null, null, intent,
16560                        null, null, 0, null, null,
16561                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16562                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16563            }
16564        } finally {
16565            Binder.restoreCallingIdentity(ident);
16566        }
16567    }
16568
16569    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16570            final int newUserId) {
16571        final int N = mUserSwitchObservers.beginBroadcast();
16572        if (N > 0) {
16573            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16574                int mCount = 0;
16575                @Override
16576                public void sendResult(Bundle data) throws RemoteException {
16577                    synchronized (ActivityManagerService.this) {
16578                        if (mCurUserSwitchCallback == this) {
16579                            mCount++;
16580                            if (mCount == N) {
16581                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16582                            }
16583                        }
16584                    }
16585                }
16586            };
16587            synchronized (this) {
16588                uss.switching = true;
16589                mCurUserSwitchCallback = callback;
16590            }
16591            for (int i=0; i<N; i++) {
16592                try {
16593                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16594                            newUserId, callback);
16595                } catch (RemoteException e) {
16596                }
16597            }
16598        } else {
16599            synchronized (this) {
16600                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16601            }
16602        }
16603        mUserSwitchObservers.finishBroadcast();
16604    }
16605
16606    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16607        synchronized (this) {
16608            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16609            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16610        }
16611    }
16612
16613    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16614        mCurUserSwitchCallback = null;
16615        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16616        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16617                oldUserId, newUserId, uss));
16618    }
16619
16620    void userInitialized(UserStartedState uss, int newUserId) {
16621        completeSwitchAndInitalize(uss, newUserId, true, false);
16622    }
16623
16624    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16625        completeSwitchAndInitalize(uss, newUserId, false, true);
16626    }
16627
16628    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16629            boolean clearInitializing, boolean clearSwitching) {
16630        boolean unfrozen = false;
16631        synchronized (this) {
16632            if (clearInitializing) {
16633                uss.initializing = false;
16634                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16635            }
16636            if (clearSwitching) {
16637                uss.switching = false;
16638            }
16639            if (!uss.switching && !uss.initializing) {
16640                mWindowManager.stopFreezingScreen();
16641                unfrozen = true;
16642            }
16643        }
16644        if (unfrozen) {
16645            final int N = mUserSwitchObservers.beginBroadcast();
16646            for (int i=0; i<N; i++) {
16647                try {
16648                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16649                } catch (RemoteException e) {
16650                }
16651            }
16652            mUserSwitchObservers.finishBroadcast();
16653        }
16654    }
16655
16656    void scheduleStartProfilesLocked() {
16657        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16658            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16659                    DateUtils.SECOND_IN_MILLIS);
16660        }
16661    }
16662
16663    void startProfilesLocked() {
16664        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16665        List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId);
16666        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16667        for (UserInfo user : profiles) {
16668            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16669                    && user.id != mCurrentUserId) {
16670                toStart.add(user);
16671            }
16672        }
16673        final int n = toStart.size();
16674        int i = 0;
16675        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16676            startUserInBackground(toStart.get(i).id);
16677        }
16678        if (i < n) {
16679            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16680        }
16681    }
16682
16683    void finishUserSwitch(UserStartedState uss) {
16684        synchronized (this) {
16685            if (uss.mState == UserStartedState.STATE_BOOTING
16686                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16687                uss.mState = UserStartedState.STATE_RUNNING;
16688                final int userId = uss.mHandle.getIdentifier();
16689                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16690                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16691                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16692                broadcastIntentLocked(null, null, intent,
16693                        null, null, 0, null, null,
16694                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16695                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16696            }
16697
16698            startProfilesLocked();
16699
16700            int num = mUserLru.size();
16701            int i = 0;
16702            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16703                Integer oldUserId = mUserLru.get(i);
16704                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16705                if (oldUss == null) {
16706                    // Shouldn't happen, but be sane if it does.
16707                    mUserLru.remove(i);
16708                    num--;
16709                    continue;
16710                }
16711                if (oldUss.mState == UserStartedState.STATE_STOPPING
16712                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16713                    // This user is already stopping, doesn't count.
16714                    num--;
16715                    i++;
16716                    continue;
16717                }
16718                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16719                    // Owner and current can't be stopped, but count as running.
16720                    i++;
16721                    continue;
16722                }
16723                // This is a user to be stopped.
16724                stopUserLocked(oldUserId, null);
16725                num--;
16726                i++;
16727            }
16728        }
16729    }
16730
16731    @Override
16732    public int stopUser(final int userId, final IStopUserCallback callback) {
16733        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16734                != PackageManager.PERMISSION_GRANTED) {
16735            String msg = "Permission Denial: switchUser() from pid="
16736                    + Binder.getCallingPid()
16737                    + ", uid=" + Binder.getCallingUid()
16738                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16739            Slog.w(TAG, msg);
16740            throw new SecurityException(msg);
16741        }
16742        if (userId <= 0) {
16743            throw new IllegalArgumentException("Can't stop primary user " + userId);
16744        }
16745        synchronized (this) {
16746            return stopUserLocked(userId, callback);
16747        }
16748    }
16749
16750    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16751        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16752        if (mCurrentUserId == userId) {
16753            return ActivityManager.USER_OP_IS_CURRENT;
16754        }
16755
16756        final UserStartedState uss = mStartedUsers.get(userId);
16757        if (uss == null) {
16758            // User is not started, nothing to do...  but we do need to
16759            // callback if requested.
16760            if (callback != null) {
16761                mHandler.post(new Runnable() {
16762                    @Override
16763                    public void run() {
16764                        try {
16765                            callback.userStopped(userId);
16766                        } catch (RemoteException e) {
16767                        }
16768                    }
16769                });
16770            }
16771            return ActivityManager.USER_OP_SUCCESS;
16772        }
16773
16774        if (callback != null) {
16775            uss.mStopCallbacks.add(callback);
16776        }
16777
16778        if (uss.mState != UserStartedState.STATE_STOPPING
16779                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16780            uss.mState = UserStartedState.STATE_STOPPING;
16781            updateStartedUserArrayLocked();
16782
16783            long ident = Binder.clearCallingIdentity();
16784            try {
16785                // We are going to broadcast ACTION_USER_STOPPING and then
16786                // once that is done send a final ACTION_SHUTDOWN and then
16787                // stop the user.
16788                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16789                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16790                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16791                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16792                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16793                // This is the result receiver for the final shutdown broadcast.
16794                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16795                    @Override
16796                    public void performReceive(Intent intent, int resultCode, String data,
16797                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16798                        finishUserStop(uss);
16799                    }
16800                };
16801                // This is the result receiver for the initial stopping broadcast.
16802                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16803                    @Override
16804                    public void performReceive(Intent intent, int resultCode, String data,
16805                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16806                        // On to the next.
16807                        synchronized (ActivityManagerService.this) {
16808                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16809                                // Whoops, we are being started back up.  Abort, abort!
16810                                return;
16811                            }
16812                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16813                        }
16814                        broadcastIntentLocked(null, null, shutdownIntent,
16815                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16816                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16817                    }
16818                };
16819                // Kick things off.
16820                broadcastIntentLocked(null, null, stoppingIntent,
16821                        null, stoppingReceiver, 0, null, null,
16822                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16823                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16824            } finally {
16825                Binder.restoreCallingIdentity(ident);
16826            }
16827        }
16828
16829        return ActivityManager.USER_OP_SUCCESS;
16830    }
16831
16832    void finishUserStop(UserStartedState uss) {
16833        final int userId = uss.mHandle.getIdentifier();
16834        boolean stopped;
16835        ArrayList<IStopUserCallback> callbacks;
16836        synchronized (this) {
16837            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16838            if (mStartedUsers.get(userId) != uss) {
16839                stopped = false;
16840            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16841                stopped = false;
16842            } else {
16843                stopped = true;
16844                // User can no longer run.
16845                mStartedUsers.remove(userId);
16846                mUserLru.remove(Integer.valueOf(userId));
16847                updateStartedUserArrayLocked();
16848
16849                // Clean up all state and processes associated with the user.
16850                // Kill all the processes for the user.
16851                forceStopUserLocked(userId, "finish user");
16852            }
16853        }
16854
16855        for (int i=0; i<callbacks.size(); i++) {
16856            try {
16857                if (stopped) callbacks.get(i).userStopped(userId);
16858                else callbacks.get(i).userStopAborted(userId);
16859            } catch (RemoteException e) {
16860            }
16861        }
16862
16863        mStackSupervisor.removeUserLocked(userId);
16864    }
16865
16866    @Override
16867    public UserInfo getCurrentUser() {
16868        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16869                != PackageManager.PERMISSION_GRANTED) && (
16870                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16871                != PackageManager.PERMISSION_GRANTED)) {
16872            String msg = "Permission Denial: getCurrentUser() from pid="
16873                    + Binder.getCallingPid()
16874                    + ", uid=" + Binder.getCallingUid()
16875                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16876            Slog.w(TAG, msg);
16877            throw new SecurityException(msg);
16878        }
16879        synchronized (this) {
16880            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16881        }
16882    }
16883
16884    int getCurrentUserIdLocked() {
16885        return mCurrentUserId;
16886    }
16887
16888    @Override
16889    public boolean isUserRunning(int userId, boolean orStopped) {
16890        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16891                != PackageManager.PERMISSION_GRANTED) {
16892            String msg = "Permission Denial: isUserRunning() from pid="
16893                    + Binder.getCallingPid()
16894                    + ", uid=" + Binder.getCallingUid()
16895                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16896            Slog.w(TAG, msg);
16897            throw new SecurityException(msg);
16898        }
16899        synchronized (this) {
16900            return isUserRunningLocked(userId, orStopped);
16901        }
16902    }
16903
16904    boolean isUserRunningLocked(int userId, boolean orStopped) {
16905        UserStartedState state = mStartedUsers.get(userId);
16906        if (state == null) {
16907            return false;
16908        }
16909        if (orStopped) {
16910            return true;
16911        }
16912        return state.mState != UserStartedState.STATE_STOPPING
16913                && state.mState != UserStartedState.STATE_SHUTDOWN;
16914    }
16915
16916    @Override
16917    public int[] getRunningUserIds() {
16918        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16919                != PackageManager.PERMISSION_GRANTED) {
16920            String msg = "Permission Denial: isUserRunning() from pid="
16921                    + Binder.getCallingPid()
16922                    + ", uid=" + Binder.getCallingUid()
16923                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16924            Slog.w(TAG, msg);
16925            throw new SecurityException(msg);
16926        }
16927        synchronized (this) {
16928            return mStartedUserArray;
16929        }
16930    }
16931
16932    private void updateStartedUserArrayLocked() {
16933        int num = 0;
16934        for (int i=0; i<mStartedUsers.size();  i++) {
16935            UserStartedState uss = mStartedUsers.valueAt(i);
16936            // This list does not include stopping users.
16937            if (uss.mState != UserStartedState.STATE_STOPPING
16938                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16939                num++;
16940            }
16941        }
16942        mStartedUserArray = new int[num];
16943        num = 0;
16944        for (int i=0; i<mStartedUsers.size();  i++) {
16945            UserStartedState uss = mStartedUsers.valueAt(i);
16946            if (uss.mState != UserStartedState.STATE_STOPPING
16947                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16948                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16949                num++;
16950            }
16951        }
16952    }
16953
16954    @Override
16955    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16956        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16957                != PackageManager.PERMISSION_GRANTED) {
16958            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16959                    + Binder.getCallingPid()
16960                    + ", uid=" + Binder.getCallingUid()
16961                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16962            Slog.w(TAG, msg);
16963            throw new SecurityException(msg);
16964        }
16965
16966        mUserSwitchObservers.register(observer);
16967    }
16968
16969    @Override
16970    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16971        mUserSwitchObservers.unregister(observer);
16972    }
16973
16974    private boolean userExists(int userId) {
16975        if (userId == 0) {
16976            return true;
16977        }
16978        UserManagerService ums = getUserManagerLocked();
16979        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16980    }
16981
16982    int[] getUsersLocked() {
16983        UserManagerService ums = getUserManagerLocked();
16984        return ums != null ? ums.getUserIds() : new int[] { 0 };
16985    }
16986
16987    UserManagerService getUserManagerLocked() {
16988        if (mUserManager == null) {
16989            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16990            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16991        }
16992        return mUserManager;
16993    }
16994
16995    private int applyUserId(int uid, int userId) {
16996        return UserHandle.getUid(userId, uid);
16997    }
16998
16999    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17000        if (info == null) return null;
17001        ApplicationInfo newInfo = new ApplicationInfo(info);
17002        newInfo.uid = applyUserId(info.uid, userId);
17003        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17004                + info.packageName;
17005        return newInfo;
17006    }
17007
17008    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17009        if (aInfo == null
17010                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17011            return aInfo;
17012        }
17013
17014        ActivityInfo info = new ActivityInfo(aInfo);
17015        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17016        return info;
17017    }
17018
17019    private final class LocalService extends ActivityManagerInternal {
17020        @Override
17021        public void goingToSleep() {
17022            ActivityManagerService.this.goingToSleep();
17023        }
17024
17025        @Override
17026        public void wakingUp() {
17027            ActivityManagerService.this.wakingUp();
17028        }
17029    }
17030}
17031