ActivityManagerService.java revision 50cdf7c3069eb2cf82acbad73c322b7a5f3af4b1
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;
20
21import com.android.internal.R;
22import com.android.internal.os.BatteryStatsImpl;
23import com.android.internal.os.ProcessStats;
24import com.android.server.AttributeCache;
25import com.android.server.IntentResolver;
26import com.android.server.ProcessMap;
27import com.android.server.SystemServer;
28import com.android.server.Watchdog;
29import com.android.server.am.ActivityStack.ActivityState;
30import com.android.server.pm.UserManagerService;
31import com.android.server.wm.WindowManagerService;
32
33import dalvik.system.Zygote;
34
35import android.app.Activity;
36import android.app.ActivityManager;
37import android.app.ActivityManagerNative;
38import android.app.ActivityOptions;
39import android.app.ActivityThread;
40import android.app.AlertDialog;
41import android.app.AppGlobals;
42import android.app.ApplicationErrorReport;
43import android.app.Dialog;
44import android.app.IActivityController;
45import android.app.IApplicationThread;
46import android.app.IInstrumentationWatcher;
47import android.app.INotificationManager;
48import android.app.IProcessObserver;
49import android.app.IServiceConnection;
50import android.app.IStopUserCallback;
51import android.app.IThumbnailReceiver;
52import android.app.IUserSwitchObserver;
53import android.app.Instrumentation;
54import android.app.Notification;
55import android.app.NotificationManager;
56import android.app.PendingIntent;
57import android.app.backup.IBackupManager;
58import android.content.ActivityNotFoundException;
59import android.content.BroadcastReceiver;
60import android.content.ClipData;
61import android.content.ComponentCallbacks2;
62import android.content.ComponentName;
63import android.content.ContentProvider;
64import android.content.ContentResolver;
65import android.content.Context;
66import android.content.DialogInterface;
67import android.content.IContentProvider;
68import android.content.IIntentReceiver;
69import android.content.IIntentSender;
70import android.content.Intent;
71import android.content.IntentFilter;
72import android.content.IntentSender;
73import android.content.pm.ActivityInfo;
74import android.content.pm.ApplicationInfo;
75import android.content.pm.ConfigurationInfo;
76import android.content.pm.IPackageDataObserver;
77import android.content.pm.IPackageManager;
78import android.content.pm.InstrumentationInfo;
79import android.content.pm.PackageInfo;
80import android.content.pm.PackageManager;
81import android.content.pm.UserInfo;
82import android.content.pm.PackageManager.NameNotFoundException;
83import android.content.pm.PathPermission;
84import android.content.pm.ProviderInfo;
85import android.content.pm.ResolveInfo;
86import android.content.pm.ServiceInfo;
87import android.content.res.CompatibilityInfo;
88import android.content.res.Configuration;
89import android.graphics.Bitmap;
90import android.net.Proxy;
91import android.net.ProxyProperties;
92import android.net.Uri;
93import android.os.Binder;
94import android.os.Build;
95import android.os.Bundle;
96import android.os.Debug;
97import android.os.DropBoxManager;
98import android.os.Environment;
99import android.os.FileObserver;
100import android.os.FileUtils;
101import android.os.Handler;
102import android.os.IBinder;
103import android.os.IPermissionController;
104import android.os.IRemoteCallback;
105import android.os.IUserManager;
106import android.os.Looper;
107import android.os.Message;
108import android.os.Parcel;
109import android.os.ParcelFileDescriptor;
110import android.os.Process;
111import android.os.RemoteCallbackList;
112import android.os.RemoteException;
113import android.os.SELinux;
114import android.os.ServiceManager;
115import android.os.StrictMode;
116import android.os.SystemClock;
117import android.os.SystemProperties;
118import android.os.UserHandle;
119import android.provider.Settings;
120import android.text.format.Time;
121import android.util.EventLog;
122import android.util.Log;
123import android.util.Pair;
124import android.util.PrintWriterPrinter;
125import android.util.Slog;
126import android.util.SparseArray;
127import android.util.TimeUtils;
128import android.view.Gravity;
129import android.view.LayoutInflater;
130import android.view.View;
131import android.view.WindowManager;
132import android.view.WindowManagerPolicy;
133
134import java.io.BufferedInputStream;
135import java.io.BufferedOutputStream;
136import java.io.BufferedReader;
137import java.io.DataInputStream;
138import java.io.DataOutputStream;
139import java.io.File;
140import java.io.FileDescriptor;
141import java.io.FileInputStream;
142import java.io.FileNotFoundException;
143import java.io.FileOutputStream;
144import java.io.IOException;
145import java.io.InputStreamReader;
146import java.io.PrintWriter;
147import java.io.StringWriter;
148import java.lang.ref.WeakReference;
149import java.util.ArrayList;
150import java.util.Arrays;
151import java.util.Collections;
152import java.util.Comparator;
153import java.util.HashMap;
154import java.util.HashSet;
155import java.util.Iterator;
156import java.util.List;
157import java.util.Locale;
158import java.util.Map;
159import java.util.Set;
160import java.util.concurrent.atomic.AtomicBoolean;
161import java.util.concurrent.atomic.AtomicLong;
162
163public final class ActivityManagerService extends ActivityManagerNative
164        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
165    private static final String USER_DATA_DIR = "/data/user/";
166    static final String TAG = "ActivityManager";
167    static final String TAG_MU = "ActivityManagerServiceMU";
168    static final boolean DEBUG = false;
169    static final boolean localLOGV = DEBUG;
170    static final boolean DEBUG_SWITCH = localLOGV || false;
171    static final boolean DEBUG_TASKS = localLOGV || false;
172    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
173    static final boolean DEBUG_PAUSE = localLOGV || false;
174    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
175    static final boolean DEBUG_TRANSITION = localLOGV || false;
176    static final boolean DEBUG_BROADCAST = localLOGV || false;
177    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
178    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
179    static final boolean DEBUG_SERVICE = localLOGV || false;
180    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
181    static final boolean DEBUG_VISBILITY = localLOGV || false;
182    static final boolean DEBUG_PROCESSES = localLOGV || false;
183    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
184    static final boolean DEBUG_PROVIDER = localLOGV || false;
185    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
186    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
187    static final boolean DEBUG_RESULTS = localLOGV || false;
188    static final boolean DEBUG_BACKUP = localLOGV || false;
189    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
190    static final boolean DEBUG_POWER = localLOGV || false;
191    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
192    static final boolean DEBUG_MU = localLOGV || false;
193    static final boolean VALIDATE_TOKENS = false;
194    static final boolean SHOW_ACTIVITY_START_TIME = true;
195
196    // Control over CPU and battery monitoring.
197    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
198    static final boolean MONITOR_CPU_USAGE = true;
199    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
200    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
201    static final boolean MONITOR_THREAD_CPU_USAGE = false;
202
203    // The flags that are set for all calls we make to the package manager.
204    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
205
206    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
207
208    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
209
210    // Maximum number of recent tasks that we can remember.
211    static final int MAX_RECENT_TASKS = 20;
212
213    // Amount of time after a call to stopAppSwitches() during which we will
214    // prevent further untrusted switches from happening.
215    static final long APP_SWITCH_DELAY_TIME = 5*1000;
216
217    // How long we wait for a launched process to attach to the activity manager
218    // before we decide it's never going to come up for real.
219    static final int PROC_START_TIMEOUT = 10*1000;
220
221    // How long we wait for a launched process to attach to the activity manager
222    // before we decide it's never going to come up for real, when the process was
223    // started with a wrapper for instrumentation (such as Valgrind) because it
224    // could take much longer than usual.
225    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
226
227    // How long to wait after going idle before forcing apps to GC.
228    static final int GC_TIMEOUT = 5*1000;
229
230    // The minimum amount of time between successive GC requests for a process.
231    static final int GC_MIN_INTERVAL = 60*1000;
232
233    // The rate at which we check for apps using excessive power -- 15 mins.
234    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
235
236    // The minimum sample duration we will allow before deciding we have
237    // enough data on wake locks to start killing things.
238    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
239
240    // The minimum sample duration we will allow before deciding we have
241    // enough data on CPU usage to start killing things.
242    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
243
244    // How long we allow a receiver to run before giving up on it.
245    static final int BROADCAST_FG_TIMEOUT = 10*1000;
246    static final int BROADCAST_BG_TIMEOUT = 60*1000;
247
248    // How long we wait until we timeout on key dispatching.
249    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
250
251    // How long we wait until we timeout on key dispatching during instrumentation.
252    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
253
254    // Amount of time we wait for observers to handle a user switch before
255    // giving up on them and unfreezing the screen.
256    static final int USER_SWITCH_TIMEOUT = 2*1000;
257
258    // Maximum number of users we allow to be running at a time.
259    static final int MAX_RUNNING_USERS = 3;
260
261    static final int MY_PID = Process.myPid();
262
263    static final String[] EMPTY_STRING_ARRAY = new String[0];
264
265    public ActivityStack mMainStack;
266
267    private final boolean mHeadless;
268
269    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
270    // default actuion automatically.  Important for devices without direct input
271    // devices.
272    private boolean mShowDialogs = true;
273
274    /**
275     * Description of a request to start a new activity, which has been held
276     * due to app switches being disabled.
277     */
278    static class PendingActivityLaunch {
279        ActivityRecord r;
280        ActivityRecord sourceRecord;
281        int startFlags;
282    }
283
284    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
285            = new ArrayList<PendingActivityLaunch>();
286
287
288    BroadcastQueue mFgBroadcastQueue;
289    BroadcastQueue mBgBroadcastQueue;
290    // Convenient for easy iteration over the queues. Foreground is first
291    // so that dispatch of foreground broadcasts gets precedence.
292    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
293
294    BroadcastQueue broadcastQueueForIntent(Intent intent) {
295        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
296        if (DEBUG_BACKGROUND_BROADCAST) {
297            Slog.i(TAG, "Broadcast intent " + intent + " on "
298                    + (isFg ? "foreground" : "background")
299                    + " queue");
300        }
301        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
302    }
303
304    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
305        for (BroadcastQueue queue : mBroadcastQueues) {
306            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
307            if (r != null) {
308                return r;
309            }
310        }
311        return null;
312    }
313
314    /**
315     * Activity we have told the window manager to have key focus.
316     */
317    ActivityRecord mFocusedActivity = null;
318    /**
319     * List of intents that were used to start the most recent tasks.
320     */
321    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
322
323    /**
324     * Process management.
325     */
326    final ProcessList mProcessList = new ProcessList();
327
328    /**
329     * All of the applications we currently have running organized by name.
330     * The keys are strings of the application package name (as
331     * returned by the package manager), and the keys are ApplicationRecord
332     * objects.
333     */
334    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
335
336    /**
337     * The currently running isolated processes.
338     */
339    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
340
341    /**
342     * Counter for assigning isolated process uids, to avoid frequently reusing the
343     * same ones.
344     */
345    int mNextIsolatedProcessUid = 0;
346
347    /**
348     * The currently running heavy-weight process, if any.
349     */
350    ProcessRecord mHeavyWeightProcess = null;
351
352    /**
353     * The last time that various processes have crashed.
354     */
355    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
356
357    /**
358     * Set of applications that we consider to be bad, and will reject
359     * incoming broadcasts from (which the user has no control over).
360     * Processes are added to this set when they have crashed twice within
361     * a minimum amount of time; they are removed from it when they are
362     * later restarted (hopefully due to some user action).  The value is the
363     * time it was added to the list.
364     */
365    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
366
367    /**
368     * All of the processes we currently have running organized by pid.
369     * The keys are the pid running the application.
370     *
371     * <p>NOTE: This object is protected by its own lock, NOT the global
372     * activity manager lock!
373     */
374    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
375
376    /**
377     * All of the processes that have been forced to be foreground.  The key
378     * is the pid of the caller who requested it (we hold a death
379     * link on it).
380     */
381    abstract class ForegroundToken implements IBinder.DeathRecipient {
382        int pid;
383        IBinder token;
384    }
385    final SparseArray<ForegroundToken> mForegroundProcesses
386            = new SparseArray<ForegroundToken>();
387
388    /**
389     * List of records for processes that someone had tried to start before the
390     * system was ready.  We don't start them at that point, but ensure they
391     * are started by the time booting is complete.
392     */
393    final ArrayList<ProcessRecord> mProcessesOnHold
394            = new ArrayList<ProcessRecord>();
395
396    /**
397     * List of persistent applications that are in the process
398     * of being started.
399     */
400    final ArrayList<ProcessRecord> mPersistentStartingProcesses
401            = new ArrayList<ProcessRecord>();
402
403    /**
404     * Processes that are being forcibly torn down.
405     */
406    final ArrayList<ProcessRecord> mRemovedProcesses
407            = new ArrayList<ProcessRecord>();
408
409    /**
410     * List of running applications, sorted by recent usage.
411     * The first entry in the list is the least recently used.
412     * It contains ApplicationRecord objects.  This list does NOT include
413     * any persistent application records (since we never want to exit them).
414     */
415    final ArrayList<ProcessRecord> mLruProcesses
416            = new ArrayList<ProcessRecord>();
417
418    /**
419     * List of processes that should gc as soon as things are idle.
420     */
421    final ArrayList<ProcessRecord> mProcessesToGc
422            = new ArrayList<ProcessRecord>();
423
424    /**
425     * This is the process holding what we currently consider to be
426     * the "home" activity.
427     */
428    ProcessRecord mHomeProcess;
429
430    /**
431     * This is the process holding the activity the user last visited that
432     * is in a different process from the one they are currently in.
433     */
434    ProcessRecord mPreviousProcess;
435
436    /**
437     * The time at which the previous process was last visible.
438     */
439    long mPreviousProcessVisibleTime;
440
441    /**
442     * Which uses have been started, so are allowed to run code.
443     */
444    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
445
446    /**
447     * LRU list of history of current users.  Most recently current is at the end.
448     */
449    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
450
451    /**
452     * Constant array of the users that are currently started.
453     */
454    int[] mStartedUserArray = new int[] { 0 };
455
456    /**
457     * Registered observers of the user switching mechanics.
458     */
459    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
460            = new RemoteCallbackList<IUserSwitchObserver>();
461
462    /**
463     * Currently active user switch.
464     */
465    Object mCurUserSwitchCallback;
466
467    /**
468     * Packages that the user has asked to have run in screen size
469     * compatibility mode instead of filling the screen.
470     */
471    final CompatModePackages mCompatModePackages;
472
473    /**
474     * Set of PendingResultRecord objects that are currently active.
475     */
476    final HashSet mPendingResultRecords = new HashSet();
477
478    /**
479     * Set of IntentSenderRecord objects that are currently active.
480     */
481    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
482            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
483
484    /**
485     * Fingerprints (hashCode()) of stack traces that we've
486     * already logged DropBox entries for.  Guarded by itself.  If
487     * something (rogue user app) forces this over
488     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
489     */
490    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
491    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
492
493    /**
494     * Strict Mode background batched logging state.
495     *
496     * The string buffer is guarded by itself, and its lock is also
497     * used to determine if another batched write is already
498     * in-flight.
499     */
500    private final StringBuilder mStrictModeBuffer = new StringBuilder();
501
502    /**
503     * Keeps track of all IIntentReceivers that have been registered for
504     * broadcasts.  Hash keys are the receiver IBinder, hash value is
505     * a ReceiverList.
506     */
507    final HashMap mRegisteredReceivers = new HashMap();
508
509    /**
510     * Resolver for broadcast intents to registered receivers.
511     * Holds BroadcastFilter (subclass of IntentFilter).
512     */
513    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
514            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
515        @Override
516        protected boolean allowFilterResult(
517                BroadcastFilter filter, List<BroadcastFilter> dest) {
518            IBinder target = filter.receiverList.receiver.asBinder();
519            for (int i=dest.size()-1; i>=0; i--) {
520                if (dest.get(i).receiverList.receiver.asBinder() == target) {
521                    return false;
522                }
523            }
524            return true;
525        }
526
527        @Override
528        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
529            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
530                    || userId == filter.owningUserId) {
531                return super.newResult(filter, match, userId);
532            }
533            return null;
534        }
535
536        @Override
537        protected BroadcastFilter[] newArray(int size) {
538            return new BroadcastFilter[size];
539        }
540
541        @Override
542        protected String packageForFilter(BroadcastFilter filter) {
543            return filter.packageName;
544        }
545    };
546
547    /**
548     * State of all active sticky broadcasts per user.  Keys are the action of the
549     * sticky Intent, values are an ArrayList of all broadcasted intents with
550     * that action (which should usually be one).  The SparseArray is keyed
551     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
552     * for stickies that are sent to all users.
553     */
554    final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
555            new SparseArray<HashMap<String, ArrayList<Intent>>>();
556
557    final ActiveServices mServices;
558
559    /**
560     * Backup/restore process management
561     */
562    String mBackupAppName = null;
563    BackupRecord mBackupTarget = null;
564
565    /**
566     * List of PendingThumbnailsRecord objects of clients who are still
567     * waiting to receive all of the thumbnails for a task.
568     */
569    final ArrayList mPendingThumbnails = new ArrayList();
570
571    /**
572     * List of HistoryRecord objects that have been finished and must
573     * still report back to a pending thumbnail receiver.
574     */
575    final ArrayList mCancelledThumbnails = new ArrayList();
576
577    final ProviderMap mProviderMap;
578
579    /**
580     * List of content providers who have clients waiting for them.  The
581     * application is currently being launched and the provider will be
582     * removed from this list once it is published.
583     */
584    final ArrayList<ContentProviderRecord> mLaunchingProviders
585            = new ArrayList<ContentProviderRecord>();
586
587    /**
588     * Global set of specific Uri permissions that have been granted.
589     */
590    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
591            = new SparseArray<HashMap<Uri, UriPermission>>();
592
593    CoreSettingsObserver mCoreSettingsObserver;
594
595    /**
596     * Thread-local storage used to carry caller permissions over through
597     * indirect content-provider access.
598     * @see #ActivityManagerService.openContentUri()
599     */
600    private class Identity {
601        public int pid;
602        public int uid;
603
604        Identity(int _pid, int _uid) {
605            pid = _pid;
606            uid = _uid;
607        }
608    }
609
610    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
611
612    /**
613     * All information we have collected about the runtime performance of
614     * any user id that can impact battery performance.
615     */
616    final BatteryStatsService mBatteryStatsService;
617
618    /**
619     * information about component usage
620     */
621    final UsageStatsService mUsageStatsService;
622
623    /**
624     * Current configuration information.  HistoryRecord objects are given
625     * a reference to this object to indicate which configuration they are
626     * currently running in, so this object must be kept immutable.
627     */
628    Configuration mConfiguration = new Configuration();
629
630    /**
631     * Current sequencing integer of the configuration, for skipping old
632     * configurations.
633     */
634    int mConfigurationSeq = 0;
635
636    /**
637     * Hardware-reported OpenGLES version.
638     */
639    final int GL_ES_VERSION;
640
641    /**
642     * List of initialization arguments to pass to all processes when binding applications to them.
643     * For example, references to the commonly used services.
644     */
645    HashMap<String, IBinder> mAppBindArgs;
646
647    /**
648     * Temporary to avoid allocations.  Protected by main lock.
649     */
650    final StringBuilder mStringBuilder = new StringBuilder(256);
651
652    /**
653     * Used to control how we initialize the service.
654     */
655    boolean mStartRunning = false;
656    ComponentName mTopComponent;
657    String mTopAction;
658    String mTopData;
659    boolean mProcessesReady = false;
660    boolean mSystemReady = false;
661    boolean mBooting = false;
662    boolean mWaitingUpdate = false;
663    boolean mDidUpdate = false;
664    boolean mOnBattery = false;
665    boolean mLaunchWarningShown = false;
666
667    Context mContext;
668
669    int mFactoryTest;
670
671    boolean mCheckedForSetup;
672
673    /**
674     * The time at which we will allow normal application switches again,
675     * after a call to {@link #stopAppSwitches()}.
676     */
677    long mAppSwitchesAllowedTime;
678
679    /**
680     * This is set to true after the first switch after mAppSwitchesAllowedTime
681     * is set; any switches after that will clear the time.
682     */
683    boolean mDidAppSwitch;
684
685    /**
686     * Last time (in realtime) at which we checked for power usage.
687     */
688    long mLastPowerCheckRealtime;
689
690    /**
691     * Last time (in uptime) at which we checked for power usage.
692     */
693    long mLastPowerCheckUptime;
694
695    /**
696     * Set while we are wanting to sleep, to prevent any
697     * activities from being started/resumed.
698     */
699    boolean mSleeping = false;
700
701    /**
702     * State of external calls telling us if the device is asleep.
703     */
704    boolean mWentToSleep = false;
705
706    /**
707     * State of external call telling us if the lock screen is shown.
708     */
709    boolean mLockScreenShown = false;
710
711    /**
712     * Set if we are shutting down the system, similar to sleeping.
713     */
714    boolean mShuttingDown = false;
715
716    /**
717     * Task identifier that activities are currently being started
718     * in.  Incremented each time a new task is created.
719     * todo: Replace this with a TokenSpace class that generates non-repeating
720     * integers that won't wrap.
721     */
722    int mCurTask = 1;
723
724    /**
725     * Current sequence id for oom_adj computation traversal.
726     */
727    int mAdjSeq = 0;
728
729    /**
730     * Current sequence id for process LRU updating.
731     */
732    int mLruSeq = 0;
733
734    /**
735     * Keep track of the non-hidden/empty process we last found, to help
736     * determine how to distribute hidden/empty processes next time.
737     */
738    int mNumNonHiddenProcs = 0;
739
740    /**
741     * Keep track of the number of hidden procs, to balance oom adj
742     * distribution between those and empty procs.
743     */
744    int mNumHiddenProcs = 0;
745
746    /**
747     * Keep track of the number of service processes we last found, to
748     * determine on the next iteration which should be B services.
749     */
750    int mNumServiceProcs = 0;
751    int mNewNumServiceProcs = 0;
752
753    /**
754     * System monitoring: number of processes that died since the last
755     * N procs were started.
756     */
757    int[] mProcDeaths = new int[20];
758
759    /**
760     * This is set if we had to do a delayed dexopt of an app before launching
761     * it, to increasing the ANR timeouts in that case.
762     */
763    boolean mDidDexOpt;
764
765    String mDebugApp = null;
766    boolean mWaitForDebugger = false;
767    boolean mDebugTransient = false;
768    String mOrigDebugApp = null;
769    boolean mOrigWaitForDebugger = false;
770    boolean mAlwaysFinishActivities = false;
771    IActivityController mController = null;
772    String mProfileApp = null;
773    ProcessRecord mProfileProc = null;
774    String mProfileFile;
775    ParcelFileDescriptor mProfileFd;
776    int mProfileType = 0;
777    boolean mAutoStopProfiler = false;
778    String mOpenGlTraceApp = null;
779
780    static class ProcessChangeItem {
781        static final int CHANGE_ACTIVITIES = 1<<0;
782        static final int CHANGE_IMPORTANCE= 1<<1;
783        int changes;
784        int uid;
785        int pid;
786        int importance;
787        boolean foregroundActivities;
788    }
789
790    final RemoteCallbackList<IProcessObserver> mProcessObservers
791            = new RemoteCallbackList<IProcessObserver>();
792    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
793
794    final ArrayList<ProcessChangeItem> mPendingProcessChanges
795            = new ArrayList<ProcessChangeItem>();
796    final ArrayList<ProcessChangeItem> mAvailProcessChanges
797            = new ArrayList<ProcessChangeItem>();
798
799    /**
800     * Callback of last caller to {@link #requestPss}.
801     */
802    Runnable mRequestPssCallback;
803
804    /**
805     * Remaining processes for which we are waiting results from the last
806     * call to {@link #requestPss}.
807     */
808    final ArrayList<ProcessRecord> mRequestPssList
809            = new ArrayList<ProcessRecord>();
810
811    /**
812     * Runtime statistics collection thread.  This object's lock is used to
813     * protect all related state.
814     */
815    final Thread mProcessStatsThread;
816
817    /**
818     * Used to collect process stats when showing not responding dialog.
819     * Protected by mProcessStatsThread.
820     */
821    final ProcessStats mProcessStats = new ProcessStats(
822            MONITOR_THREAD_CPU_USAGE);
823    final AtomicLong mLastCpuTime = new AtomicLong(0);
824    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
825
826    long mLastWriteTime = 0;
827
828    /**
829     * Set to true after the system has finished booting.
830     */
831    boolean mBooted = false;
832
833    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
834    int mProcessLimitOverride = -1;
835
836    WindowManagerService mWindowManager;
837
838    static ActivityManagerService mSelf;
839    static ActivityThread mSystemThread;
840
841    private int mCurrentUserId = 0;
842    private int[] mCurrentUserArray = new int[] { 0 };
843    private UserManagerService mUserManager;
844
845    private final class AppDeathRecipient implements IBinder.DeathRecipient {
846        final ProcessRecord mApp;
847        final int mPid;
848        final IApplicationThread mAppThread;
849
850        AppDeathRecipient(ProcessRecord app, int pid,
851                IApplicationThread thread) {
852            if (localLOGV) Slog.v(
853                TAG, "New death recipient " + this
854                + " for thread " + thread.asBinder());
855            mApp = app;
856            mPid = pid;
857            mAppThread = thread;
858        }
859
860        public void binderDied() {
861            if (localLOGV) Slog.v(
862                TAG, "Death received in " + this
863                + " for thread " + mAppThread.asBinder());
864            synchronized(ActivityManagerService.this) {
865                appDiedLocked(mApp, mPid, mAppThread);
866            }
867        }
868    }
869
870    static final int SHOW_ERROR_MSG = 1;
871    static final int SHOW_NOT_RESPONDING_MSG = 2;
872    static final int SHOW_FACTORY_ERROR_MSG = 3;
873    static final int UPDATE_CONFIGURATION_MSG = 4;
874    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
875    static final int WAIT_FOR_DEBUGGER_MSG = 6;
876    static final int SERVICE_TIMEOUT_MSG = 12;
877    static final int UPDATE_TIME_ZONE = 13;
878    static final int SHOW_UID_ERROR_MSG = 14;
879    static final int IM_FEELING_LUCKY_MSG = 15;
880    static final int PROC_START_TIMEOUT_MSG = 20;
881    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
882    static final int KILL_APPLICATION_MSG = 22;
883    static final int FINALIZE_PENDING_INTENT_MSG = 23;
884    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
885    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
886    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
887    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
888    static final int CLEAR_DNS_CACHE = 28;
889    static final int UPDATE_HTTP_PROXY = 29;
890    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
891    static final int DISPATCH_PROCESSES_CHANGED = 31;
892    static final int DISPATCH_PROCESS_DIED = 32;
893    static final int REPORT_MEM_USAGE = 33;
894    static final int REPORT_USER_SWITCH_MSG = 34;
895    static final int CONTINUE_USER_SWITCH_MSG = 35;
896    static final int USER_SWITCH_TIMEOUT_MSG = 36;
897
898    static final int FIRST_ACTIVITY_STACK_MSG = 100;
899    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
900    static final int FIRST_COMPAT_MODE_MSG = 300;
901
902    AlertDialog mUidAlert;
903    CompatModeDialog mCompatModeDialog;
904    long mLastMemUsageReportTime = 0;
905
906    final Handler mHandler = new Handler() {
907        //public Handler() {
908        //    if (localLOGV) Slog.v(TAG, "Handler started!");
909        //}
910
911        public void handleMessage(Message msg) {
912            switch (msg.what) {
913            case SHOW_ERROR_MSG: {
914                HashMap data = (HashMap) msg.obj;
915                synchronized (ActivityManagerService.this) {
916                    ProcessRecord proc = (ProcessRecord)data.get("app");
917                    if (proc != null && proc.crashDialog != null) {
918                        Slog.e(TAG, "App already has crash dialog: " + proc);
919                        return;
920                    }
921                    AppErrorResult res = (AppErrorResult) data.get("result");
922                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
923                        Dialog d = new AppErrorDialog(mContext, res, proc);
924                        d.show();
925                        proc.crashDialog = d;
926                    } else {
927                        // The device is asleep, so just pretend that the user
928                        // saw a crash dialog and hit "force quit".
929                        res.set(0);
930                    }
931                }
932
933                ensureBootCompleted();
934            } break;
935            case SHOW_NOT_RESPONDING_MSG: {
936                synchronized (ActivityManagerService.this) {
937                    HashMap data = (HashMap) msg.obj;
938                    ProcessRecord proc = (ProcessRecord)data.get("app");
939                    if (proc != null && proc.anrDialog != null) {
940                        Slog.e(TAG, "App already has anr dialog: " + proc);
941                        return;
942                    }
943
944                    Intent intent = new Intent("android.intent.action.ANR");
945                    if (!mProcessesReady) {
946                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
947                                | Intent.FLAG_RECEIVER_FOREGROUND);
948                    }
949                    broadcastIntentLocked(null, null, intent,
950                            null, null, 0, null, null, null,
951                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
952
953                    if (mShowDialogs) {
954                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
955                                mContext, proc, (ActivityRecord)data.get("activity"));
956                        d.show();
957                        proc.anrDialog = d;
958                    } else {
959                        // Just kill the app if there is no dialog to be shown.
960                        killAppAtUsersRequest(proc, null);
961                    }
962                }
963
964                ensureBootCompleted();
965            } break;
966            case SHOW_STRICT_MODE_VIOLATION_MSG: {
967                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
968                synchronized (ActivityManagerService.this) {
969                    ProcessRecord proc = (ProcessRecord) data.get("app");
970                    if (proc == null) {
971                        Slog.e(TAG, "App not found when showing strict mode dialog.");
972                        break;
973                    }
974                    if (proc.crashDialog != null) {
975                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
976                        return;
977                    }
978                    AppErrorResult res = (AppErrorResult) data.get("result");
979                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
980                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
981                        d.show();
982                        proc.crashDialog = d;
983                    } else {
984                        // The device is asleep, so just pretend that the user
985                        // saw a crash dialog and hit "force quit".
986                        res.set(0);
987                    }
988                }
989                ensureBootCompleted();
990            } break;
991            case SHOW_FACTORY_ERROR_MSG: {
992                Dialog d = new FactoryErrorDialog(
993                    mContext, msg.getData().getCharSequence("msg"));
994                d.show();
995                ensureBootCompleted();
996            } break;
997            case UPDATE_CONFIGURATION_MSG: {
998                final ContentResolver resolver = mContext.getContentResolver();
999                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1000            } break;
1001            case GC_BACKGROUND_PROCESSES_MSG: {
1002                synchronized (ActivityManagerService.this) {
1003                    performAppGcsIfAppropriateLocked();
1004                }
1005            } break;
1006            case WAIT_FOR_DEBUGGER_MSG: {
1007                synchronized (ActivityManagerService.this) {
1008                    ProcessRecord app = (ProcessRecord)msg.obj;
1009                    if (msg.arg1 != 0) {
1010                        if (!app.waitedForDebugger) {
1011                            Dialog d = new AppWaitingForDebuggerDialog(
1012                                    ActivityManagerService.this,
1013                                    mContext, app);
1014                            app.waitDialog = d;
1015                            app.waitedForDebugger = true;
1016                            d.show();
1017                        }
1018                    } else {
1019                        if (app.waitDialog != null) {
1020                            app.waitDialog.dismiss();
1021                            app.waitDialog = null;
1022                        }
1023                    }
1024                }
1025            } break;
1026            case SERVICE_TIMEOUT_MSG: {
1027                if (mDidDexOpt) {
1028                    mDidDexOpt = false;
1029                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1030                    nmsg.obj = msg.obj;
1031                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1032                    return;
1033                }
1034                mServices.serviceTimeout((ProcessRecord)msg.obj);
1035            } break;
1036            case UPDATE_TIME_ZONE: {
1037                synchronized (ActivityManagerService.this) {
1038                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1039                        ProcessRecord r = mLruProcesses.get(i);
1040                        if (r.thread != null) {
1041                            try {
1042                                r.thread.updateTimeZone();
1043                            } catch (RemoteException ex) {
1044                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1045                            }
1046                        }
1047                    }
1048                }
1049            } break;
1050            case CLEAR_DNS_CACHE: {
1051                synchronized (ActivityManagerService.this) {
1052                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1053                        ProcessRecord r = mLruProcesses.get(i);
1054                        if (r.thread != null) {
1055                            try {
1056                                r.thread.clearDnsCache();
1057                            } catch (RemoteException ex) {
1058                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1059                            }
1060                        }
1061                    }
1062                }
1063            } break;
1064            case UPDATE_HTTP_PROXY: {
1065                ProxyProperties proxy = (ProxyProperties)msg.obj;
1066                String host = "";
1067                String port = "";
1068                String exclList = "";
1069                if (proxy != null) {
1070                    host = proxy.getHost();
1071                    port = Integer.toString(proxy.getPort());
1072                    exclList = proxy.getExclusionList();
1073                }
1074                synchronized (ActivityManagerService.this) {
1075                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1076                        ProcessRecord r = mLruProcesses.get(i);
1077                        if (r.thread != null) {
1078                            try {
1079                                r.thread.setHttpProxy(host, port, exclList);
1080                            } catch (RemoteException ex) {
1081                                Slog.w(TAG, "Failed to update http proxy for: " +
1082                                        r.info.processName);
1083                            }
1084                        }
1085                    }
1086                }
1087            } break;
1088            case SHOW_UID_ERROR_MSG: {
1089                String title = "System UIDs Inconsistent";
1090                String text = "UIDs on the system are inconsistent, you need to wipe your"
1091                        + " data partition or your device will be unstable.";
1092                Log.e(TAG, title + ": " + text);
1093                if (mShowDialogs) {
1094                    // XXX This is a temporary dialog, no need to localize.
1095                    AlertDialog d = new BaseErrorDialog(mContext);
1096                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1097                    d.setCancelable(false);
1098                    d.setTitle(title);
1099                    d.setMessage(text);
1100                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1101                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1102                    mUidAlert = d;
1103                    d.show();
1104                }
1105            } break;
1106            case IM_FEELING_LUCKY_MSG: {
1107                if (mUidAlert != null) {
1108                    mUidAlert.dismiss();
1109                    mUidAlert = null;
1110                }
1111            } break;
1112            case PROC_START_TIMEOUT_MSG: {
1113                if (mDidDexOpt) {
1114                    mDidDexOpt = false;
1115                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1116                    nmsg.obj = msg.obj;
1117                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1118                    return;
1119                }
1120                ProcessRecord app = (ProcessRecord)msg.obj;
1121                synchronized (ActivityManagerService.this) {
1122                    processStartTimedOutLocked(app);
1123                }
1124            } break;
1125            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1126                synchronized (ActivityManagerService.this) {
1127                    doPendingActivityLaunchesLocked(true);
1128                }
1129            } break;
1130            case KILL_APPLICATION_MSG: {
1131                synchronized (ActivityManagerService.this) {
1132                    int appid = msg.arg1;
1133                    boolean restart = (msg.arg2 == 1);
1134                    String pkg = (String) msg.obj;
1135                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1136                            UserHandle.USER_ALL);
1137                }
1138            } break;
1139            case FINALIZE_PENDING_INTENT_MSG: {
1140                ((PendingIntentRecord)msg.obj).completeFinalize();
1141            } break;
1142            case POST_HEAVY_NOTIFICATION_MSG: {
1143                INotificationManager inm = NotificationManager.getService();
1144                if (inm == null) {
1145                    return;
1146                }
1147
1148                ActivityRecord root = (ActivityRecord)msg.obj;
1149                ProcessRecord process = root.app;
1150                if (process == null) {
1151                    return;
1152                }
1153
1154                try {
1155                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1156                    String text = mContext.getString(R.string.heavy_weight_notification,
1157                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1158                    Notification notification = new Notification();
1159                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1160                    notification.when = 0;
1161                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1162                    notification.tickerText = text;
1163                    notification.defaults = 0; // please be quiet
1164                    notification.sound = null;
1165                    notification.vibrate = null;
1166                    notification.setLatestEventInfo(context, text,
1167                            mContext.getText(R.string.heavy_weight_notification_detail),
1168                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1169                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1170                                    new UserHandle(root.userId)));
1171
1172                    try {
1173                        int[] outId = new int[1];
1174                        inm.enqueueNotificationWithTag("android", null,
1175                                R.string.heavy_weight_notification,
1176                                notification, outId, root.userId);
1177                    } catch (RuntimeException e) {
1178                        Slog.w(ActivityManagerService.TAG,
1179                                "Error showing notification for heavy-weight app", e);
1180                    } catch (RemoteException e) {
1181                    }
1182                } catch (NameNotFoundException e) {
1183                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1184                }
1185            } break;
1186            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1187                INotificationManager inm = NotificationManager.getService();
1188                if (inm == null) {
1189                    return;
1190                }
1191                try {
1192                    inm.cancelNotificationWithTag("android", null,
1193                            R.string.heavy_weight_notification,  msg.arg1);
1194                } catch (RuntimeException e) {
1195                    Slog.w(ActivityManagerService.TAG,
1196                            "Error canceling notification for service", e);
1197                } catch (RemoteException e) {
1198                }
1199            } break;
1200            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1201                synchronized (ActivityManagerService.this) {
1202                    checkExcessivePowerUsageLocked(true);
1203                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1204                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1205                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1206                }
1207            } break;
1208            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1209                synchronized (ActivityManagerService.this) {
1210                    ActivityRecord ar = (ActivityRecord)msg.obj;
1211                    if (mCompatModeDialog != null) {
1212                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1213                                ar.info.applicationInfo.packageName)) {
1214                            return;
1215                        }
1216                        mCompatModeDialog.dismiss();
1217                        mCompatModeDialog = null;
1218                    }
1219                    if (ar != null && false) {
1220                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1221                                ar.packageName)) {
1222                            int mode = mCompatModePackages.computeCompatModeLocked(
1223                                    ar.info.applicationInfo);
1224                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1225                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1226                                mCompatModeDialog = new CompatModeDialog(
1227                                        ActivityManagerService.this, mContext,
1228                                        ar.info.applicationInfo);
1229                                mCompatModeDialog.show();
1230                            }
1231                        }
1232                    }
1233                }
1234                break;
1235            }
1236            case DISPATCH_PROCESSES_CHANGED: {
1237                dispatchProcessesChanged();
1238                break;
1239            }
1240            case DISPATCH_PROCESS_DIED: {
1241                final int pid = msg.arg1;
1242                final int uid = msg.arg2;
1243                dispatchProcessDied(pid, uid);
1244                break;
1245            }
1246            case REPORT_MEM_USAGE: {
1247                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1248                if (!isDebuggable) {
1249                    return;
1250                }
1251                synchronized (ActivityManagerService.this) {
1252                    long now = SystemClock.uptimeMillis();
1253                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1254                        // Don't report more than every 5 minutes to somewhat
1255                        // avoid spamming.
1256                        return;
1257                    }
1258                    mLastMemUsageReportTime = now;
1259                }
1260                Thread thread = new Thread() {
1261                    @Override public void run() {
1262                        StringBuilder dropBuilder = new StringBuilder(1024);
1263                        StringBuilder logBuilder = new StringBuilder(1024);
1264                        StringWriter oomSw = new StringWriter();
1265                        PrintWriter oomPw = new PrintWriter(oomSw);
1266                        StringWriter catSw = new StringWriter();
1267                        PrintWriter catPw = new PrintWriter(catSw);
1268                        String[] emptyArgs = new String[] { };
1269                        StringBuilder tag = new StringBuilder(128);
1270                        StringBuilder stack = new StringBuilder(128);
1271                        tag.append("Low on memory -- ");
1272                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1273                                tag, stack);
1274                        dropBuilder.append(stack);
1275                        dropBuilder.append('\n');
1276                        dropBuilder.append('\n');
1277                        String oomString = oomSw.toString();
1278                        dropBuilder.append(oomString);
1279                        dropBuilder.append('\n');
1280                        logBuilder.append(oomString);
1281                        try {
1282                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1283                                    "procrank", });
1284                            final InputStreamReader converter = new InputStreamReader(
1285                                    proc.getInputStream());
1286                            BufferedReader in = new BufferedReader(converter);
1287                            String line;
1288                            while (true) {
1289                                line = in.readLine();
1290                                if (line == null) {
1291                                    break;
1292                                }
1293                                if (line.length() > 0) {
1294                                    logBuilder.append(line);
1295                                    logBuilder.append('\n');
1296                                }
1297                                dropBuilder.append(line);
1298                                dropBuilder.append('\n');
1299                            }
1300                            converter.close();
1301                        } catch (IOException e) {
1302                        }
1303                        synchronized (ActivityManagerService.this) {
1304                            catPw.println();
1305                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1306                            catPw.println();
1307                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1308                                    false, false, null);
1309                            catPw.println();
1310                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1311                        }
1312                        dropBuilder.append(catSw.toString());
1313                        addErrorToDropBox("lowmem", null, "system_server", null,
1314                                null, tag.toString(), dropBuilder.toString(), null, null);
1315                        Slog.i(TAG, logBuilder.toString());
1316                        synchronized (ActivityManagerService.this) {
1317                            long now = SystemClock.uptimeMillis();
1318                            if (mLastMemUsageReportTime < now) {
1319                                mLastMemUsageReportTime = now;
1320                            }
1321                        }
1322                    }
1323                };
1324                thread.start();
1325                break;
1326            }
1327            case REPORT_USER_SWITCH_MSG: {
1328                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1329                break;
1330            }
1331            case CONTINUE_USER_SWITCH_MSG: {
1332                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1333                break;
1334            }
1335            case USER_SWITCH_TIMEOUT_MSG: {
1336                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1337                break;
1338            }
1339            }
1340        }
1341    };
1342
1343    public static void setSystemProcess() {
1344        try {
1345            ActivityManagerService m = mSelf;
1346
1347            ServiceManager.addService("activity", m, true);
1348            ServiceManager.addService("meminfo", new MemBinder(m));
1349            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1350            ServiceManager.addService("dbinfo", new DbBinder(m));
1351            if (MONITOR_CPU_USAGE) {
1352                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1353            }
1354            ServiceManager.addService("permission", new PermissionController(m));
1355
1356            ApplicationInfo info =
1357                mSelf.mContext.getPackageManager().getApplicationInfo(
1358                            "android", STOCK_PM_FLAGS);
1359            mSystemThread.installSystemApplicationInfo(info);
1360
1361            synchronized (mSelf) {
1362                ProcessRecord app = mSelf.newProcessRecordLocked(
1363                        mSystemThread.getApplicationThread(), info,
1364                        info.processName, false);
1365                app.persistent = true;
1366                app.pid = MY_PID;
1367                app.maxAdj = ProcessList.SYSTEM_ADJ;
1368                mSelf.mProcessNames.put(app.processName, app.uid, app);
1369                synchronized (mSelf.mPidsSelfLocked) {
1370                    mSelf.mPidsSelfLocked.put(app.pid, app);
1371                }
1372                mSelf.updateLruProcessLocked(app, true, true);
1373            }
1374        } catch (PackageManager.NameNotFoundException e) {
1375            throw new RuntimeException(
1376                    "Unable to find android system package", e);
1377        }
1378    }
1379
1380    public void setWindowManager(WindowManagerService wm) {
1381        mWindowManager = wm;
1382    }
1383
1384    public static final Context main(int factoryTest) {
1385        AThread thr = new AThread();
1386        thr.start();
1387
1388        synchronized (thr) {
1389            while (thr.mService == null) {
1390                try {
1391                    thr.wait();
1392                } catch (InterruptedException e) {
1393                }
1394            }
1395        }
1396
1397        ActivityManagerService m = thr.mService;
1398        mSelf = m;
1399        ActivityThread at = ActivityThread.systemMain();
1400        mSystemThread = at;
1401        Context context = at.getSystemContext();
1402        context.setTheme(android.R.style.Theme_Holo);
1403        m.mContext = context;
1404        m.mFactoryTest = factoryTest;
1405        m.mMainStack = new ActivityStack(m, context, true);
1406
1407        m.mBatteryStatsService.publish(context);
1408        m.mUsageStatsService.publish(context);
1409
1410        synchronized (thr) {
1411            thr.mReady = true;
1412            thr.notifyAll();
1413        }
1414
1415        m.startRunning(null, null, null, null);
1416
1417        return context;
1418    }
1419
1420    public static ActivityManagerService self() {
1421        return mSelf;
1422    }
1423
1424    static class AThread extends Thread {
1425        ActivityManagerService mService;
1426        boolean mReady = false;
1427
1428        public AThread() {
1429            super("ActivityManager");
1430        }
1431
1432        public void run() {
1433            Looper.prepare();
1434
1435            android.os.Process.setThreadPriority(
1436                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1437            android.os.Process.setCanSelfBackground(false);
1438
1439            ActivityManagerService m = new ActivityManagerService();
1440
1441            synchronized (this) {
1442                mService = m;
1443                notifyAll();
1444            }
1445
1446            synchronized (this) {
1447                while (!mReady) {
1448                    try {
1449                        wait();
1450                    } catch (InterruptedException e) {
1451                    }
1452                }
1453            }
1454
1455            // For debug builds, log event loop stalls to dropbox for analysis.
1456            if (StrictMode.conditionallyEnableDebugLogging()) {
1457                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1458            }
1459
1460            Looper.loop();
1461        }
1462    }
1463
1464    static class MemBinder extends Binder {
1465        ActivityManagerService mActivityManagerService;
1466        MemBinder(ActivityManagerService activityManagerService) {
1467            mActivityManagerService = activityManagerService;
1468        }
1469
1470        @Override
1471        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1472            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1473                    != PackageManager.PERMISSION_GRANTED) {
1474                pw.println("Permission Denial: can't dump meminfo from from pid="
1475                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1476                        + " without permission " + android.Manifest.permission.DUMP);
1477                return;
1478            }
1479
1480            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1481                    false, null, null, null);
1482        }
1483    }
1484
1485    static class GraphicsBinder extends Binder {
1486        ActivityManagerService mActivityManagerService;
1487        GraphicsBinder(ActivityManagerService activityManagerService) {
1488            mActivityManagerService = activityManagerService;
1489        }
1490
1491        @Override
1492        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1493            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1494                    != PackageManager.PERMISSION_GRANTED) {
1495                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1496                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1497                        + " without permission " + android.Manifest.permission.DUMP);
1498                return;
1499            }
1500
1501            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1502        }
1503    }
1504
1505    static class DbBinder extends Binder {
1506        ActivityManagerService mActivityManagerService;
1507        DbBinder(ActivityManagerService activityManagerService) {
1508            mActivityManagerService = activityManagerService;
1509        }
1510
1511        @Override
1512        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1513            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1514                    != PackageManager.PERMISSION_GRANTED) {
1515                pw.println("Permission Denial: can't dump dbinfo from from pid="
1516                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1517                        + " without permission " + android.Manifest.permission.DUMP);
1518                return;
1519            }
1520
1521            mActivityManagerService.dumpDbInfo(fd, pw, args);
1522        }
1523    }
1524
1525    static class CpuBinder extends Binder {
1526        ActivityManagerService mActivityManagerService;
1527        CpuBinder(ActivityManagerService activityManagerService) {
1528            mActivityManagerService = activityManagerService;
1529        }
1530
1531        @Override
1532        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1533            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1534                    != PackageManager.PERMISSION_GRANTED) {
1535                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1536                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1537                        + " without permission " + android.Manifest.permission.DUMP);
1538                return;
1539            }
1540
1541            synchronized (mActivityManagerService.mProcessStatsThread) {
1542                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1543                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1544                        SystemClock.uptimeMillis()));
1545            }
1546        }
1547    }
1548
1549    private ActivityManagerService() {
1550        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1551
1552        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1553        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1554        mBroadcastQueues[0] = mFgBroadcastQueue;
1555        mBroadcastQueues[1] = mBgBroadcastQueue;
1556
1557        mServices = new ActiveServices(this);
1558        mProviderMap = new ProviderMap(this);
1559
1560        File dataDir = Environment.getDataDirectory();
1561        File systemDir = new File(dataDir, "system");
1562        systemDir.mkdirs();
1563        mBatteryStatsService = new BatteryStatsService(new File(
1564                systemDir, "batterystats.bin").toString());
1565        mBatteryStatsService.getActiveStatistics().readLocked();
1566        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1567        mOnBattery = DEBUG_POWER ? true
1568                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1569        mBatteryStatsService.getActiveStatistics().setCallback(this);
1570
1571        mUsageStatsService = new UsageStatsService(new File(
1572                systemDir, "usagestats").toString());
1573        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1574
1575        // User 0 is the first and only user that runs at boot.
1576        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1577        mUserLru.add(Integer.valueOf(0));
1578        updateStartedUserArrayLocked();
1579
1580        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1581            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1582
1583        mConfiguration.setToDefaults();
1584        mConfiguration.setLocale(Locale.getDefault());
1585
1586        mConfigurationSeq = mConfiguration.seq = 1;
1587        mProcessStats.init();
1588
1589        mCompatModePackages = new CompatModePackages(this, systemDir);
1590
1591        // Add ourself to the Watchdog monitors.
1592        Watchdog.getInstance().addMonitor(this);
1593
1594        mProcessStatsThread = new Thread("ProcessStats") {
1595            public void run() {
1596                while (true) {
1597                    try {
1598                        try {
1599                            synchronized(this) {
1600                                final long now = SystemClock.uptimeMillis();
1601                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1602                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1603                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1604                                //        + ", write delay=" + nextWriteDelay);
1605                                if (nextWriteDelay < nextCpuDelay) {
1606                                    nextCpuDelay = nextWriteDelay;
1607                                }
1608                                if (nextCpuDelay > 0) {
1609                                    mProcessStatsMutexFree.set(true);
1610                                    this.wait(nextCpuDelay);
1611                                }
1612                            }
1613                        } catch (InterruptedException e) {
1614                        }
1615                        updateCpuStatsNow();
1616                    } catch (Exception e) {
1617                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1618                    }
1619                }
1620            }
1621        };
1622        mProcessStatsThread.start();
1623    }
1624
1625    @Override
1626    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1627            throws RemoteException {
1628        if (code == SYSPROPS_TRANSACTION) {
1629            // We need to tell all apps about the system property change.
1630            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1631            synchronized(this) {
1632                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1633                    final int NA = apps.size();
1634                    for (int ia=0; ia<NA; ia++) {
1635                        ProcessRecord app = apps.valueAt(ia);
1636                        if (app.thread != null) {
1637                            procs.add(app.thread.asBinder());
1638                        }
1639                    }
1640                }
1641            }
1642
1643            int N = procs.size();
1644            for (int i=0; i<N; i++) {
1645                Parcel data2 = Parcel.obtain();
1646                try {
1647                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1648                } catch (RemoteException e) {
1649                }
1650                data2.recycle();
1651            }
1652        }
1653        try {
1654            return super.onTransact(code, data, reply, flags);
1655        } catch (RuntimeException e) {
1656            // The activity manager only throws security exceptions, so let's
1657            // log all others.
1658            if (!(e instanceof SecurityException)) {
1659                Slog.e(TAG, "Activity Manager Crash", e);
1660            }
1661            throw e;
1662        }
1663    }
1664
1665    void updateCpuStats() {
1666        final long now = SystemClock.uptimeMillis();
1667        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1668            return;
1669        }
1670        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1671            synchronized (mProcessStatsThread) {
1672                mProcessStatsThread.notify();
1673            }
1674        }
1675    }
1676
1677    void updateCpuStatsNow() {
1678        synchronized (mProcessStatsThread) {
1679            mProcessStatsMutexFree.set(false);
1680            final long now = SystemClock.uptimeMillis();
1681            boolean haveNewCpuStats = false;
1682
1683            if (MONITOR_CPU_USAGE &&
1684                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1685                mLastCpuTime.set(now);
1686                haveNewCpuStats = true;
1687                mProcessStats.update();
1688                //Slog.i(TAG, mProcessStats.printCurrentState());
1689                //Slog.i(TAG, "Total CPU usage: "
1690                //        + mProcessStats.getTotalCpuPercent() + "%");
1691
1692                // Slog the cpu usage if the property is set.
1693                if ("true".equals(SystemProperties.get("events.cpu"))) {
1694                    int user = mProcessStats.getLastUserTime();
1695                    int system = mProcessStats.getLastSystemTime();
1696                    int iowait = mProcessStats.getLastIoWaitTime();
1697                    int irq = mProcessStats.getLastIrqTime();
1698                    int softIrq = mProcessStats.getLastSoftIrqTime();
1699                    int idle = mProcessStats.getLastIdleTime();
1700
1701                    int total = user + system + iowait + irq + softIrq + idle;
1702                    if (total == 0) total = 1;
1703
1704                    EventLog.writeEvent(EventLogTags.CPU,
1705                            ((user+system+iowait+irq+softIrq) * 100) / total,
1706                            (user * 100) / total,
1707                            (system * 100) / total,
1708                            (iowait * 100) / total,
1709                            (irq * 100) / total,
1710                            (softIrq * 100) / total);
1711                }
1712            }
1713
1714            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1715            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1716            synchronized(bstats) {
1717                synchronized(mPidsSelfLocked) {
1718                    if (haveNewCpuStats) {
1719                        if (mOnBattery) {
1720                            int perc = bstats.startAddingCpuLocked();
1721                            int totalUTime = 0;
1722                            int totalSTime = 0;
1723                            final int N = mProcessStats.countStats();
1724                            for (int i=0; i<N; i++) {
1725                                ProcessStats.Stats st = mProcessStats.getStats(i);
1726                                if (!st.working) {
1727                                    continue;
1728                                }
1729                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1730                                int otherUTime = (st.rel_utime*perc)/100;
1731                                int otherSTime = (st.rel_stime*perc)/100;
1732                                totalUTime += otherUTime;
1733                                totalSTime += otherSTime;
1734                                if (pr != null) {
1735                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1736                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1737                                            st.rel_stime-otherSTime);
1738                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1739                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1740                                } else {
1741                                    BatteryStatsImpl.Uid.Proc ps =
1742                                            bstats.getProcessStatsLocked(st.name, st.pid);
1743                                    if (ps != null) {
1744                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1745                                                st.rel_stime-otherSTime);
1746                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1747                                    }
1748                                }
1749                            }
1750                            bstats.finishAddingCpuLocked(perc, totalUTime,
1751                                    totalSTime, cpuSpeedTimes);
1752                        }
1753                    }
1754                }
1755
1756                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1757                    mLastWriteTime = now;
1758                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1759                }
1760            }
1761        }
1762    }
1763
1764    @Override
1765    public void batteryNeedsCpuUpdate() {
1766        updateCpuStatsNow();
1767    }
1768
1769    @Override
1770    public void batteryPowerChanged(boolean onBattery) {
1771        // When plugging in, update the CPU stats first before changing
1772        // the plug state.
1773        updateCpuStatsNow();
1774        synchronized (this) {
1775            synchronized(mPidsSelfLocked) {
1776                mOnBattery = DEBUG_POWER ? true : onBattery;
1777            }
1778        }
1779    }
1780
1781    /**
1782     * Initialize the application bind args. These are passed to each
1783     * process when the bindApplication() IPC is sent to the process. They're
1784     * lazily setup to make sure the services are running when they're asked for.
1785     */
1786    private HashMap<String, IBinder> getCommonServicesLocked() {
1787        if (mAppBindArgs == null) {
1788            mAppBindArgs = new HashMap<String, IBinder>();
1789
1790            // Setup the application init args
1791            mAppBindArgs.put("package", ServiceManager.getService("package"));
1792            mAppBindArgs.put("window", ServiceManager.getService("window"));
1793            mAppBindArgs.put(Context.ALARM_SERVICE,
1794                    ServiceManager.getService(Context.ALARM_SERVICE));
1795        }
1796        return mAppBindArgs;
1797    }
1798
1799    final void setFocusedActivityLocked(ActivityRecord r) {
1800        if (mFocusedActivity != r) {
1801            mFocusedActivity = r;
1802            if (r != null) {
1803                mWindowManager.setFocusedApp(r.appToken, true);
1804            }
1805        }
1806    }
1807
1808    private final void updateLruProcessInternalLocked(ProcessRecord app,
1809            boolean updateActivityTime, int bestPos) {
1810        // put it on the LRU to keep track of when it should be exited.
1811        int lrui = mLruProcesses.indexOf(app);
1812        if (lrui >= 0) mLruProcesses.remove(lrui);
1813
1814        int i = mLruProcesses.size()-1;
1815        int skipTop = 0;
1816
1817        app.lruSeq = mLruSeq;
1818
1819        // compute the new weight for this process.
1820        if (updateActivityTime) {
1821            app.lastActivityTime = SystemClock.uptimeMillis();
1822        }
1823        if (app.activities.size() > 0) {
1824            // If this process has activities, we more strongly want to keep
1825            // it around.
1826            app.lruWeight = app.lastActivityTime;
1827        } else if (app.pubProviders.size() > 0) {
1828            // If this process contains content providers, we want to keep
1829            // it a little more strongly.
1830            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1831            // Also don't let it kick out the first few "real" hidden processes.
1832            skipTop = ProcessList.MIN_HIDDEN_APPS;
1833        } else {
1834            // If this process doesn't have activities, we less strongly
1835            // want to keep it around, and generally want to avoid getting
1836            // in front of any very recently used activities.
1837            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1838            // Also don't let it kick out the first few "real" hidden processes.
1839            skipTop = ProcessList.MIN_HIDDEN_APPS;
1840        }
1841
1842        while (i >= 0) {
1843            ProcessRecord p = mLruProcesses.get(i);
1844            // If this app shouldn't be in front of the first N background
1845            // apps, then skip over that many that are currently hidden.
1846            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1847                skipTop--;
1848            }
1849            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1850                mLruProcesses.add(i+1, app);
1851                break;
1852            }
1853            i--;
1854        }
1855        if (i < 0) {
1856            mLruProcesses.add(0, app);
1857        }
1858
1859        // If the app is currently using a content provider or service,
1860        // bump those processes as well.
1861        if (app.connections.size() > 0) {
1862            for (ConnectionRecord cr : app.connections) {
1863                if (cr.binding != null && cr.binding.service != null
1864                        && cr.binding.service.app != null
1865                        && cr.binding.service.app.lruSeq != mLruSeq) {
1866                    updateLruProcessInternalLocked(cr.binding.service.app,
1867                            updateActivityTime, i+1);
1868                }
1869            }
1870        }
1871        for (int j=app.conProviders.size()-1; j>=0; j--) {
1872            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1873            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1874                updateLruProcessInternalLocked(cpr.proc,
1875                        updateActivityTime, i+1);
1876            }
1877        }
1878    }
1879
1880    final void updateLruProcessLocked(ProcessRecord app,
1881            boolean oomAdj, boolean updateActivityTime) {
1882        mLruSeq++;
1883        updateLruProcessInternalLocked(app, updateActivityTime, 0);
1884
1885        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1886        if (oomAdj) {
1887            updateOomAdjLocked();
1888        }
1889    }
1890
1891    final ProcessRecord getProcessRecordLocked(
1892            String processName, int uid) {
1893        if (uid == Process.SYSTEM_UID) {
1894            // The system gets to run in any process.  If there are multiple
1895            // processes with the same uid, just pick the first (this
1896            // should never happen).
1897            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1898                    processName);
1899            if (procs == null) return null;
1900            final int N = procs.size();
1901            for (int i = 0; i < N; i++) {
1902                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1903            }
1904        }
1905        ProcessRecord proc = mProcessNames.get(processName, uid);
1906        return proc;
1907    }
1908
1909    void ensurePackageDexOpt(String packageName) {
1910        IPackageManager pm = AppGlobals.getPackageManager();
1911        try {
1912            if (pm.performDexOpt(packageName)) {
1913                mDidDexOpt = true;
1914            }
1915        } catch (RemoteException e) {
1916        }
1917    }
1918
1919    boolean isNextTransitionForward() {
1920        int transit = mWindowManager.getPendingAppTransition();
1921        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1922                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1923                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1924    }
1925
1926    final ProcessRecord startProcessLocked(String processName,
1927            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1928            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1929            boolean isolated) {
1930        ProcessRecord app;
1931        if (!isolated) {
1932            app = getProcessRecordLocked(processName, info.uid);
1933        } else {
1934            // If this is an isolated process, it can't re-use an existing process.
1935            app = null;
1936        }
1937        // We don't have to do anything more if:
1938        // (1) There is an existing application record; and
1939        // (2) The caller doesn't think it is dead, OR there is no thread
1940        //     object attached to it so we know it couldn't have crashed; and
1941        // (3) There is a pid assigned to it, so it is either starting or
1942        //     already running.
1943        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1944                + " app=" + app + " knownToBeDead=" + knownToBeDead
1945                + " thread=" + (app != null ? app.thread : null)
1946                + " pid=" + (app != null ? app.pid : -1));
1947        if (app != null && app.pid > 0) {
1948            if (!knownToBeDead || app.thread == null) {
1949                // We already have the app running, or are waiting for it to
1950                // come up (we have a pid but not yet its thread), so keep it.
1951                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1952                // If this is a new package in the process, add the package to the list
1953                app.addPackage(info.packageName);
1954                return app;
1955            } else {
1956                // An application record is attached to a previous process,
1957                // clean it up now.
1958                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1959                handleAppDiedLocked(app, true, true);
1960            }
1961        }
1962
1963        String hostingNameStr = hostingName != null
1964                ? hostingName.flattenToShortString() : null;
1965
1966        if (!isolated) {
1967            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1968                // If we are in the background, then check to see if this process
1969                // is bad.  If so, we will just silently fail.
1970                if (mBadProcesses.get(info.processName, info.uid) != null) {
1971                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1972                            + "/" + info.processName);
1973                    return null;
1974                }
1975            } else {
1976                // When the user is explicitly starting a process, then clear its
1977                // crash count so that we won't make it bad until they see at
1978                // least one crash dialog again, and make the process good again
1979                // if it had been bad.
1980                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1981                        + "/" + info.processName);
1982                mProcessCrashTimes.remove(info.processName, info.uid);
1983                if (mBadProcesses.get(info.processName, info.uid) != null) {
1984                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1985                            info.processName);
1986                    mBadProcesses.remove(info.processName, info.uid);
1987                    if (app != null) {
1988                        app.bad = false;
1989                    }
1990                }
1991            }
1992        }
1993
1994        if (app == null) {
1995            app = newProcessRecordLocked(null, info, processName, isolated);
1996            if (app == null) {
1997                Slog.w(TAG, "Failed making new process record for "
1998                        + processName + "/" + info.uid + " isolated=" + isolated);
1999                return null;
2000            }
2001            mProcessNames.put(processName, app.uid, app);
2002            if (isolated) {
2003                mIsolatedProcesses.put(app.uid, app);
2004            }
2005        } else {
2006            // If this is a new package in the process, add the package to the list
2007            app.addPackage(info.packageName);
2008        }
2009
2010        // If the system is not ready yet, then hold off on starting this
2011        // process until it is.
2012        if (!mProcessesReady
2013                && !isAllowedWhileBooting(info)
2014                && !allowWhileBooting) {
2015            if (!mProcessesOnHold.contains(app)) {
2016                mProcessesOnHold.add(app);
2017            }
2018            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2019            return app;
2020        }
2021
2022        startProcessLocked(app, hostingType, hostingNameStr);
2023        return (app.pid != 0) ? app : null;
2024    }
2025
2026    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2027        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2028    }
2029
2030    private final void startProcessLocked(ProcessRecord app,
2031            String hostingType, String hostingNameStr) {
2032        if (app.pid > 0 && app.pid != MY_PID) {
2033            synchronized (mPidsSelfLocked) {
2034                mPidsSelfLocked.remove(app.pid);
2035                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2036            }
2037            app.setPid(0);
2038        }
2039
2040        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2041                "startProcessLocked removing on hold: " + app);
2042        mProcessesOnHold.remove(app);
2043
2044        updateCpuStats();
2045
2046        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2047        mProcDeaths[0] = 0;
2048
2049        try {
2050            int uid = app.uid;
2051
2052            int[] gids = null;
2053            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2054            if (!app.isolated) {
2055                int[] permGids = null;
2056                try {
2057                    final PackageManager pm = mContext.getPackageManager();
2058                    permGids = pm.getPackageGids(app.info.packageName);
2059
2060                    if (Environment.isExternalStorageEmulated()) {
2061                        if (pm.checkPermission(
2062                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2063                                app.info.packageName) == PERMISSION_GRANTED) {
2064                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2065                        } else {
2066                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2067                        }
2068                    }
2069                } catch (PackageManager.NameNotFoundException e) {
2070                    Slog.w(TAG, "Unable to retrieve gids", e);
2071                }
2072
2073                /*
2074                 * Add shared application GID so applications can share some
2075                 * resources like shared libraries
2076                 */
2077                if (permGids == null) {
2078                    gids = new int[1];
2079                } else {
2080                    gids = new int[permGids.length + 1];
2081                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2082                }
2083                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2084            }
2085            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2086                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2087                        && mTopComponent != null
2088                        && app.processName.equals(mTopComponent.getPackageName())) {
2089                    uid = 0;
2090                }
2091                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2092                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2093                    uid = 0;
2094                }
2095            }
2096            int debugFlags = 0;
2097            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2098                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2099                // Also turn on CheckJNI for debuggable apps. It's quite
2100                // awkward to turn on otherwise.
2101                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2102            }
2103            // Run the app in safe mode if its manifest requests so or the
2104            // system is booted in safe mode.
2105            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2106                Zygote.systemInSafeMode == true) {
2107                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2108            }
2109            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2110                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2111            }
2112            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2113                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2114            }
2115            if ("1".equals(SystemProperties.get("debug.assert"))) {
2116                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2117            }
2118
2119            // Start the process.  It will either succeed and return a result containing
2120            // the PID of the new process, or else throw a RuntimeException.
2121            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2122                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2123                    app.info.targetSdkVersion, null, null);
2124
2125            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2126            synchronized (bs) {
2127                if (bs.isOnBattery()) {
2128                    app.batteryStats.incStartsLocked();
2129                }
2130            }
2131
2132            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2133                    app.processName, hostingType,
2134                    hostingNameStr != null ? hostingNameStr : "");
2135
2136            if (app.persistent) {
2137                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2138            }
2139
2140            StringBuilder buf = mStringBuilder;
2141            buf.setLength(0);
2142            buf.append("Start proc ");
2143            buf.append(app.processName);
2144            buf.append(" for ");
2145            buf.append(hostingType);
2146            if (hostingNameStr != null) {
2147                buf.append(" ");
2148                buf.append(hostingNameStr);
2149            }
2150            buf.append(": pid=");
2151            buf.append(startResult.pid);
2152            buf.append(" uid=");
2153            buf.append(uid);
2154            buf.append(" gids={");
2155            if (gids != null) {
2156                for (int gi=0; gi<gids.length; gi++) {
2157                    if (gi != 0) buf.append(", ");
2158                    buf.append(gids[gi]);
2159
2160                }
2161            }
2162            buf.append("}");
2163            Slog.i(TAG, buf.toString());
2164            app.setPid(startResult.pid);
2165            app.usingWrapper = startResult.usingWrapper;
2166            app.removed = false;
2167            synchronized (mPidsSelfLocked) {
2168                this.mPidsSelfLocked.put(startResult.pid, app);
2169                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2170                msg.obj = app;
2171                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2172                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2173            }
2174        } catch (RuntimeException e) {
2175            // XXX do better error recovery.
2176            app.setPid(0);
2177            Slog.e(TAG, "Failure starting process " + app.processName, e);
2178        }
2179    }
2180
2181    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2182        if (resumed) {
2183            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2184        } else {
2185            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2186        }
2187    }
2188
2189    boolean startHomeActivityLocked(int userId) {
2190        if (mHeadless) {
2191            // Added because none of the other calls to ensureBootCompleted seem to fire
2192            // when running headless.
2193            ensureBootCompleted();
2194            return false;
2195        }
2196
2197        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2198                && mTopAction == null) {
2199            // We are running in factory test mode, but unable to find
2200            // the factory test app, so just sit around displaying the
2201            // error message and don't try to start anything.
2202            return false;
2203        }
2204        Intent intent = new Intent(
2205            mTopAction,
2206            mTopData != null ? Uri.parse(mTopData) : null);
2207        intent.setComponent(mTopComponent);
2208        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2209            intent.addCategory(Intent.CATEGORY_HOME);
2210        }
2211        ActivityInfo aInfo =
2212            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2213        if (aInfo != null) {
2214            intent.setComponent(new ComponentName(
2215                    aInfo.applicationInfo.packageName, aInfo.name));
2216            // Don't do this if the home app is currently being
2217            // instrumented.
2218            aInfo = new ActivityInfo(aInfo);
2219            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2220            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2221                    aInfo.applicationInfo.uid);
2222            if (app == null || app.instrumentationClass == null) {
2223                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2224                mMainStack.startActivityLocked(null, intent, null, aInfo,
2225                        null, null, 0, 0, 0, 0, null, false, null);
2226            }
2227        }
2228
2229        return true;
2230    }
2231
2232    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2233        ActivityInfo ai = null;
2234        ComponentName comp = intent.getComponent();
2235        try {
2236            if (comp != null) {
2237                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2238            } else {
2239                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2240                        intent,
2241                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2242                            flags, userId);
2243
2244                if (info != null) {
2245                    ai = info.activityInfo;
2246                }
2247            }
2248        } catch (RemoteException e) {
2249            // ignore
2250        }
2251
2252        return ai;
2253    }
2254
2255    /**
2256     * Starts the "new version setup screen" if appropriate.
2257     */
2258    void startSetupActivityLocked() {
2259        // Only do this once per boot.
2260        if (mCheckedForSetup) {
2261            return;
2262        }
2263
2264        // We will show this screen if the current one is a different
2265        // version than the last one shown, and we are not running in
2266        // low-level factory test mode.
2267        final ContentResolver resolver = mContext.getContentResolver();
2268        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2269                Settings.Secure.getInt(resolver,
2270                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2271            mCheckedForSetup = true;
2272
2273            // See if we should be showing the platform update setup UI.
2274            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2275            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2276                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2277
2278            // We don't allow third party apps to replace this.
2279            ResolveInfo ri = null;
2280            for (int i=0; ris != null && i<ris.size(); i++) {
2281                if ((ris.get(i).activityInfo.applicationInfo.flags
2282                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2283                    ri = ris.get(i);
2284                    break;
2285                }
2286            }
2287
2288            if (ri != null) {
2289                String vers = ri.activityInfo.metaData != null
2290                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2291                        : null;
2292                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2293                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2294                            Intent.METADATA_SETUP_VERSION);
2295                }
2296                String lastVers = Settings.Secure.getString(
2297                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2298                if (vers != null && !vers.equals(lastVers)) {
2299                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2300                    intent.setComponent(new ComponentName(
2301                            ri.activityInfo.packageName, ri.activityInfo.name));
2302                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2303                            null, null, 0, 0, 0, 0, null, false, null);
2304                }
2305            }
2306        }
2307    }
2308
2309    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2310        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2311    }
2312
2313    void enforceNotIsolatedCaller(String caller) {
2314        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2315            throw new SecurityException("Isolated process not allowed to call " + caller);
2316        }
2317    }
2318
2319    public int getFrontActivityScreenCompatMode() {
2320        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2321        synchronized (this) {
2322            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2323        }
2324    }
2325
2326    public void setFrontActivityScreenCompatMode(int mode) {
2327        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2328                "setFrontActivityScreenCompatMode");
2329        synchronized (this) {
2330            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2331        }
2332    }
2333
2334    public int getPackageScreenCompatMode(String packageName) {
2335        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2336        synchronized (this) {
2337            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2338        }
2339    }
2340
2341    public void setPackageScreenCompatMode(String packageName, int mode) {
2342        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2343                "setPackageScreenCompatMode");
2344        synchronized (this) {
2345            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2346        }
2347    }
2348
2349    public boolean getPackageAskScreenCompat(String packageName) {
2350        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2351        synchronized (this) {
2352            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2353        }
2354    }
2355
2356    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2357        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2358                "setPackageAskScreenCompat");
2359        synchronized (this) {
2360            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2361        }
2362    }
2363
2364    void reportResumedActivityLocked(ActivityRecord r) {
2365        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2366        updateUsageStats(r, true);
2367    }
2368
2369    private void dispatchProcessesChanged() {
2370        int N;
2371        synchronized (this) {
2372            N = mPendingProcessChanges.size();
2373            if (mActiveProcessChanges.length < N) {
2374                mActiveProcessChanges = new ProcessChangeItem[N];
2375            }
2376            mPendingProcessChanges.toArray(mActiveProcessChanges);
2377            mAvailProcessChanges.addAll(mPendingProcessChanges);
2378            mPendingProcessChanges.clear();
2379            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2380        }
2381        int i = mProcessObservers.beginBroadcast();
2382        while (i > 0) {
2383            i--;
2384            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2385            if (observer != null) {
2386                try {
2387                    for (int j=0; j<N; j++) {
2388                        ProcessChangeItem item = mActiveProcessChanges[j];
2389                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2390                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2391                                    + item.pid + " uid=" + item.uid + ": "
2392                                    + item.foregroundActivities);
2393                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2394                                    item.foregroundActivities);
2395                        }
2396                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2397                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2398                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2399                            observer.onImportanceChanged(item.pid, item.uid,
2400                                    item.importance);
2401                        }
2402                    }
2403                } catch (RemoteException e) {
2404                }
2405            }
2406        }
2407        mProcessObservers.finishBroadcast();
2408    }
2409
2410    private void dispatchProcessDied(int pid, int uid) {
2411        int i = mProcessObservers.beginBroadcast();
2412        while (i > 0) {
2413            i--;
2414            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2415            if (observer != null) {
2416                try {
2417                    observer.onProcessDied(pid, uid);
2418                } catch (RemoteException e) {
2419                }
2420            }
2421        }
2422        mProcessObservers.finishBroadcast();
2423    }
2424
2425    final void doPendingActivityLaunchesLocked(boolean doResume) {
2426        final int N = mPendingActivityLaunches.size();
2427        if (N <= 0) {
2428            return;
2429        }
2430        for (int i=0; i<N; i++) {
2431            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2432            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2433                    pal.startFlags, doResume && i == (N-1), null);
2434        }
2435        mPendingActivityLaunches.clear();
2436    }
2437
2438    public final int startActivity(IApplicationThread caller,
2439            Intent intent, String resolvedType, IBinder resultTo,
2440            String resultWho, int requestCode, int startFlags,
2441            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2442        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2443                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2444    }
2445
2446    public final int startActivityAsUser(IApplicationThread caller,
2447            Intent intent, String resolvedType, IBinder resultTo,
2448            String resultWho, int requestCode, int startFlags,
2449            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2450        enforceNotIsolatedCaller("startActivity");
2451        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2452                false, true, "startActivity", null);
2453        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2454                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2455                null, null, options, userId);
2456    }
2457
2458    public final WaitResult startActivityAndWait(IApplicationThread caller,
2459            Intent intent, String resolvedType, IBinder resultTo,
2460            String resultWho, int requestCode, int startFlags, String profileFile,
2461            ParcelFileDescriptor profileFd, Bundle options, int userId) {
2462        enforceNotIsolatedCaller("startActivityAndWait");
2463        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2464                false, true, "startActivityAndWait", null);
2465        WaitResult res = new WaitResult();
2466        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2467                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2468                res, null, options, UserHandle.getCallingUserId());
2469        return res;
2470    }
2471
2472    public final int startActivityWithConfig(IApplicationThread caller,
2473            Intent intent, String resolvedType, IBinder resultTo,
2474            String resultWho, int requestCode, int startFlags, Configuration config,
2475            Bundle options, int userId) {
2476        enforceNotIsolatedCaller("startActivityWithConfig");
2477        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2478                false, true, "startActivityWithConfig", null);
2479        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2480                resultTo, resultWho, requestCode, startFlags,
2481                null, null, null, config, options, userId);
2482        return ret;
2483    }
2484
2485    public int startActivityIntentSender(IApplicationThread caller,
2486            IntentSender intent, Intent fillInIntent, String resolvedType,
2487            IBinder resultTo, String resultWho, int requestCode,
2488            int flagsMask, int flagsValues, Bundle options) {
2489        enforceNotIsolatedCaller("startActivityIntentSender");
2490        // Refuse possible leaked file descriptors
2491        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2492            throw new IllegalArgumentException("File descriptors passed in Intent");
2493        }
2494
2495        IIntentSender sender = intent.getTarget();
2496        if (!(sender instanceof PendingIntentRecord)) {
2497            throw new IllegalArgumentException("Bad PendingIntent object");
2498        }
2499
2500        PendingIntentRecord pir = (PendingIntentRecord)sender;
2501
2502        synchronized (this) {
2503            // If this is coming from the currently resumed activity, it is
2504            // effectively saying that app switches are allowed at this point.
2505            if (mMainStack.mResumedActivity != null
2506                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2507                            Binder.getCallingUid()) {
2508                mAppSwitchesAllowedTime = 0;
2509            }
2510        }
2511        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2512                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2513        return ret;
2514    }
2515
2516    public boolean startNextMatchingActivity(IBinder callingActivity,
2517            Intent intent, Bundle options) {
2518        // Refuse possible leaked file descriptors
2519        if (intent != null && intent.hasFileDescriptors() == true) {
2520            throw new IllegalArgumentException("File descriptors passed in Intent");
2521        }
2522
2523        synchronized (this) {
2524            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2525            if (r == null) {
2526                ActivityOptions.abort(options);
2527                return false;
2528            }
2529            if (r.app == null || r.app.thread == null) {
2530                // The caller is not running...  d'oh!
2531                ActivityOptions.abort(options);
2532                return false;
2533            }
2534            intent = new Intent(intent);
2535            // The caller is not allowed to change the data.
2536            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2537            // And we are resetting to find the next component...
2538            intent.setComponent(null);
2539
2540            ActivityInfo aInfo = null;
2541            try {
2542                List<ResolveInfo> resolves =
2543                    AppGlobals.getPackageManager().queryIntentActivities(
2544                            intent, r.resolvedType,
2545                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2546                            UserHandle.getCallingUserId());
2547
2548                // Look for the original activity in the list...
2549                final int N = resolves != null ? resolves.size() : 0;
2550                for (int i=0; i<N; i++) {
2551                    ResolveInfo rInfo = resolves.get(i);
2552                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2553                            && rInfo.activityInfo.name.equals(r.info.name)) {
2554                        // We found the current one...  the next matching is
2555                        // after it.
2556                        i++;
2557                        if (i<N) {
2558                            aInfo = resolves.get(i).activityInfo;
2559                        }
2560                        break;
2561                    }
2562                }
2563            } catch (RemoteException e) {
2564            }
2565
2566            if (aInfo == null) {
2567                // Nobody who is next!
2568                ActivityOptions.abort(options);
2569                return false;
2570            }
2571
2572            intent.setComponent(new ComponentName(
2573                    aInfo.applicationInfo.packageName, aInfo.name));
2574            intent.setFlags(intent.getFlags()&~(
2575                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2576                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2577                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2578                    Intent.FLAG_ACTIVITY_NEW_TASK));
2579
2580            // Okay now we need to start the new activity, replacing the
2581            // currently running activity.  This is a little tricky because
2582            // we want to start the new one as if the current one is finished,
2583            // but not finish the current one first so that there is no flicker.
2584            // And thus...
2585            final boolean wasFinishing = r.finishing;
2586            r.finishing = true;
2587
2588            // Propagate reply information over to the new activity.
2589            final ActivityRecord resultTo = r.resultTo;
2590            final String resultWho = r.resultWho;
2591            final int requestCode = r.requestCode;
2592            r.resultTo = null;
2593            if (resultTo != null) {
2594                resultTo.removeResultsLocked(r, resultWho, requestCode);
2595            }
2596
2597            final long origId = Binder.clearCallingIdentity();
2598            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2599                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2600                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2601                    options, false, null);
2602            Binder.restoreCallingIdentity(origId);
2603
2604            r.finishing = wasFinishing;
2605            if (res != ActivityManager.START_SUCCESS) {
2606                return false;
2607            }
2608            return true;
2609        }
2610    }
2611
2612    final int startActivityInPackage(int uid,
2613            Intent intent, String resolvedType, IBinder resultTo,
2614            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2615
2616        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2617                false, true, "startActivityInPackage", null);
2618
2619        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2620                resultTo, resultWho, requestCode, startFlags,
2621                null, null, null, null, options, userId);
2622        return ret;
2623    }
2624
2625    public final int startActivities(IApplicationThread caller,
2626            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2627        enforceNotIsolatedCaller("startActivities");
2628        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2629                options, UserHandle.getCallingUserId());
2630        return ret;
2631    }
2632
2633    final int startActivitiesInPackage(int uid,
2634            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2635            Bundle options, int userId) {
2636
2637        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2638                false, true, "startActivityInPackage", null);
2639        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2640                options, userId);
2641        return ret;
2642    }
2643
2644    final void addRecentTaskLocked(TaskRecord task) {
2645        int N = mRecentTasks.size();
2646        // Quick case: check if the top-most recent task is the same.
2647        if (N > 0 && mRecentTasks.get(0) == task) {
2648            return;
2649        }
2650        // Remove any existing entries that are the same kind of task.
2651        for (int i=0; i<N; i++) {
2652            TaskRecord tr = mRecentTasks.get(i);
2653            if (task.userId == tr.userId
2654                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2655                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2656                mRecentTasks.remove(i);
2657                i--;
2658                N--;
2659                if (task.intent == null) {
2660                    // If the new recent task we are adding is not fully
2661                    // specified, then replace it with the existing recent task.
2662                    task = tr;
2663                }
2664            }
2665        }
2666        if (N >= MAX_RECENT_TASKS) {
2667            mRecentTasks.remove(N-1);
2668        }
2669        mRecentTasks.add(0, task);
2670    }
2671
2672    public void setRequestedOrientation(IBinder token,
2673            int requestedOrientation) {
2674        synchronized (this) {
2675            ActivityRecord r = mMainStack.isInStackLocked(token);
2676            if (r == null) {
2677                return;
2678            }
2679            final long origId = Binder.clearCallingIdentity();
2680            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2681            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2682                    mConfiguration,
2683                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2684            if (config != null) {
2685                r.frozenBeforeDestroy = true;
2686                if (!updateConfigurationLocked(config, r, false, false)) {
2687                    mMainStack.resumeTopActivityLocked(null);
2688                }
2689            }
2690            Binder.restoreCallingIdentity(origId);
2691        }
2692    }
2693
2694    public int getRequestedOrientation(IBinder token) {
2695        synchronized (this) {
2696            ActivityRecord r = mMainStack.isInStackLocked(token);
2697            if (r == null) {
2698                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2699            }
2700            return mWindowManager.getAppOrientation(r.appToken);
2701        }
2702    }
2703
2704    /**
2705     * This is the internal entry point for handling Activity.finish().
2706     *
2707     * @param token The Binder token referencing the Activity we want to finish.
2708     * @param resultCode Result code, if any, from this Activity.
2709     * @param resultData Result data (Intent), if any, from this Activity.
2710     *
2711     * @return Returns true if the activity successfully finished, or false if it is still running.
2712     */
2713    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2714        // Refuse possible leaked file descriptors
2715        if (resultData != null && resultData.hasFileDescriptors() == true) {
2716            throw new IllegalArgumentException("File descriptors passed in Intent");
2717        }
2718
2719        synchronized(this) {
2720            if (mController != null) {
2721                // Find the first activity that is not finishing.
2722                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2723                if (next != null) {
2724                    // ask watcher if this is allowed
2725                    boolean resumeOK = true;
2726                    try {
2727                        resumeOK = mController.activityResuming(next.packageName);
2728                    } catch (RemoteException e) {
2729                        mController = null;
2730                    }
2731
2732                    if (!resumeOK) {
2733                        return false;
2734                    }
2735                }
2736            }
2737            final long origId = Binder.clearCallingIdentity();
2738            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2739                    resultData, "app-request", true);
2740            Binder.restoreCallingIdentity(origId);
2741            return res;
2742        }
2743    }
2744
2745    public final void finishHeavyWeightApp() {
2746        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2747                != PackageManager.PERMISSION_GRANTED) {
2748            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2749                    + Binder.getCallingPid()
2750                    + ", uid=" + Binder.getCallingUid()
2751                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2752            Slog.w(TAG, msg);
2753            throw new SecurityException(msg);
2754        }
2755
2756        synchronized(this) {
2757            if (mHeavyWeightProcess == null) {
2758                return;
2759            }
2760
2761            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2762                    mHeavyWeightProcess.activities);
2763            for (int i=0; i<activities.size(); i++) {
2764                ActivityRecord r = activities.get(i);
2765                if (!r.finishing) {
2766                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2767                    if (index >= 0) {
2768                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2769                                null, "finish-heavy", true);
2770                    }
2771                }
2772            }
2773
2774            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2775                    mHeavyWeightProcess.userId, 0));
2776            mHeavyWeightProcess = null;
2777        }
2778    }
2779
2780    public void crashApplication(int uid, int initialPid, String packageName,
2781            String message) {
2782        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2783                != PackageManager.PERMISSION_GRANTED) {
2784            String msg = "Permission Denial: crashApplication() from pid="
2785                    + Binder.getCallingPid()
2786                    + ", uid=" + Binder.getCallingUid()
2787                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2788            Slog.w(TAG, msg);
2789            throw new SecurityException(msg);
2790        }
2791
2792        synchronized(this) {
2793            ProcessRecord proc = null;
2794
2795            // Figure out which process to kill.  We don't trust that initialPid
2796            // still has any relation to current pids, so must scan through the
2797            // list.
2798            synchronized (mPidsSelfLocked) {
2799                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2800                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2801                    if (p.uid != uid) {
2802                        continue;
2803                    }
2804                    if (p.pid == initialPid) {
2805                        proc = p;
2806                        break;
2807                    }
2808                    for (String str : p.pkgList) {
2809                        if (str.equals(packageName)) {
2810                            proc = p;
2811                        }
2812                    }
2813                }
2814            }
2815
2816            if (proc == null) {
2817                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2818                        + " initialPid=" + initialPid
2819                        + " packageName=" + packageName);
2820                return;
2821            }
2822
2823            if (proc.thread != null) {
2824                if (proc.pid == Process.myPid()) {
2825                    Log.w(TAG, "crashApplication: trying to crash self!");
2826                    return;
2827                }
2828                long ident = Binder.clearCallingIdentity();
2829                try {
2830                    proc.thread.scheduleCrash(message);
2831                } catch (RemoteException e) {
2832                }
2833                Binder.restoreCallingIdentity(ident);
2834            }
2835        }
2836    }
2837
2838    public final void finishSubActivity(IBinder token, String resultWho,
2839            int requestCode) {
2840        synchronized(this) {
2841            final long origId = Binder.clearCallingIdentity();
2842            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2843            Binder.restoreCallingIdentity(origId);
2844        }
2845    }
2846
2847    public boolean finishActivityAffinity(IBinder token) {
2848        synchronized(this) {
2849            final long origId = Binder.clearCallingIdentity();
2850            boolean res = mMainStack.finishActivityAffinityLocked(token);
2851            Binder.restoreCallingIdentity(origId);
2852            return res;
2853        }
2854    }
2855
2856    public boolean willActivityBeVisible(IBinder token) {
2857        synchronized(this) {
2858            int i;
2859            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2860                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2861                if (r.appToken == token) {
2862                    return true;
2863                }
2864                if (r.fullscreen && !r.finishing) {
2865                    return false;
2866                }
2867            }
2868            return true;
2869        }
2870    }
2871
2872    public void overridePendingTransition(IBinder token, String packageName,
2873            int enterAnim, int exitAnim) {
2874        synchronized(this) {
2875            ActivityRecord self = mMainStack.isInStackLocked(token);
2876            if (self == null) {
2877                return;
2878            }
2879
2880            final long origId = Binder.clearCallingIdentity();
2881
2882            if (self.state == ActivityState.RESUMED
2883                    || self.state == ActivityState.PAUSING) {
2884                mWindowManager.overridePendingAppTransition(packageName,
2885                        enterAnim, exitAnim, null);
2886            }
2887
2888            Binder.restoreCallingIdentity(origId);
2889        }
2890    }
2891
2892    /**
2893     * Main function for removing an existing process from the activity manager
2894     * as a result of that process going away.  Clears out all connections
2895     * to the process.
2896     */
2897    private final void handleAppDiedLocked(ProcessRecord app,
2898            boolean restarting, boolean allowRestart) {
2899        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2900        if (!restarting) {
2901            mLruProcesses.remove(app);
2902        }
2903
2904        if (mProfileProc == app) {
2905            clearProfilerLocked();
2906        }
2907
2908        // Just in case...
2909        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2910            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2911            mMainStack.mPausingActivity = null;
2912        }
2913        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2914            mMainStack.mLastPausedActivity = null;
2915        }
2916
2917        // Remove this application's activities from active lists.
2918        mMainStack.removeHistoryRecordsForAppLocked(app);
2919
2920        boolean atTop = true;
2921        boolean hasVisibleActivities = false;
2922
2923        // Clean out the history list.
2924        int i = mMainStack.mHistory.size();
2925        if (localLOGV) Slog.v(
2926            TAG, "Removing app " + app + " from history with " + i + " entries");
2927        while (i > 0) {
2928            i--;
2929            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2930            if (localLOGV) Slog.v(
2931                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2932            if (r.app == app) {
2933                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2934                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2935                        RuntimeException here = new RuntimeException("here");
2936                        here.fillInStackTrace();
2937                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2938                                + ": haveState=" + r.haveState
2939                                + " stateNotNeeded=" + r.stateNotNeeded
2940                                + " finishing=" + r.finishing
2941                                + " state=" + r.state, here);
2942                    }
2943                    if (!r.finishing) {
2944                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2945                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2946                                System.identityHashCode(r),
2947                                r.task.taskId, r.shortComponentName,
2948                                "proc died without state saved");
2949                    }
2950                    mMainStack.removeActivityFromHistoryLocked(r);
2951
2952                } else {
2953                    // We have the current state for this activity, so
2954                    // it can be restarted later when needed.
2955                    if (localLOGV) Slog.v(
2956                        TAG, "Keeping entry, setting app to null");
2957                    if (r.visible) {
2958                        hasVisibleActivities = true;
2959                    }
2960                    r.app = null;
2961                    r.nowVisible = false;
2962                    if (!r.haveState) {
2963                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2964                                "App died, clearing saved state of " + r);
2965                        r.icicle = null;
2966                    }
2967                }
2968
2969                r.stack.cleanUpActivityLocked(r, true, true);
2970            }
2971            atTop = false;
2972        }
2973
2974        app.activities.clear();
2975
2976        if (app.instrumentationClass != null) {
2977            Slog.w(TAG, "Crash of app " + app.processName
2978                  + " running instrumentation " + app.instrumentationClass);
2979            Bundle info = new Bundle();
2980            info.putString("shortMsg", "Process crashed.");
2981            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2982        }
2983
2984        if (!restarting) {
2985            if (!mMainStack.resumeTopActivityLocked(null)) {
2986                // If there was nothing to resume, and we are not already
2987                // restarting this process, but there is a visible activity that
2988                // is hosted by the process...  then make sure all visible
2989                // activities are running, taking care of restarting this
2990                // process.
2991                if (hasVisibleActivities) {
2992                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2993                }
2994            }
2995        }
2996    }
2997
2998    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2999        IBinder threadBinder = thread.asBinder();
3000        // Find the application record.
3001        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3002            ProcessRecord rec = mLruProcesses.get(i);
3003            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3004                return i;
3005            }
3006        }
3007        return -1;
3008    }
3009
3010    final ProcessRecord getRecordForAppLocked(
3011            IApplicationThread thread) {
3012        if (thread == null) {
3013            return null;
3014        }
3015
3016        int appIndex = getLRURecordIndexForAppLocked(thread);
3017        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3018    }
3019
3020    final void appDiedLocked(ProcessRecord app, int pid,
3021            IApplicationThread thread) {
3022
3023        mProcDeaths[0]++;
3024
3025        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3026        synchronized (stats) {
3027            stats.noteProcessDiedLocked(app.info.uid, pid);
3028        }
3029
3030        // Clean up already done if the process has been re-started.
3031        if (app.pid == pid && app.thread != null &&
3032                app.thread.asBinder() == thread.asBinder()) {
3033            if (!app.killedBackground) {
3034                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3035                        + ") has died.");
3036            }
3037            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3038            if (localLOGV) Slog.v(
3039                TAG, "Dying app: " + app + ", pid: " + pid
3040                + ", thread: " + thread.asBinder());
3041            boolean doLowMem = app.instrumentationClass == null;
3042            handleAppDiedLocked(app, false, true);
3043
3044            if (doLowMem) {
3045                // If there are no longer any background processes running,
3046                // and the app that died was not running instrumentation,
3047                // then tell everyone we are now low on memory.
3048                boolean haveBg = false;
3049                for (int i=mLruProcesses.size()-1; i>=0; i--) {
3050                    ProcessRecord rec = mLruProcesses.get(i);
3051                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3052                        haveBg = true;
3053                        break;
3054                    }
3055                }
3056
3057                if (!haveBg) {
3058                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3059                    long now = SystemClock.uptimeMillis();
3060                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
3061                        ProcessRecord rec = mLruProcesses.get(i);
3062                        if (rec != app && rec.thread != null &&
3063                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3064                            // The low memory report is overriding any current
3065                            // state for a GC request.  Make sure to do
3066                            // heavy/important/visible/foreground processes first.
3067                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3068                                rec.lastRequestedGc = 0;
3069                            } else {
3070                                rec.lastRequestedGc = rec.lastLowMemory;
3071                            }
3072                            rec.reportLowMemory = true;
3073                            rec.lastLowMemory = now;
3074                            mProcessesToGc.remove(rec);
3075                            addProcessToGcListLocked(rec);
3076                        }
3077                    }
3078                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3079                    scheduleAppGcsLocked();
3080                }
3081            }
3082        } else if (app.pid != pid) {
3083            // A new process has already been started.
3084            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3085                    + ") has died and restarted (pid " + app.pid + ").");
3086            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3087        } else if (DEBUG_PROCESSES) {
3088            Slog.d(TAG, "Received spurious death notification for thread "
3089                    + thread.asBinder());
3090        }
3091    }
3092
3093    /**
3094     * If a stack trace dump file is configured, dump process stack traces.
3095     * @param clearTraces causes the dump file to be erased prior to the new
3096     *    traces being written, if true; when false, the new traces will be
3097     *    appended to any existing file content.
3098     * @param firstPids of dalvik VM processes to dump stack traces for first
3099     * @param lastPids of dalvik VM processes to dump stack traces for last
3100     * @param nativeProcs optional list of native process names to dump stack crawls
3101     * @return file containing stack traces, or null if no dump file is configured
3102     */
3103    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3104            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3105        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3106        if (tracesPath == null || tracesPath.length() == 0) {
3107            return null;
3108        }
3109
3110        File tracesFile = new File(tracesPath);
3111        try {
3112            File tracesDir = tracesFile.getParentFile();
3113            if (!tracesDir.exists()) {
3114                tracesFile.mkdirs();
3115                if (!SELinux.restorecon(tracesDir)) {
3116                    return null;
3117                }
3118            }
3119            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3120
3121            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3122            tracesFile.createNewFile();
3123            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3124        } catch (IOException e) {
3125            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3126            return null;
3127        }
3128
3129        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3130        return tracesFile;
3131    }
3132
3133    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3134            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3135        // Use a FileObserver to detect when traces finish writing.
3136        // The order of traces is considered important to maintain for legibility.
3137        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3138            public synchronized void onEvent(int event, String path) { notify(); }
3139        };
3140
3141        try {
3142            observer.startWatching();
3143
3144            // First collect all of the stacks of the most important pids.
3145            if (firstPids != null) {
3146                try {
3147                    int num = firstPids.size();
3148                    for (int i = 0; i < num; i++) {
3149                        synchronized (observer) {
3150                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3151                            observer.wait(200);  // Wait for write-close, give up after 200msec
3152                        }
3153                    }
3154                } catch (InterruptedException e) {
3155                    Log.wtf(TAG, e);
3156                }
3157            }
3158
3159            // Next measure CPU usage.
3160            if (processStats != null) {
3161                processStats.init();
3162                System.gc();
3163                processStats.update();
3164                try {
3165                    synchronized (processStats) {
3166                        processStats.wait(500); // measure over 1/2 second.
3167                    }
3168                } catch (InterruptedException e) {
3169                }
3170                processStats.update();
3171
3172                // We'll take the stack crawls of just the top apps using CPU.
3173                final int N = processStats.countWorkingStats();
3174                int numProcs = 0;
3175                for (int i=0; i<N && numProcs<5; i++) {
3176                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3177                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3178                        numProcs++;
3179                        try {
3180                            synchronized (observer) {
3181                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3182                                observer.wait(200);  // Wait for write-close, give up after 200msec
3183                            }
3184                        } catch (InterruptedException e) {
3185                            Log.wtf(TAG, e);
3186                        }
3187
3188                    }
3189                }
3190            }
3191
3192        } finally {
3193            observer.stopWatching();
3194        }
3195
3196        if (nativeProcs != null) {
3197            int[] pids = Process.getPidsForCommands(nativeProcs);
3198            if (pids != null) {
3199                for (int pid : pids) {
3200                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3201                }
3202            }
3203        }
3204    }
3205
3206    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3207        if (true || IS_USER_BUILD) {
3208            return;
3209        }
3210        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3211        if (tracesPath == null || tracesPath.length() == 0) {
3212            return;
3213        }
3214
3215        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3216        StrictMode.allowThreadDiskWrites();
3217        try {
3218            final File tracesFile = new File(tracesPath);
3219            final File tracesDir = tracesFile.getParentFile();
3220            final File tracesTmp = new File(tracesDir, "__tmp__");
3221            try {
3222                if (!tracesDir.exists()) {
3223                    tracesFile.mkdirs();
3224                    if (!SELinux.restorecon(tracesDir.getPath())) {
3225                        return;
3226                    }
3227                }
3228                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3229
3230                if (tracesFile.exists()) {
3231                    tracesTmp.delete();
3232                    tracesFile.renameTo(tracesTmp);
3233                }
3234                StringBuilder sb = new StringBuilder();
3235                Time tobj = new Time();
3236                tobj.set(System.currentTimeMillis());
3237                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3238                sb.append(": ");
3239                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3240                sb.append(" since ");
3241                sb.append(msg);
3242                FileOutputStream fos = new FileOutputStream(tracesFile);
3243                fos.write(sb.toString().getBytes());
3244                if (app == null) {
3245                    fos.write("\n*** No application process!".getBytes());
3246                }
3247                fos.close();
3248                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3249            } catch (IOException e) {
3250                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3251                return;
3252            }
3253
3254            if (app != null) {
3255                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3256                firstPids.add(app.pid);
3257                dumpStackTraces(tracesPath, firstPids, null, null, null);
3258            }
3259
3260            File lastTracesFile = null;
3261            File curTracesFile = null;
3262            for (int i=9; i>=0; i--) {
3263                String name = String.format("slow%02d.txt", i);
3264                curTracesFile = new File(tracesDir, name);
3265                if (curTracesFile.exists()) {
3266                    if (lastTracesFile != null) {
3267                        curTracesFile.renameTo(lastTracesFile);
3268                    } else {
3269                        curTracesFile.delete();
3270                    }
3271                }
3272                lastTracesFile = curTracesFile;
3273            }
3274            tracesFile.renameTo(curTracesFile);
3275            if (tracesTmp.exists()) {
3276                tracesTmp.renameTo(tracesFile);
3277            }
3278        } finally {
3279            StrictMode.setThreadPolicy(oldPolicy);
3280        }
3281    }
3282
3283    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3284            ActivityRecord parent, final String annotation) {
3285        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3286        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3287
3288        if (mController != null) {
3289            try {
3290                // 0 == continue, -1 = kill process immediately
3291                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3292                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3293            } catch (RemoteException e) {
3294                mController = null;
3295            }
3296        }
3297
3298        long anrTime = SystemClock.uptimeMillis();
3299        if (MONITOR_CPU_USAGE) {
3300            updateCpuStatsNow();
3301        }
3302
3303        synchronized (this) {
3304            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3305            if (mShuttingDown) {
3306                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3307                return;
3308            } else if (app.notResponding) {
3309                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3310                return;
3311            } else if (app.crashing) {
3312                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3313                return;
3314            }
3315
3316            // In case we come through here for the same app before completing
3317            // this one, mark as anring now so we will bail out.
3318            app.notResponding = true;
3319
3320            // Log the ANR to the event log.
3321            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3322                    annotation);
3323
3324            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3325            firstPids.add(app.pid);
3326
3327            int parentPid = app.pid;
3328            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3329            if (parentPid != app.pid) firstPids.add(parentPid);
3330
3331            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3332
3333            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3334                ProcessRecord r = mLruProcesses.get(i);
3335                if (r != null && r.thread != null) {
3336                    int pid = r.pid;
3337                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3338                        if (r.persistent) {
3339                            firstPids.add(pid);
3340                        } else {
3341                            lastPids.put(pid, Boolean.TRUE);
3342                        }
3343                    }
3344                }
3345            }
3346        }
3347
3348        // Log the ANR to the main log.
3349        StringBuilder info = new StringBuilder();
3350        info.setLength(0);
3351        info.append("ANR in ").append(app.processName);
3352        if (activity != null && activity.shortComponentName != null) {
3353            info.append(" (").append(activity.shortComponentName).append(")");
3354        }
3355        info.append("\n");
3356        if (annotation != null) {
3357            info.append("Reason: ").append(annotation).append("\n");
3358        }
3359        if (parent != null && parent != activity) {
3360            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3361        }
3362
3363        final ProcessStats processStats = new ProcessStats(true);
3364
3365        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3366
3367        String cpuInfo = null;
3368        if (MONITOR_CPU_USAGE) {
3369            updateCpuStatsNow();
3370            synchronized (mProcessStatsThread) {
3371                cpuInfo = mProcessStats.printCurrentState(anrTime);
3372            }
3373            info.append(processStats.printCurrentLoad());
3374            info.append(cpuInfo);
3375        }
3376
3377        info.append(processStats.printCurrentState(anrTime));
3378
3379        Slog.e(TAG, info.toString());
3380        if (tracesFile == null) {
3381            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3382            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3383        }
3384
3385        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3386                cpuInfo, tracesFile, null);
3387
3388        if (mController != null) {
3389            try {
3390                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3391                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3392                if (res != 0) {
3393                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3394                    return;
3395                }
3396            } catch (RemoteException e) {
3397                mController = null;
3398            }
3399        }
3400
3401        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3402        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3403                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3404
3405        synchronized (this) {
3406            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3407                Slog.w(TAG, "Killing " + app + ": background ANR");
3408                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3409                        app.processName, app.setAdj, "background ANR");
3410                Process.killProcessQuiet(app.pid);
3411                return;
3412            }
3413
3414            // Set the app's notResponding state, and look up the errorReportReceiver
3415            makeAppNotRespondingLocked(app,
3416                    activity != null ? activity.shortComponentName : null,
3417                    annotation != null ? "ANR " + annotation : "ANR",
3418                    info.toString());
3419
3420            // Bring up the infamous App Not Responding dialog
3421            Message msg = Message.obtain();
3422            HashMap map = new HashMap();
3423            msg.what = SHOW_NOT_RESPONDING_MSG;
3424            msg.obj = map;
3425            map.put("app", app);
3426            if (activity != null) {
3427                map.put("activity", activity);
3428            }
3429
3430            mHandler.sendMessage(msg);
3431        }
3432    }
3433
3434    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3435        if (!mLaunchWarningShown) {
3436            mLaunchWarningShown = true;
3437            mHandler.post(new Runnable() {
3438                @Override
3439                public void run() {
3440                    synchronized (ActivityManagerService.this) {
3441                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3442                        d.show();
3443                        mHandler.postDelayed(new Runnable() {
3444                            @Override
3445                            public void run() {
3446                                synchronized (ActivityManagerService.this) {
3447                                    d.dismiss();
3448                                    mLaunchWarningShown = false;
3449                                }
3450                            }
3451                        }, 4000);
3452                    }
3453                }
3454            });
3455        }
3456    }
3457
3458    public boolean clearApplicationUserData(final String packageName,
3459            final IPackageDataObserver observer, int userId) {
3460        enforceNotIsolatedCaller("clearApplicationUserData");
3461        int uid = Binder.getCallingUid();
3462        int pid = Binder.getCallingPid();
3463        userId = handleIncomingUserLocked(pid, uid,
3464                userId, false, true, "clearApplicationUserData", null);
3465        long callingId = Binder.clearCallingIdentity();
3466        try {
3467            IPackageManager pm = AppGlobals.getPackageManager();
3468            int pkgUid = -1;
3469            synchronized(this) {
3470                try {
3471                    pkgUid = pm.getPackageUid(packageName, userId);
3472                } catch (RemoteException e) {
3473                }
3474                if (pkgUid == -1) {
3475                    Slog.w(TAG, "Invalid packageName:" + packageName);
3476                    return false;
3477                }
3478                if (uid == pkgUid || checkComponentPermission(
3479                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3480                        pid, uid, -1, true)
3481                        == PackageManager.PERMISSION_GRANTED) {
3482                    forceStopPackageLocked(packageName, pkgUid);
3483                } else {
3484                    throw new SecurityException(pid+" does not have permission:"+
3485                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3486                                    "for process:"+packageName);
3487                }
3488            }
3489
3490            try {
3491                //clear application user data
3492                pm.clearApplicationUserData(packageName, observer, userId);
3493                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3494                        Uri.fromParts("package", packageName, null));
3495                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3496                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3497                        null, null, 0, null, null, null, false, false, userId);
3498            } catch (RemoteException e) {
3499            }
3500        } finally {
3501            Binder.restoreCallingIdentity(callingId);
3502        }
3503        return true;
3504    }
3505
3506    public void killBackgroundProcesses(final String packageName, int userId) {
3507        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3508                != PackageManager.PERMISSION_GRANTED &&
3509                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3510                        != PackageManager.PERMISSION_GRANTED) {
3511            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3512                    + Binder.getCallingPid()
3513                    + ", uid=" + Binder.getCallingUid()
3514                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3515            Slog.w(TAG, msg);
3516            throw new SecurityException(msg);
3517        }
3518
3519        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
3520                userId, true, true, "killBackgroundProcesses", null);
3521        long callingId = Binder.clearCallingIdentity();
3522        try {
3523            IPackageManager pm = AppGlobals.getPackageManager();
3524            synchronized(this) {
3525                int appId = -1;
3526                try {
3527                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
3528                } catch (RemoteException e) {
3529                }
3530                if (appId == -1) {
3531                    Slog.w(TAG, "Invalid packageName: " + packageName);
3532                    return;
3533                }
3534                killPackageProcessesLocked(packageName, appId, userId,
3535                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3536            }
3537        } finally {
3538            Binder.restoreCallingIdentity(callingId);
3539        }
3540    }
3541
3542    public void killAllBackgroundProcesses() {
3543        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3544                != PackageManager.PERMISSION_GRANTED) {
3545            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3546                    + Binder.getCallingPid()
3547                    + ", uid=" + Binder.getCallingUid()
3548                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3549            Slog.w(TAG, msg);
3550            throw new SecurityException(msg);
3551        }
3552
3553        long callingId = Binder.clearCallingIdentity();
3554        try {
3555            synchronized(this) {
3556                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3557                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3558                    final int NA = apps.size();
3559                    for (int ia=0; ia<NA; ia++) {
3560                        ProcessRecord app = apps.valueAt(ia);
3561                        if (app.persistent) {
3562                            // we don't kill persistent processes
3563                            continue;
3564                        }
3565                        if (app.removed) {
3566                            procs.add(app);
3567                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3568                            app.removed = true;
3569                            procs.add(app);
3570                        }
3571                    }
3572                }
3573
3574                int N = procs.size();
3575                for (int i=0; i<N; i++) {
3576                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3577                }
3578            }
3579        } finally {
3580            Binder.restoreCallingIdentity(callingId);
3581        }
3582    }
3583
3584    public void forceStopPackage(final String packageName, int userId) {
3585        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3586                != PackageManager.PERMISSION_GRANTED) {
3587            String msg = "Permission Denial: forceStopPackage() from pid="
3588                    + Binder.getCallingPid()
3589                    + ", uid=" + Binder.getCallingUid()
3590                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3591            Slog.w(TAG, msg);
3592            throw new SecurityException(msg);
3593        }
3594        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
3595                userId, true, true, "forceStopPackage", null);
3596        long callingId = Binder.clearCallingIdentity();
3597        try {
3598            IPackageManager pm = AppGlobals.getPackageManager();
3599            synchronized(this) {
3600                int[] users = userId == UserHandle.USER_ALL
3601                        ? getUsersLocked() : new int[] { userId };
3602                for (int user : users) {
3603                    int pkgUid = -1;
3604                    try {
3605                        pkgUid = pm.getPackageUid(packageName, user);
3606                    } catch (RemoteException e) {
3607                    }
3608                    if (pkgUid == -1) {
3609                        Slog.w(TAG, "Invalid packageName: " + packageName);
3610                        continue;
3611                    }
3612                    try {
3613                        pm.setPackageStoppedState(packageName, true, user);
3614                    } catch (RemoteException e) {
3615                    } catch (IllegalArgumentException e) {
3616                        Slog.w(TAG, "Failed trying to unstop package "
3617                                + packageName + ": " + e);
3618                    }
3619                    if (isUserRunningLocked(user)) {
3620                        forceStopPackageLocked(packageName, pkgUid);
3621                    }
3622                }
3623            }
3624        } finally {
3625            Binder.restoreCallingIdentity(callingId);
3626        }
3627    }
3628
3629    /*
3630     * The pkg name and app id have to be specified.
3631     */
3632    public void killApplicationWithAppId(String pkg, int appid) {
3633        if (pkg == null) {
3634            return;
3635        }
3636        // Make sure the uid is valid.
3637        if (appid < 0) {
3638            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
3639            return;
3640        }
3641        int callerUid = Binder.getCallingUid();
3642        // Only the system server can kill an application
3643        if (callerUid == Process.SYSTEM_UID) {
3644            // Post an aysnc message to kill the application
3645            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3646            msg.arg1 = appid;
3647            msg.arg2 = 0;
3648            msg.obj = pkg;
3649            mHandler.sendMessage(msg);
3650        } else {
3651            throw new SecurityException(callerUid + " cannot kill pkg: " +
3652                    pkg);
3653        }
3654    }
3655
3656    public void closeSystemDialogs(String reason) {
3657        enforceNotIsolatedCaller("closeSystemDialogs");
3658
3659        final int pid = Binder.getCallingPid();
3660        final int uid = Binder.getCallingUid();
3661        final long origId = Binder.clearCallingIdentity();
3662        try {
3663            synchronized (this) {
3664                // Only allow this from foreground processes, so that background
3665                // applications can't abuse it to prevent system UI from being shown.
3666                if (uid >= Process.FIRST_APPLICATION_UID) {
3667                    ProcessRecord proc;
3668                    synchronized (mPidsSelfLocked) {
3669                        proc = mPidsSelfLocked.get(pid);
3670                    }
3671                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3672                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3673                                + " from background process " + proc);
3674                        return;
3675                    }
3676                }
3677                closeSystemDialogsLocked(reason);
3678            }
3679        } finally {
3680            Binder.restoreCallingIdentity(origId);
3681        }
3682    }
3683
3684    void closeSystemDialogsLocked(String reason) {
3685        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3686        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3687        if (reason != null) {
3688            intent.putExtra("reason", reason);
3689        }
3690        mWindowManager.closeSystemDialogs(reason);
3691
3692        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3693            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3694            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3695                r.stack.finishActivityLocked(r, i,
3696                        Activity.RESULT_CANCELED, null, "close-sys", true);
3697            }
3698        }
3699
3700        broadcastIntentLocked(null, null, intent, null,
3701                null, 0, null, null, null, false, false, -1,
3702                Process.SYSTEM_UID, UserHandle.USER_ALL);
3703    }
3704
3705    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3706            throws RemoteException {
3707        enforceNotIsolatedCaller("getProcessMemoryInfo");
3708        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3709        for (int i=pids.length-1; i>=0; i--) {
3710            infos[i] = new Debug.MemoryInfo();
3711            Debug.getMemoryInfo(pids[i], infos[i]);
3712        }
3713        return infos;
3714    }
3715
3716    public long[] getProcessPss(int[] pids) throws RemoteException {
3717        enforceNotIsolatedCaller("getProcessPss");
3718        long[] pss = new long[pids.length];
3719        for (int i=pids.length-1; i>=0; i--) {
3720            pss[i] = Debug.getPss(pids[i]);
3721        }
3722        return pss;
3723    }
3724
3725    public void killApplicationProcess(String processName, int uid) {
3726        if (processName == null) {
3727            return;
3728        }
3729
3730        int callerUid = Binder.getCallingUid();
3731        // Only the system server can kill an application
3732        if (callerUid == Process.SYSTEM_UID) {
3733            synchronized (this) {
3734                ProcessRecord app = getProcessRecordLocked(processName, uid);
3735                if (app != null && app.thread != null) {
3736                    try {
3737                        app.thread.scheduleSuicide();
3738                    } catch (RemoteException e) {
3739                        // If the other end already died, then our work here is done.
3740                    }
3741                } else {
3742                    Slog.w(TAG, "Process/uid not found attempting kill of "
3743                            + processName + " / " + uid);
3744                }
3745            }
3746        } else {
3747            throw new SecurityException(callerUid + " cannot kill app process: " +
3748                    processName);
3749        }
3750    }
3751
3752    private void forceStopPackageLocked(final String packageName, int uid) {
3753        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
3754                false, true, false, UserHandle.getUserId(uid));
3755        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3756                Uri.fromParts("package", packageName, null));
3757        if (!mProcessesReady) {
3758            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3759        }
3760        intent.putExtra(Intent.EXTRA_UID, uid);
3761        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
3762        broadcastIntentLocked(null, null, intent,
3763                null, null, 0, null, null, null,
3764                false, false,
3765                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3766    }
3767
3768    private void forceStopUserLocked(int userId) {
3769        forceStopPackageLocked(null, -1, false, false, true, false, userId);
3770        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3771        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3772        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3773        broadcastIntentLocked(null, null, intent,
3774                null, null, 0, null, null, null,
3775                false, false,
3776                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
3777    }
3778
3779    private final boolean killPackageProcessesLocked(String packageName, int appId,
3780            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3781            boolean doit, boolean evenPersistent, String reason) {
3782        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3783
3784        // Remove all processes this package may have touched: all with the
3785        // same UID (except for the system or root user), and all whose name
3786        // matches the package name.
3787        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3788        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3789            final int NA = apps.size();
3790            for (int ia=0; ia<NA; ia++) {
3791                ProcessRecord app = apps.valueAt(ia);
3792                if (app.persistent && !evenPersistent) {
3793                    // we don't kill persistent processes
3794                    continue;
3795                }
3796                if (app.removed) {
3797                    if (doit) {
3798                        procs.add(app);
3799                    }
3800                    continue;
3801                }
3802
3803                // Skip process if it doesn't meet our oom adj requirement.
3804                if (app.setAdj < minOomAdj) {
3805                    continue;
3806                }
3807
3808                // If no package is specified, we call all processes under the
3809                // give user id.
3810                if (packageName == null) {
3811                    if (app.userId != userId) {
3812                        continue;
3813                    }
3814                // Package has been specified, we want to hit all processes
3815                // that match it.  We need to qualify this by the processes
3816                // that are running under the specified app and user ID.
3817                } else {
3818                    if (UserHandle.getAppId(app.uid) != appId) {
3819                        continue;
3820                    }
3821                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
3822                        continue;
3823                    }
3824                    if (!app.pkgList.contains(packageName)) {
3825                        continue;
3826                    }
3827                }
3828
3829                // Process has passed all conditions, kill it!
3830                if (!doit) {
3831                    return true;
3832                }
3833                app.removed = true;
3834                procs.add(app);
3835            }
3836        }
3837
3838        int N = procs.size();
3839        for (int i=0; i<N; i++) {
3840            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3841        }
3842        return N > 0;
3843    }
3844
3845    private final boolean forceStopPackageLocked(String name, int appId,
3846            boolean callerWillRestart, boolean purgeCache, boolean doit,
3847            boolean evenPersistent, int userId) {
3848        int i;
3849        int N;
3850
3851        if (userId == UserHandle.USER_ALL && name == null) {
3852            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3853        }
3854
3855        if (appId < 0 && name != null) {
3856            try {
3857                appId = UserHandle.getAppId(
3858                        AppGlobals.getPackageManager().getPackageUid(name, 0));
3859            } catch (RemoteException e) {
3860            }
3861        }
3862
3863        if (doit) {
3864            if (name != null) {
3865                Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3866                        + " user=" + userId);
3867            } else {
3868                Slog.i(TAG, "Force stopping user " + userId);
3869            }
3870
3871            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3872            while (badApps.hasNext()) {
3873                SparseArray<Long> ba = badApps.next();
3874                for (i=ba.size()-1; i>=0; i--) {
3875                    boolean remove = false;
3876                    final int entUid = ba.keyAt(i);
3877                    if (name != null) {
3878                        if (userId == UserHandle.USER_ALL) {
3879                            if (UserHandle.getAppId(entUid) == appId) {
3880                                remove = true;
3881                            }
3882                        } else {
3883                            if (entUid == UserHandle.getUid(userId, appId)) {
3884                                remove = true;
3885                            }
3886                        }
3887                    } else if (UserHandle.getUserId(entUid) == userId) {
3888                        remove = true;
3889                    }
3890                    if (remove) {
3891                        ba.removeAt(i);
3892                    }
3893                }
3894                if (ba.size() == 0) {
3895                    badApps.remove();
3896                }
3897            }
3898        }
3899
3900        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3901                -100, callerWillRestart, false, doit, evenPersistent,
3902                name == null ? ("force stop user " + userId) : ("force stop " + name));
3903
3904        TaskRecord lastTask = null;
3905        for (i=0; i<mMainStack.mHistory.size(); i++) {
3906            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3907            final boolean samePackage = r.packageName.equals(name)
3908                    || (name == null && r.userId == userId);
3909            if ((userId == UserHandle.USER_ALL || r.userId == userId)
3910                    && (samePackage || r.task == lastTask)
3911                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3912                if (!doit) {
3913                    if (r.finishing) {
3914                        // If this activity is just finishing, then it is not
3915                        // interesting as far as something to stop.
3916                        continue;
3917                    }
3918                    return true;
3919                }
3920                didSomething = true;
3921                Slog.i(TAG, "  Force finishing activity " + r);
3922                if (samePackage) {
3923                    if (r.app != null) {
3924                        r.app.removed = true;
3925                    }
3926                    r.app = null;
3927                }
3928                lastTask = r.task;
3929                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3930                        null, "force-stop", true)) {
3931                    i--;
3932                }
3933            }
3934        }
3935
3936        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3937            if (!doit) {
3938                return true;
3939            }
3940            didSomething = true;
3941        }
3942
3943        if (name == null) {
3944            // Remove all sticky broadcasts from this user.
3945            mStickyBroadcasts.remove(userId);
3946        }
3947
3948        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3949        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
3950                userId, providers)) {
3951            if (!doit) {
3952                return true;
3953            }
3954            didSomething = true;
3955        }
3956        N = providers.size();
3957        for (i=0; i<N; i++) {
3958            removeDyingProviderLocked(null, providers.get(i), true);
3959        }
3960
3961        if (mIntentSenderRecords.size() > 0) {
3962            Iterator<WeakReference<PendingIntentRecord>> it
3963                    = mIntentSenderRecords.values().iterator();
3964            while (it.hasNext()) {
3965                WeakReference<PendingIntentRecord> wpir = it.next();
3966                if (wpir == null) {
3967                    it.remove();
3968                    continue;
3969                }
3970                PendingIntentRecord pir = wpir.get();
3971                if (pir == null) {
3972                    it.remove();
3973                    continue;
3974                }
3975                if (name == null) {
3976                    // Stopping user, remove all objects for the user.
3977                    if (pir.key.userId != userId) {
3978                        // Not the same user, skip it.
3979                        continue;
3980                    }
3981                } else {
3982                    if (UserHandle.getAppId(pir.uid) != appId) {
3983                        // Different app id, skip it.
3984                        continue;
3985                    }
3986                    if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
3987                        // Different user, skip it.
3988                        continue;
3989                    }
3990                    if (!pir.key.packageName.equals(name)) {
3991                        // Different package, skip it.
3992                        continue;
3993                    }
3994                }
3995                if (!doit) {
3996                    return true;
3997                }
3998                didSomething = true;
3999                it.remove();
4000                pir.canceled = true;
4001                if (pir.key.activity != null) {
4002                    pir.key.activity.pendingResults.remove(pir.ref);
4003                }
4004            }
4005        }
4006
4007        if (doit) {
4008            if (purgeCache && name != null) {
4009                AttributeCache ac = AttributeCache.instance();
4010                if (ac != null) {
4011                    ac.removePackage(name);
4012                }
4013            }
4014            if (mBooted) {
4015                mMainStack.resumeTopActivityLocked(null);
4016                mMainStack.scheduleIdleLocked();
4017            }
4018        }
4019
4020        return didSomething;
4021    }
4022
4023    private final boolean removeProcessLocked(ProcessRecord app,
4024            boolean callerWillRestart, boolean allowRestart, String reason) {
4025        final String name = app.processName;
4026        final int uid = app.uid;
4027        if (DEBUG_PROCESSES) Slog.d(
4028            TAG, "Force removing proc " + app.toShortString() + " (" + name
4029            + "/" + uid + ")");
4030
4031        mProcessNames.remove(name, uid);
4032        mIsolatedProcesses.remove(app.uid);
4033        if (mHeavyWeightProcess == app) {
4034            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4035                    mHeavyWeightProcess.userId, 0));
4036            mHeavyWeightProcess = null;
4037        }
4038        boolean needRestart = false;
4039        if (app.pid > 0 && app.pid != MY_PID) {
4040            int pid = app.pid;
4041            synchronized (mPidsSelfLocked) {
4042                mPidsSelfLocked.remove(pid);
4043                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4044            }
4045            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
4046            handleAppDiedLocked(app, true, allowRestart);
4047            mLruProcesses.remove(app);
4048            Process.killProcessQuiet(pid);
4049
4050            if (app.persistent && !app.isolated) {
4051                if (!callerWillRestart) {
4052                    addAppLocked(app.info, false);
4053                } else {
4054                    needRestart = true;
4055                }
4056            }
4057        } else {
4058            mRemovedProcesses.add(app);
4059        }
4060
4061        return needRestart;
4062    }
4063
4064    private final void processStartTimedOutLocked(ProcessRecord app) {
4065        final int pid = app.pid;
4066        boolean gone = false;
4067        synchronized (mPidsSelfLocked) {
4068            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4069            if (knownApp != null && knownApp.thread == null) {
4070                mPidsSelfLocked.remove(pid);
4071                gone = true;
4072            }
4073        }
4074
4075        if (gone) {
4076            Slog.w(TAG, "Process " + app + " failed to attach");
4077            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
4078                    app.processName);
4079            mProcessNames.remove(app.processName, app.uid);
4080            mIsolatedProcesses.remove(app.uid);
4081            if (mHeavyWeightProcess == app) {
4082                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4083                        mHeavyWeightProcess.userId, 0));
4084                mHeavyWeightProcess = null;
4085            }
4086            // Take care of any launching providers waiting for this process.
4087            checkAppInLaunchingProvidersLocked(app, true);
4088            // Take care of any services that are waiting for the process.
4089            mServices.processStartTimedOutLocked(app);
4090            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
4091                    app.processName, app.setAdj, "start timeout");
4092            Process.killProcessQuiet(pid);
4093            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4094                Slog.w(TAG, "Unattached app died before backup, skipping");
4095                try {
4096                    IBackupManager bm = IBackupManager.Stub.asInterface(
4097                            ServiceManager.getService(Context.BACKUP_SERVICE));
4098                    bm.agentDisconnected(app.info.packageName);
4099                } catch (RemoteException e) {
4100                    // Can't happen; the backup manager is local
4101                }
4102            }
4103            if (isPendingBroadcastProcessLocked(pid)) {
4104                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4105                skipPendingBroadcastLocked(pid);
4106            }
4107        } else {
4108            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4109        }
4110    }
4111
4112    private final boolean attachApplicationLocked(IApplicationThread thread,
4113            int pid) {
4114
4115        // Find the application record that is being attached...  either via
4116        // the pid if we are running in multiple processes, or just pull the
4117        // next app record if we are emulating process with anonymous threads.
4118        ProcessRecord app;
4119        if (pid != MY_PID && pid >= 0) {
4120            synchronized (mPidsSelfLocked) {
4121                app = mPidsSelfLocked.get(pid);
4122            }
4123        } else {
4124            app = null;
4125        }
4126
4127        if (app == null) {
4128            Slog.w(TAG, "No pending application record for pid " + pid
4129                    + " (IApplicationThread " + thread + "); dropping process");
4130            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4131            if (pid > 0 && pid != MY_PID) {
4132                Process.killProcessQuiet(pid);
4133            } else {
4134                try {
4135                    thread.scheduleExit();
4136                } catch (Exception e) {
4137                    // Ignore exceptions.
4138                }
4139            }
4140            return false;
4141        }
4142
4143        // If this application record is still attached to a previous
4144        // process, clean it up now.
4145        if (app.thread != null) {
4146            handleAppDiedLocked(app, true, true);
4147        }
4148
4149        // Tell the process all about itself.
4150
4151        if (localLOGV) Slog.v(
4152                TAG, "Binding process pid " + pid + " to record " + app);
4153
4154        String processName = app.processName;
4155        try {
4156            AppDeathRecipient adr = new AppDeathRecipient(
4157                    app, pid, thread);
4158            thread.asBinder().linkToDeath(adr, 0);
4159            app.deathRecipient = adr;
4160        } catch (RemoteException e) {
4161            app.resetPackageList();
4162            startProcessLocked(app, "link fail", processName);
4163            return false;
4164        }
4165
4166        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
4167
4168        app.thread = thread;
4169        app.curAdj = app.setAdj = -100;
4170        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4171        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4172        app.forcingToForeground = null;
4173        app.foregroundServices = false;
4174        app.hasShownUi = false;
4175        app.debugging = false;
4176
4177        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4178
4179        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4180        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4181
4182        if (!normalMode) {
4183            Slog.i(TAG, "Launching preboot mode app: " + app);
4184        }
4185
4186        if (localLOGV) Slog.v(
4187            TAG, "New app record " + app
4188            + " thread=" + thread.asBinder() + " pid=" + pid);
4189        try {
4190            int testMode = IApplicationThread.DEBUG_OFF;
4191            if (mDebugApp != null && mDebugApp.equals(processName)) {
4192                testMode = mWaitForDebugger
4193                    ? IApplicationThread.DEBUG_WAIT
4194                    : IApplicationThread.DEBUG_ON;
4195                app.debugging = true;
4196                if (mDebugTransient) {
4197                    mDebugApp = mOrigDebugApp;
4198                    mWaitForDebugger = mOrigWaitForDebugger;
4199                }
4200            }
4201            String profileFile = app.instrumentationProfileFile;
4202            ParcelFileDescriptor profileFd = null;
4203            boolean profileAutoStop = false;
4204            if (mProfileApp != null && mProfileApp.equals(processName)) {
4205                mProfileProc = app;
4206                profileFile = mProfileFile;
4207                profileFd = mProfileFd;
4208                profileAutoStop = mAutoStopProfiler;
4209            }
4210            boolean enableOpenGlTrace = false;
4211            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4212                enableOpenGlTrace = true;
4213                mOpenGlTraceApp = null;
4214            }
4215
4216            // If the app is being launched for restore or full backup, set it up specially
4217            boolean isRestrictedBackupMode = false;
4218            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4219                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4220                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4221                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4222            }
4223
4224            ensurePackageDexOpt(app.instrumentationInfo != null
4225                    ? app.instrumentationInfo.packageName
4226                    : app.info.packageName);
4227            if (app.instrumentationClass != null) {
4228                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4229            }
4230            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4231                    + processName + " with config " + mConfiguration);
4232            ApplicationInfo appInfo = app.instrumentationInfo != null
4233                    ? app.instrumentationInfo : app.info;
4234            app.compat = compatibilityInfoForPackageLocked(appInfo);
4235            if (profileFd != null) {
4236                profileFd = profileFd.dup();
4237            }
4238            thread.bindApplication(processName, appInfo, providers,
4239                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4240                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4241                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4242                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4243                    mCoreSettingsObserver.getCoreSettingsLocked());
4244            updateLruProcessLocked(app, false, true);
4245            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4246        } catch (Exception e) {
4247            // todo: Yikes!  What should we do?  For now we will try to
4248            // start another process, but that could easily get us in
4249            // an infinite loop of restarting processes...
4250            Slog.w(TAG, "Exception thrown during bind!", e);
4251
4252            app.resetPackageList();
4253            app.unlinkDeathRecipient();
4254            startProcessLocked(app, "bind fail", processName);
4255            return false;
4256        }
4257
4258        // Remove this record from the list of starting applications.
4259        mPersistentStartingProcesses.remove(app);
4260        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4261                "Attach application locked removing on hold: " + app);
4262        mProcessesOnHold.remove(app);
4263
4264        boolean badApp = false;
4265        boolean didSomething = false;
4266
4267        // See if the top visible activity is waiting to run in this process...
4268        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4269        if (hr != null && normalMode) {
4270            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4271                    && processName.equals(hr.processName)) {
4272                try {
4273                    if (mHeadless) {
4274                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4275                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4276                        didSomething = true;
4277                    }
4278                } catch (Exception e) {
4279                    Slog.w(TAG, "Exception in new application when starting activity "
4280                          + hr.intent.getComponent().flattenToShortString(), e);
4281                    badApp = true;
4282                }
4283            } else {
4284                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4285            }
4286        }
4287
4288        // Find any services that should be running in this process...
4289        if (!badApp) {
4290            try {
4291                didSomething |= mServices.attachApplicationLocked(app, processName);
4292            } catch (Exception e) {
4293                badApp = true;
4294            }
4295        }
4296
4297        // Check if a next-broadcast receiver is in this process...
4298        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4299            try {
4300                didSomething = sendPendingBroadcastsLocked(app);
4301            } catch (Exception e) {
4302                // If the app died trying to launch the receiver we declare it 'bad'
4303                badApp = true;
4304            }
4305        }
4306
4307        // Check whether the next backup agent is in this process...
4308        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4309            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4310            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4311            try {
4312                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4313                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4314                        mBackupTarget.backupMode);
4315            } catch (Exception e) {
4316                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4317                e.printStackTrace();
4318            }
4319        }
4320
4321        if (badApp) {
4322            // todo: Also need to kill application to deal with all
4323            // kinds of exceptions.
4324            handleAppDiedLocked(app, false, true);
4325            return false;
4326        }
4327
4328        if (!didSomething) {
4329            updateOomAdjLocked();
4330        }
4331
4332        return true;
4333    }
4334
4335    public final void attachApplication(IApplicationThread thread) {
4336        synchronized (this) {
4337            int callingPid = Binder.getCallingPid();
4338            final long origId = Binder.clearCallingIdentity();
4339            attachApplicationLocked(thread, callingPid);
4340            Binder.restoreCallingIdentity(origId);
4341        }
4342    }
4343
4344    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4345        final long origId = Binder.clearCallingIdentity();
4346        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4347        if (stopProfiling) {
4348            synchronized (this) {
4349                if (mProfileProc == r.app) {
4350                    if (mProfileFd != null) {
4351                        try {
4352                            mProfileFd.close();
4353                        } catch (IOException e) {
4354                        }
4355                        clearProfilerLocked();
4356                    }
4357                }
4358            }
4359        }
4360        Binder.restoreCallingIdentity(origId);
4361    }
4362
4363    void enableScreenAfterBoot() {
4364        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4365                SystemClock.uptimeMillis());
4366        mWindowManager.enableScreenAfterBoot();
4367
4368        synchronized (this) {
4369            updateEventDispatchingLocked();
4370        }
4371    }
4372
4373    public void showBootMessage(final CharSequence msg, final boolean always) {
4374        enforceNotIsolatedCaller("showBootMessage");
4375        mWindowManager.showBootMessage(msg, always);
4376    }
4377
4378    public void dismissKeyguardOnNextActivity() {
4379        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4380        final long token = Binder.clearCallingIdentity();
4381        try {
4382            synchronized (this) {
4383                if (mLockScreenShown) {
4384                    mLockScreenShown = false;
4385                    comeOutOfSleepIfNeededLocked();
4386                }
4387                mMainStack.dismissKeyguardOnNextActivityLocked();
4388            }
4389        } finally {
4390            Binder.restoreCallingIdentity(token);
4391        }
4392    }
4393
4394    final void finishBooting() {
4395        IntentFilter pkgFilter = new IntentFilter();
4396        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4397        pkgFilter.addDataScheme("package");
4398        mContext.registerReceiver(new BroadcastReceiver() {
4399            @Override
4400            public void onReceive(Context context, Intent intent) {
4401                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4402                if (pkgs != null) {
4403                    for (String pkg : pkgs) {
4404                        synchronized (ActivityManagerService.this) {
4405                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4406                                setResultCode(Activity.RESULT_OK);
4407                                return;
4408                            }
4409                        }
4410                    }
4411                }
4412            }
4413        }, pkgFilter);
4414
4415        synchronized (this) {
4416            // Ensure that any processes we had put on hold are now started
4417            // up.
4418            final int NP = mProcessesOnHold.size();
4419            if (NP > 0) {
4420                ArrayList<ProcessRecord> procs =
4421                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4422                for (int ip=0; ip<NP; ip++) {
4423                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4424                            + procs.get(ip));
4425                    startProcessLocked(procs.get(ip), "on-hold", null);
4426                }
4427            }
4428
4429            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4430                // Start looking for apps that are abusing wake locks.
4431                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4432                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4433                // Tell anyone interested that we are done booting!
4434                SystemProperties.set("sys.boot_completed", "1");
4435                SystemProperties.set("dev.bootcomplete", "1");
4436                for (int i=0; i<mStartedUsers.size(); i++) {
4437                    UserStartedState uss = mStartedUsers.valueAt(i);
4438                    if (uss.mState == UserStartedState.STATE_BOOTING) {
4439                        uss.mState = UserStartedState.STATE_RUNNING;
4440                        final int userId = mStartedUsers.keyAt(i);
4441                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4442                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4443                        broadcastIntentLocked(null, null, intent,
4444                                null, null, 0, null, null,
4445                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4446                                false, false, MY_PID, Process.SYSTEM_UID, userId);
4447                    }
4448                }
4449            }
4450        }
4451    }
4452
4453    final void ensureBootCompleted() {
4454        boolean booting;
4455        boolean enableScreen;
4456        synchronized (this) {
4457            booting = mBooting;
4458            mBooting = false;
4459            enableScreen = !mBooted;
4460            mBooted = true;
4461        }
4462
4463        if (booting) {
4464            finishBooting();
4465        }
4466
4467        if (enableScreen) {
4468            enableScreenAfterBoot();
4469        }
4470    }
4471
4472    public final void activityResumed(IBinder token) {
4473        final long origId = Binder.clearCallingIdentity();
4474        mMainStack.activityResumed(token);
4475        Binder.restoreCallingIdentity(origId);
4476    }
4477
4478    public final void activityPaused(IBinder token) {
4479        final long origId = Binder.clearCallingIdentity();
4480        mMainStack.activityPaused(token, false);
4481        Binder.restoreCallingIdentity(origId);
4482    }
4483
4484    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4485            CharSequence description) {
4486        if (localLOGV) Slog.v(
4487            TAG, "Activity stopped: token=" + token);
4488
4489        // Refuse possible leaked file descriptors
4490        if (icicle != null && icicle.hasFileDescriptors()) {
4491            throw new IllegalArgumentException("File descriptors passed in Bundle");
4492        }
4493
4494        ActivityRecord r = null;
4495
4496        final long origId = Binder.clearCallingIdentity();
4497
4498        synchronized (this) {
4499            r = mMainStack.isInStackLocked(token);
4500            if (r != null) {
4501                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4502            }
4503        }
4504
4505        if (r != null) {
4506            sendPendingThumbnail(r, null, null, null, false);
4507        }
4508
4509        trimApplications();
4510
4511        Binder.restoreCallingIdentity(origId);
4512    }
4513
4514    public final void activityDestroyed(IBinder token) {
4515        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4516        mMainStack.activityDestroyed(token);
4517    }
4518
4519    public String getCallingPackage(IBinder token) {
4520        synchronized (this) {
4521            ActivityRecord r = getCallingRecordLocked(token);
4522            return r != null && r.app != null ? r.info.packageName : null;
4523        }
4524    }
4525
4526    public ComponentName getCallingActivity(IBinder token) {
4527        synchronized (this) {
4528            ActivityRecord r = getCallingRecordLocked(token);
4529            return r != null ? r.intent.getComponent() : null;
4530        }
4531    }
4532
4533    private ActivityRecord getCallingRecordLocked(IBinder token) {
4534        ActivityRecord r = mMainStack.isInStackLocked(token);
4535        if (r == null) {
4536            return null;
4537        }
4538        return r.resultTo;
4539    }
4540
4541    public ComponentName getActivityClassForToken(IBinder token) {
4542        synchronized(this) {
4543            ActivityRecord r = mMainStack.isInStackLocked(token);
4544            if (r == null) {
4545                return null;
4546            }
4547            return r.intent.getComponent();
4548        }
4549    }
4550
4551    public String getPackageForToken(IBinder token) {
4552        synchronized(this) {
4553            ActivityRecord r = mMainStack.isInStackLocked(token);
4554            if (r == null) {
4555                return null;
4556            }
4557            return r.packageName;
4558        }
4559    }
4560
4561    public IIntentSender getIntentSender(int type,
4562            String packageName, IBinder token, String resultWho,
4563            int requestCode, Intent[] intents, String[] resolvedTypes,
4564            int flags, Bundle options, int userId) {
4565        enforceNotIsolatedCaller("getIntentSender");
4566        // Refuse possible leaked file descriptors
4567        if (intents != null) {
4568            if (intents.length < 1) {
4569                throw new IllegalArgumentException("Intents array length must be >= 1");
4570            }
4571            for (int i=0; i<intents.length; i++) {
4572                Intent intent = intents[i];
4573                if (intent != null) {
4574                    if (intent.hasFileDescriptors()) {
4575                        throw new IllegalArgumentException("File descriptors passed in Intent");
4576                    }
4577                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4578                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4579                        throw new IllegalArgumentException(
4580                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4581                    }
4582                    intents[i] = new Intent(intent);
4583                }
4584            }
4585            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4586                throw new IllegalArgumentException(
4587                        "Intent array length does not match resolvedTypes length");
4588            }
4589        }
4590        if (options != null) {
4591            if (options.hasFileDescriptors()) {
4592                throw new IllegalArgumentException("File descriptors passed in options");
4593            }
4594        }
4595
4596        synchronized(this) {
4597            int callingUid = Binder.getCallingUid();
4598            int origUserId = userId;
4599            userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId,
4600                    type == ActivityManager.INTENT_SENDER_BROADCAST, true,
4601                    "getIntentSender", null);
4602            if (origUserId == UserHandle.USER_CURRENT) {
4603                // We don't want to evaluate this until the pending intent is
4604                // actually executed.  However, we do want to always do the
4605                // security checking for it above.
4606                userId = UserHandle.USER_CURRENT;
4607            }
4608            try {
4609                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4610                    int uid = AppGlobals.getPackageManager()
4611                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4612                    if (!UserHandle.isSameApp(callingUid, uid)) {
4613                        String msg = "Permission Denial: getIntentSender() from pid="
4614                            + Binder.getCallingPid()
4615                            + ", uid=" + Binder.getCallingUid()
4616                            + ", (need uid=" + uid + ")"
4617                            + " is not allowed to send as package " + packageName;
4618                        Slog.w(TAG, msg);
4619                        throw new SecurityException(msg);
4620                    }
4621                }
4622
4623                return getIntentSenderLocked(type, packageName, callingUid, userId,
4624                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4625
4626            } catch (RemoteException e) {
4627                throw new SecurityException(e);
4628            }
4629        }
4630    }
4631
4632    IIntentSender getIntentSenderLocked(int type, String packageName,
4633            int callingUid, int userId, IBinder token, String resultWho,
4634            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4635            Bundle options) {
4636        if (DEBUG_MU)
4637            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4638        ActivityRecord activity = null;
4639        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4640            activity = mMainStack.isInStackLocked(token);
4641            if (activity == null) {
4642                return null;
4643            }
4644            if (activity.finishing) {
4645                return null;
4646            }
4647        }
4648
4649        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4650        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4651        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4652        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4653                |PendingIntent.FLAG_UPDATE_CURRENT);
4654
4655        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4656                type, packageName, activity, resultWho,
4657                requestCode, intents, resolvedTypes, flags, options, userId);
4658        WeakReference<PendingIntentRecord> ref;
4659        ref = mIntentSenderRecords.get(key);
4660        PendingIntentRecord rec = ref != null ? ref.get() : null;
4661        if (rec != null) {
4662            if (!cancelCurrent) {
4663                if (updateCurrent) {
4664                    if (rec.key.requestIntent != null) {
4665                        rec.key.requestIntent.replaceExtras(intents != null ?
4666                                intents[intents.length - 1] : null);
4667                    }
4668                    if (intents != null) {
4669                        intents[intents.length-1] = rec.key.requestIntent;
4670                        rec.key.allIntents = intents;
4671                        rec.key.allResolvedTypes = resolvedTypes;
4672                    } else {
4673                        rec.key.allIntents = null;
4674                        rec.key.allResolvedTypes = null;
4675                    }
4676                }
4677                return rec;
4678            }
4679            rec.canceled = true;
4680            mIntentSenderRecords.remove(key);
4681        }
4682        if (noCreate) {
4683            return rec;
4684        }
4685        rec = new PendingIntentRecord(this, key, callingUid);
4686        mIntentSenderRecords.put(key, rec.ref);
4687        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4688            if (activity.pendingResults == null) {
4689                activity.pendingResults
4690                        = new HashSet<WeakReference<PendingIntentRecord>>();
4691            }
4692            activity.pendingResults.add(rec.ref);
4693        }
4694        return rec;
4695    }
4696
4697    public void cancelIntentSender(IIntentSender sender) {
4698        if (!(sender instanceof PendingIntentRecord)) {
4699            return;
4700        }
4701        synchronized(this) {
4702            PendingIntentRecord rec = (PendingIntentRecord)sender;
4703            try {
4704                int uid = AppGlobals.getPackageManager()
4705                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4706                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4707                    String msg = "Permission Denial: cancelIntentSender() from pid="
4708                        + Binder.getCallingPid()
4709                        + ", uid=" + Binder.getCallingUid()
4710                        + " is not allowed to cancel packges "
4711                        + rec.key.packageName;
4712                    Slog.w(TAG, msg);
4713                    throw new SecurityException(msg);
4714                }
4715            } catch (RemoteException e) {
4716                throw new SecurityException(e);
4717            }
4718            cancelIntentSenderLocked(rec, true);
4719        }
4720    }
4721
4722    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4723        rec.canceled = true;
4724        mIntentSenderRecords.remove(rec.key);
4725        if (cleanActivity && rec.key.activity != null) {
4726            rec.key.activity.pendingResults.remove(rec.ref);
4727        }
4728    }
4729
4730    public String getPackageForIntentSender(IIntentSender pendingResult) {
4731        if (!(pendingResult instanceof PendingIntentRecord)) {
4732            return null;
4733        }
4734        try {
4735            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4736            return res.key.packageName;
4737        } catch (ClassCastException e) {
4738        }
4739        return null;
4740    }
4741
4742    public int getUidForIntentSender(IIntentSender sender) {
4743        if (sender instanceof PendingIntentRecord) {
4744            try {
4745                PendingIntentRecord res = (PendingIntentRecord)sender;
4746                return res.uid;
4747            } catch (ClassCastException e) {
4748            }
4749        }
4750        return -1;
4751    }
4752
4753    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4754        if (!(pendingResult instanceof PendingIntentRecord)) {
4755            return false;
4756        }
4757        try {
4758            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4759            if (res.key.allIntents == null) {
4760                return false;
4761            }
4762            for (int i=0; i<res.key.allIntents.length; i++) {
4763                Intent intent = res.key.allIntents[i];
4764                if (intent.getPackage() != null && intent.getComponent() != null) {
4765                    return false;
4766                }
4767            }
4768            return true;
4769        } catch (ClassCastException e) {
4770        }
4771        return false;
4772    }
4773
4774    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4775        if (!(pendingResult instanceof PendingIntentRecord)) {
4776            return false;
4777        }
4778        try {
4779            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4780            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4781                return true;
4782            }
4783            return false;
4784        } catch (ClassCastException e) {
4785        }
4786        return false;
4787    }
4788
4789    public void setProcessLimit(int max) {
4790        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4791                "setProcessLimit()");
4792        synchronized (this) {
4793            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4794            mProcessLimitOverride = max;
4795        }
4796        trimApplications();
4797    }
4798
4799    public int getProcessLimit() {
4800        synchronized (this) {
4801            return mProcessLimitOverride;
4802        }
4803    }
4804
4805    void foregroundTokenDied(ForegroundToken token) {
4806        synchronized (ActivityManagerService.this) {
4807            synchronized (mPidsSelfLocked) {
4808                ForegroundToken cur
4809                    = mForegroundProcesses.get(token.pid);
4810                if (cur != token) {
4811                    return;
4812                }
4813                mForegroundProcesses.remove(token.pid);
4814                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4815                if (pr == null) {
4816                    return;
4817                }
4818                pr.forcingToForeground = null;
4819                pr.foregroundServices = false;
4820            }
4821            updateOomAdjLocked();
4822        }
4823    }
4824
4825    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4826        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4827                "setProcessForeground()");
4828        synchronized(this) {
4829            boolean changed = false;
4830
4831            synchronized (mPidsSelfLocked) {
4832                ProcessRecord pr = mPidsSelfLocked.get(pid);
4833                if (pr == null && isForeground) {
4834                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4835                    return;
4836                }
4837                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4838                if (oldToken != null) {
4839                    oldToken.token.unlinkToDeath(oldToken, 0);
4840                    mForegroundProcesses.remove(pid);
4841                    if (pr != null) {
4842                        pr.forcingToForeground = null;
4843                    }
4844                    changed = true;
4845                }
4846                if (isForeground && token != null) {
4847                    ForegroundToken newToken = new ForegroundToken() {
4848                        public void binderDied() {
4849                            foregroundTokenDied(this);
4850                        }
4851                    };
4852                    newToken.pid = pid;
4853                    newToken.token = token;
4854                    try {
4855                        token.linkToDeath(newToken, 0);
4856                        mForegroundProcesses.put(pid, newToken);
4857                        pr.forcingToForeground = token;
4858                        changed = true;
4859                    } catch (RemoteException e) {
4860                        // If the process died while doing this, we will later
4861                        // do the cleanup with the process death link.
4862                    }
4863                }
4864            }
4865
4866            if (changed) {
4867                updateOomAdjLocked();
4868            }
4869        }
4870    }
4871
4872    // =========================================================
4873    // PERMISSIONS
4874    // =========================================================
4875
4876    static class PermissionController extends IPermissionController.Stub {
4877        ActivityManagerService mActivityManagerService;
4878        PermissionController(ActivityManagerService activityManagerService) {
4879            mActivityManagerService = activityManagerService;
4880        }
4881
4882        public boolean checkPermission(String permission, int pid, int uid) {
4883            return mActivityManagerService.checkPermission(permission, pid,
4884                    uid) == PackageManager.PERMISSION_GRANTED;
4885        }
4886    }
4887
4888    /**
4889     * This can be called with or without the global lock held.
4890     */
4891    int checkComponentPermission(String permission, int pid, int uid,
4892            int owningUid, boolean exported) {
4893        // We might be performing an operation on behalf of an indirect binder
4894        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4895        // client identity accordingly before proceeding.
4896        Identity tlsIdentity = sCallerIdentity.get();
4897        if (tlsIdentity != null) {
4898            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4899                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4900            uid = tlsIdentity.uid;
4901            pid = tlsIdentity.pid;
4902        }
4903
4904        if (pid == MY_PID) {
4905            return PackageManager.PERMISSION_GRANTED;
4906        }
4907
4908        return ActivityManager.checkComponentPermission(permission, uid,
4909                owningUid, exported);
4910    }
4911
4912    /**
4913     * As the only public entry point for permissions checking, this method
4914     * can enforce the semantic that requesting a check on a null global
4915     * permission is automatically denied.  (Internally a null permission
4916     * string is used when calling {@link #checkComponentPermission} in cases
4917     * when only uid-based security is needed.)
4918     *
4919     * This can be called with or without the global lock held.
4920     */
4921    public int checkPermission(String permission, int pid, int uid) {
4922        if (permission == null) {
4923            return PackageManager.PERMISSION_DENIED;
4924        }
4925        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4926    }
4927
4928    /**
4929     * Binder IPC calls go through the public entry point.
4930     * This can be called with or without the global lock held.
4931     */
4932    int checkCallingPermission(String permission) {
4933        return checkPermission(permission,
4934                Binder.getCallingPid(),
4935                UserHandle.getAppId(Binder.getCallingUid()));
4936    }
4937
4938    /**
4939     * This can be called with or without the global lock held.
4940     */
4941    void enforceCallingPermission(String permission, String func) {
4942        if (checkCallingPermission(permission)
4943                == PackageManager.PERMISSION_GRANTED) {
4944            return;
4945        }
4946
4947        String msg = "Permission Denial: " + func + " from pid="
4948                + Binder.getCallingPid()
4949                + ", uid=" + Binder.getCallingUid()
4950                + " requires " + permission;
4951        Slog.w(TAG, msg);
4952        throw new SecurityException(msg);
4953    }
4954
4955    /**
4956     * Determine if UID is holding permissions required to access {@link Uri} in
4957     * the given {@link ProviderInfo}. Final permission checking is always done
4958     * in {@link ContentProvider}.
4959     */
4960    private final boolean checkHoldingPermissionsLocked(
4961            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4962        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4963                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4964
4965        if (pi.applicationInfo.uid == uid) {
4966            return true;
4967        } else if (!pi.exported) {
4968            return false;
4969        }
4970
4971        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4972        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4973        try {
4974            // check if target holds top-level <provider> permissions
4975            if (!readMet && pi.readPermission != null
4976                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4977                readMet = true;
4978            }
4979            if (!writeMet && pi.writePermission != null
4980                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4981                writeMet = true;
4982            }
4983
4984            // track if unprotected read/write is allowed; any denied
4985            // <path-permission> below removes this ability
4986            boolean allowDefaultRead = pi.readPermission == null;
4987            boolean allowDefaultWrite = pi.writePermission == null;
4988
4989            // check if target holds any <path-permission> that match uri
4990            final PathPermission[] pps = pi.pathPermissions;
4991            if (pps != null) {
4992                final String path = uri.getPath();
4993                int i = pps.length;
4994                while (i > 0 && (!readMet || !writeMet)) {
4995                    i--;
4996                    PathPermission pp = pps[i];
4997                    if (pp.match(path)) {
4998                        if (!readMet) {
4999                            final String pprperm = pp.getReadPermission();
5000                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5001                                    + pprperm + " for " + pp.getPath()
5002                                    + ": match=" + pp.match(path)
5003                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5004                            if (pprperm != null) {
5005                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5006                                    readMet = true;
5007                                } else {
5008                                    allowDefaultRead = false;
5009                                }
5010                            }
5011                        }
5012                        if (!writeMet) {
5013                            final String ppwperm = pp.getWritePermission();
5014                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5015                                    + ppwperm + " for " + pp.getPath()
5016                                    + ": match=" + pp.match(path)
5017                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5018                            if (ppwperm != null) {
5019                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5020                                    writeMet = true;
5021                                } else {
5022                                    allowDefaultWrite = false;
5023                                }
5024                            }
5025                        }
5026                    }
5027                }
5028            }
5029
5030            // grant unprotected <provider> read/write, if not blocked by
5031            // <path-permission> above
5032            if (allowDefaultRead) readMet = true;
5033            if (allowDefaultWrite) writeMet = true;
5034
5035        } catch (RemoteException e) {
5036            return false;
5037        }
5038
5039        return readMet && writeMet;
5040    }
5041
5042    private final boolean checkUriPermissionLocked(Uri uri, int uid,
5043            int modeFlags) {
5044        // Root gets to do everything.
5045        if (uid == 0) {
5046            return true;
5047        }
5048        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5049        if (perms == null) return false;
5050        UriPermission perm = perms.get(uri);
5051        if (perm == null) return false;
5052        return (modeFlags&perm.modeFlags) == modeFlags;
5053    }
5054
5055    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5056        enforceNotIsolatedCaller("checkUriPermission");
5057
5058        // Another redirected-binder-call permissions check as in
5059        // {@link checkComponentPermission}.
5060        Identity tlsIdentity = sCallerIdentity.get();
5061        if (tlsIdentity != null) {
5062            uid = tlsIdentity.uid;
5063            pid = tlsIdentity.pid;
5064        }
5065
5066        // Our own process gets to do everything.
5067        if (pid == MY_PID) {
5068            return PackageManager.PERMISSION_GRANTED;
5069        }
5070        synchronized(this) {
5071            return checkUriPermissionLocked(uri, uid, modeFlags)
5072                    ? PackageManager.PERMISSION_GRANTED
5073                    : PackageManager.PERMISSION_DENIED;
5074        }
5075    }
5076
5077    /**
5078     * Check if the targetPkg can be granted permission to access uri by
5079     * the callingUid using the given modeFlags.  Throws a security exception
5080     * if callingUid is not allowed to do this.  Returns the uid of the target
5081     * if the URI permission grant should be performed; returns -1 if it is not
5082     * needed (for example targetPkg already has permission to access the URI).
5083     * If you already know the uid of the target, you can supply it in
5084     * lastTargetUid else set that to -1.
5085     */
5086    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5087            Uri uri, int modeFlags, int lastTargetUid) {
5088        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5089                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5090        if (modeFlags == 0) {
5091            return -1;
5092        }
5093
5094        if (targetPkg != null) {
5095            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5096                    "Checking grant " + targetPkg + " permission to " + uri);
5097        }
5098
5099        final IPackageManager pm = AppGlobals.getPackageManager();
5100
5101        // If this is not a content: uri, we can't do anything with it.
5102        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5103            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5104                    "Can't grant URI permission for non-content URI: " + uri);
5105            return -1;
5106        }
5107
5108        String name = uri.getAuthority();
5109        ProviderInfo pi = null;
5110        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5111                UserHandle.getUserId(callingUid));
5112        if (cpr != null) {
5113            pi = cpr.info;
5114        } else {
5115            try {
5116                pi = pm.resolveContentProvider(name,
5117                        PackageManager.GET_URI_PERMISSION_PATTERNS,
5118                        UserHandle.getUserId(callingUid));
5119            } catch (RemoteException ex) {
5120            }
5121        }
5122        if (pi == null) {
5123            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5124            return -1;
5125        }
5126
5127        int targetUid = lastTargetUid;
5128        if (targetUid < 0 && targetPkg != null) {
5129            try {
5130                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5131                if (targetUid < 0) {
5132                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5133                            "Can't grant URI permission no uid for: " + targetPkg);
5134                    return -1;
5135                }
5136            } catch (RemoteException ex) {
5137                return -1;
5138            }
5139        }
5140
5141        if (targetUid >= 0) {
5142            // First...  does the target actually need this permission?
5143            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5144                // No need to grant the target this permission.
5145                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5146                        "Target " + targetPkg + " already has full permission to " + uri);
5147                return -1;
5148            }
5149        } else {
5150            // First...  there is no target package, so can anyone access it?
5151            boolean allowed = pi.exported;
5152            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5153                if (pi.readPermission != null) {
5154                    allowed = false;
5155                }
5156            }
5157            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5158                if (pi.writePermission != null) {
5159                    allowed = false;
5160                }
5161            }
5162            if (allowed) {
5163                return -1;
5164            }
5165        }
5166
5167        // Second...  is the provider allowing granting of URI permissions?
5168        if (!pi.grantUriPermissions) {
5169            throw new SecurityException("Provider " + pi.packageName
5170                    + "/" + pi.name
5171                    + " does not allow granting of Uri permissions (uri "
5172                    + uri + ")");
5173        }
5174        if (pi.uriPermissionPatterns != null) {
5175            final int N = pi.uriPermissionPatterns.length;
5176            boolean allowed = false;
5177            for (int i=0; i<N; i++) {
5178                if (pi.uriPermissionPatterns[i] != null
5179                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5180                    allowed = true;
5181                    break;
5182                }
5183            }
5184            if (!allowed) {
5185                throw new SecurityException("Provider " + pi.packageName
5186                        + "/" + pi.name
5187                        + " does not allow granting of permission to path of Uri "
5188                        + uri);
5189            }
5190        }
5191
5192        // Third...  does the caller itself have permission to access
5193        // this uri?
5194        if (callingUid != Process.myUid()) {
5195            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5196                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5197                    throw new SecurityException("Uid " + callingUid
5198                            + " does not have permission to uri " + uri);
5199                }
5200            }
5201        }
5202
5203        return targetUid;
5204    }
5205
5206    public int checkGrantUriPermission(int callingUid, String targetPkg,
5207            Uri uri, int modeFlags) {
5208        enforceNotIsolatedCaller("checkGrantUriPermission");
5209        synchronized(this) {
5210            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5211        }
5212    }
5213
5214    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5215            Uri uri, int modeFlags, UriPermissionOwner owner) {
5216        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5217                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5218        if (modeFlags == 0) {
5219            return;
5220        }
5221
5222        // So here we are: the caller has the assumed permission
5223        // to the uri, and the target doesn't.  Let's now give this to
5224        // the target.
5225
5226        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5227                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5228
5229        HashMap<Uri, UriPermission> targetUris
5230                = mGrantedUriPermissions.get(targetUid);
5231        if (targetUris == null) {
5232            targetUris = new HashMap<Uri, UriPermission>();
5233            mGrantedUriPermissions.put(targetUid, targetUris);
5234        }
5235
5236        UriPermission perm = targetUris.get(uri);
5237        if (perm == null) {
5238            perm = new UriPermission(targetUid, uri);
5239            targetUris.put(uri, perm);
5240        }
5241
5242        perm.modeFlags |= modeFlags;
5243        if (owner == null) {
5244            perm.globalModeFlags |= modeFlags;
5245        } else {
5246            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5247                 perm.readOwners.add(owner);
5248                 owner.addReadPermission(perm);
5249            }
5250            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5251                 perm.writeOwners.add(owner);
5252                 owner.addWritePermission(perm);
5253            }
5254        }
5255    }
5256
5257    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5258            int modeFlags, UriPermissionOwner owner) {
5259        if (targetPkg == null) {
5260            throw new NullPointerException("targetPkg");
5261        }
5262
5263        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5264        if (targetUid < 0) {
5265            return;
5266        }
5267
5268        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5269    }
5270
5271    static class NeededUriGrants extends ArrayList<Uri> {
5272        final String targetPkg;
5273        final int targetUid;
5274        final int flags;
5275
5276        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5277            targetPkg = _targetPkg;
5278            targetUid = _targetUid;
5279            flags = _flags;
5280        }
5281    }
5282
5283    /**
5284     * Like checkGrantUriPermissionLocked, but takes an Intent.
5285     */
5286    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5287            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5288        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5289                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5290                + " clip=" + (intent != null ? intent.getClipData() : null)
5291                + " from " + intent + "; flags=0x"
5292                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5293
5294        if (targetPkg == null) {
5295            throw new NullPointerException("targetPkg");
5296        }
5297
5298        if (intent == null) {
5299            return null;
5300        }
5301        Uri data = intent.getData();
5302        ClipData clip = intent.getClipData();
5303        if (data == null && clip == null) {
5304            return null;
5305        }
5306        if (data != null) {
5307            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5308                mode, needed != null ? needed.targetUid : -1);
5309            if (target > 0) {
5310                if (needed == null) {
5311                    needed = new NeededUriGrants(targetPkg, target, mode);
5312                }
5313                needed.add(data);
5314            }
5315        }
5316        if (clip != null) {
5317            for (int i=0; i<clip.getItemCount(); i++) {
5318                Uri uri = clip.getItemAt(i).getUri();
5319                if (uri != null) {
5320                    int target = -1;
5321                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5322                            mode, needed != null ? needed.targetUid : -1);
5323                    if (target > 0) {
5324                        if (needed == null) {
5325                            needed = new NeededUriGrants(targetPkg, target, mode);
5326                        }
5327                        needed.add(uri);
5328                    }
5329                } else {
5330                    Intent clipIntent = clip.getItemAt(i).getIntent();
5331                    if (clipIntent != null) {
5332                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5333                                callingUid, targetPkg, clipIntent, mode, needed);
5334                        if (newNeeded != null) {
5335                            needed = newNeeded;
5336                        }
5337                    }
5338                }
5339            }
5340        }
5341
5342        return needed;
5343    }
5344
5345    /**
5346     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5347     */
5348    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5349            UriPermissionOwner owner) {
5350        if (needed != null) {
5351            for (int i=0; i<needed.size(); i++) {
5352                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5353                        needed.get(i), needed.flags, owner);
5354            }
5355        }
5356    }
5357
5358    void grantUriPermissionFromIntentLocked(int callingUid,
5359            String targetPkg, Intent intent, UriPermissionOwner owner) {
5360        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5361                intent, intent != null ? intent.getFlags() : 0, null);
5362        if (needed == null) {
5363            return;
5364        }
5365
5366        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5367    }
5368
5369    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5370            Uri uri, int modeFlags) {
5371        enforceNotIsolatedCaller("grantUriPermission");
5372        synchronized(this) {
5373            final ProcessRecord r = getRecordForAppLocked(caller);
5374            if (r == null) {
5375                throw new SecurityException("Unable to find app for caller "
5376                        + caller
5377                        + " when granting permission to uri " + uri);
5378            }
5379            if (targetPkg == null) {
5380                throw new IllegalArgumentException("null target");
5381            }
5382            if (uri == null) {
5383                throw new IllegalArgumentException("null uri");
5384            }
5385
5386            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5387                    null);
5388        }
5389    }
5390
5391    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5392        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5393                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5394            HashMap<Uri, UriPermission> perms
5395                    = mGrantedUriPermissions.get(perm.uid);
5396            if (perms != null) {
5397                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5398                        "Removing " + perm.uid + " permission to " + perm.uri);
5399                perms.remove(perm.uri);
5400                if (perms.size() == 0) {
5401                    mGrantedUriPermissions.remove(perm.uid);
5402                }
5403            }
5404        }
5405    }
5406
5407    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5408            int modeFlags) {
5409        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5410                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5411        if (modeFlags == 0) {
5412            return;
5413        }
5414
5415        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5416                "Revoking all granted permissions to " + uri);
5417
5418        final IPackageManager pm = AppGlobals.getPackageManager();
5419
5420        final String authority = uri.getAuthority();
5421        ProviderInfo pi = null;
5422        int userId = UserHandle.getUserId(callingUid);
5423        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5424        if (cpr != null) {
5425            pi = cpr.info;
5426        } else {
5427            try {
5428                pi = pm.resolveContentProvider(authority,
5429                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5430            } catch (RemoteException ex) {
5431            }
5432        }
5433        if (pi == null) {
5434            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5435            return;
5436        }
5437
5438        // Does the caller have this permission on the URI?
5439        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5440            // Right now, if you are not the original owner of the permission,
5441            // you are not allowed to revoke it.
5442            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5443                throw new SecurityException("Uid " + callingUid
5444                        + " does not have permission to uri " + uri);
5445            //}
5446        }
5447
5448        // Go through all of the permissions and remove any that match.
5449        final List<String> SEGMENTS = uri.getPathSegments();
5450        if (SEGMENTS != null) {
5451            final int NS = SEGMENTS.size();
5452            int N = mGrantedUriPermissions.size();
5453            for (int i=0; i<N; i++) {
5454                HashMap<Uri, UriPermission> perms
5455                        = mGrantedUriPermissions.valueAt(i);
5456                Iterator<UriPermission> it = perms.values().iterator();
5457            toploop:
5458                while (it.hasNext()) {
5459                    UriPermission perm = it.next();
5460                    Uri targetUri = perm.uri;
5461                    if (!authority.equals(targetUri.getAuthority())) {
5462                        continue;
5463                    }
5464                    List<String> targetSegments = targetUri.getPathSegments();
5465                    if (targetSegments == null) {
5466                        continue;
5467                    }
5468                    if (targetSegments.size() < NS) {
5469                        continue;
5470                    }
5471                    for (int j=0; j<NS; j++) {
5472                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5473                            continue toploop;
5474                        }
5475                    }
5476                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5477                            "Revoking " + perm.uid + " permission to " + perm.uri);
5478                    perm.clearModes(modeFlags);
5479                    if (perm.modeFlags == 0) {
5480                        it.remove();
5481                    }
5482                }
5483                if (perms.size() == 0) {
5484                    mGrantedUriPermissions.remove(
5485                            mGrantedUriPermissions.keyAt(i));
5486                    N--;
5487                    i--;
5488                }
5489            }
5490        }
5491    }
5492
5493    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5494            int modeFlags) {
5495        enforceNotIsolatedCaller("revokeUriPermission");
5496        synchronized(this) {
5497            final ProcessRecord r = getRecordForAppLocked(caller);
5498            if (r == null) {
5499                throw new SecurityException("Unable to find app for caller "
5500                        + caller
5501                        + " when revoking permission to uri " + uri);
5502            }
5503            if (uri == null) {
5504                Slog.w(TAG, "revokeUriPermission: null uri");
5505                return;
5506            }
5507
5508            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5509                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5510            if (modeFlags == 0) {
5511                return;
5512            }
5513
5514            final IPackageManager pm = AppGlobals.getPackageManager();
5515
5516            final String authority = uri.getAuthority();
5517            ProviderInfo pi = null;
5518            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5519            if (cpr != null) {
5520                pi = cpr.info;
5521            } else {
5522                try {
5523                    pi = pm.resolveContentProvider(authority,
5524                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5525                } catch (RemoteException ex) {
5526                }
5527            }
5528            if (pi == null) {
5529                Slog.w(TAG, "No content provider found for permission revoke: "
5530                        + uri.toSafeString());
5531                return;
5532            }
5533
5534            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5535        }
5536    }
5537
5538    @Override
5539    public IBinder newUriPermissionOwner(String name) {
5540        enforceNotIsolatedCaller("newUriPermissionOwner");
5541        synchronized(this) {
5542            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5543            return owner.getExternalTokenLocked();
5544        }
5545    }
5546
5547    @Override
5548    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5549            Uri uri, int modeFlags) {
5550        synchronized(this) {
5551            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5552            if (owner == null) {
5553                throw new IllegalArgumentException("Unknown owner: " + token);
5554            }
5555            if (fromUid != Binder.getCallingUid()) {
5556                if (Binder.getCallingUid() != Process.myUid()) {
5557                    // Only system code can grant URI permissions on behalf
5558                    // of other users.
5559                    throw new SecurityException("nice try");
5560                }
5561            }
5562            if (targetPkg == null) {
5563                throw new IllegalArgumentException("null target");
5564            }
5565            if (uri == null) {
5566                throw new IllegalArgumentException("null uri");
5567            }
5568
5569            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5570        }
5571    }
5572
5573    @Override
5574    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5575        synchronized(this) {
5576            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5577            if (owner == null) {
5578                throw new IllegalArgumentException("Unknown owner: " + token);
5579            }
5580
5581            if (uri == null) {
5582                owner.removeUriPermissionsLocked(mode);
5583            } else {
5584                owner.removeUriPermissionLocked(uri, mode);
5585            }
5586        }
5587    }
5588
5589    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5590        synchronized (this) {
5591            ProcessRecord app =
5592                who != null ? getRecordForAppLocked(who) : null;
5593            if (app == null) return;
5594
5595            Message msg = Message.obtain();
5596            msg.what = WAIT_FOR_DEBUGGER_MSG;
5597            msg.obj = app;
5598            msg.arg1 = waiting ? 1 : 0;
5599            mHandler.sendMessage(msg);
5600        }
5601    }
5602
5603    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5604        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5605        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5606        outInfo.availMem = Process.getFreeMemory();
5607        outInfo.totalMem = Process.getTotalMemory();
5608        outInfo.threshold = homeAppMem;
5609        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5610        outInfo.hiddenAppThreshold = hiddenAppMem;
5611        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5612                ProcessList.SERVICE_ADJ);
5613        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5614                ProcessList.VISIBLE_APP_ADJ);
5615        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5616                ProcessList.FOREGROUND_APP_ADJ);
5617    }
5618
5619    // =========================================================
5620    // TASK MANAGEMENT
5621    // =========================================================
5622
5623    public List getTasks(int maxNum, int flags,
5624                         IThumbnailReceiver receiver) {
5625        ArrayList list = new ArrayList();
5626
5627        PendingThumbnailsRecord pending = null;
5628        IApplicationThread topThumbnail = null;
5629        ActivityRecord topRecord = null;
5630
5631        synchronized(this) {
5632            if (localLOGV) Slog.v(
5633                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5634                + ", receiver=" + receiver);
5635
5636            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5637                    != PackageManager.PERMISSION_GRANTED) {
5638                if (receiver != null) {
5639                    // If the caller wants to wait for pending thumbnails,
5640                    // it ain't gonna get them.
5641                    try {
5642                        receiver.finished();
5643                    } catch (RemoteException ex) {
5644                    }
5645                }
5646                String msg = "Permission Denial: getTasks() from pid="
5647                        + Binder.getCallingPid()
5648                        + ", uid=" + Binder.getCallingUid()
5649                        + " requires " + android.Manifest.permission.GET_TASKS;
5650                Slog.w(TAG, msg);
5651                throw new SecurityException(msg);
5652            }
5653
5654            int pos = mMainStack.mHistory.size()-1;
5655            ActivityRecord next =
5656                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5657            ActivityRecord top = null;
5658            TaskRecord curTask = null;
5659            int numActivities = 0;
5660            int numRunning = 0;
5661            while (pos >= 0 && maxNum > 0) {
5662                final ActivityRecord r = next;
5663                pos--;
5664                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5665
5666                // Initialize state for next task if needed.
5667                if (top == null ||
5668                        (top.state == ActivityState.INITIALIZING
5669                            && top.task == r.task)) {
5670                    top = r;
5671                    curTask = r.task;
5672                    numActivities = numRunning = 0;
5673                }
5674
5675                // Add 'r' into the current task.
5676                numActivities++;
5677                if (r.app != null && r.app.thread != null) {
5678                    numRunning++;
5679                }
5680
5681                if (localLOGV) Slog.v(
5682                    TAG, r.intent.getComponent().flattenToShortString()
5683                    + ": task=" + r.task);
5684
5685                // If the next one is a different task, generate a new
5686                // TaskInfo entry for what we have.
5687                if (next == null || next.task != curTask) {
5688                    ActivityManager.RunningTaskInfo ci
5689                            = new ActivityManager.RunningTaskInfo();
5690                    ci.id = curTask.taskId;
5691                    ci.baseActivity = r.intent.getComponent();
5692                    ci.topActivity = top.intent.getComponent();
5693                    if (top.thumbHolder != null) {
5694                        ci.description = top.thumbHolder.lastDescription;
5695                    }
5696                    ci.numActivities = numActivities;
5697                    ci.numRunning = numRunning;
5698                    //System.out.println(
5699                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5700                    if (ci.thumbnail == null && receiver != null) {
5701                        if (localLOGV) Slog.v(
5702                            TAG, "State=" + top.state + "Idle=" + top.idle
5703                            + " app=" + top.app
5704                            + " thr=" + (top.app != null ? top.app.thread : null));
5705                        if (top.state == ActivityState.RESUMED
5706                                || top.state == ActivityState.PAUSING) {
5707                            if (top.idle && top.app != null
5708                                && top.app.thread != null) {
5709                                topRecord = top;
5710                                topThumbnail = top.app.thread;
5711                            } else {
5712                                top.thumbnailNeeded = true;
5713                            }
5714                        }
5715                        if (pending == null) {
5716                            pending = new PendingThumbnailsRecord(receiver);
5717                        }
5718                        pending.pendingRecords.add(top);
5719                    }
5720                    list.add(ci);
5721                    maxNum--;
5722                    top = null;
5723                }
5724            }
5725
5726            if (pending != null) {
5727                mPendingThumbnails.add(pending);
5728            }
5729        }
5730
5731        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5732
5733        if (topThumbnail != null) {
5734            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5735            try {
5736                topThumbnail.requestThumbnail(topRecord.appToken);
5737            } catch (Exception e) {
5738                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5739                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5740            }
5741        }
5742
5743        if (pending == null && receiver != null) {
5744            // In this case all thumbnails were available and the client
5745            // is being asked to be told when the remaining ones come in...
5746            // which is unusually, since the top-most currently running
5747            // activity should never have a canned thumbnail!  Oh well.
5748            try {
5749                receiver.finished();
5750            } catch (RemoteException ex) {
5751            }
5752        }
5753
5754        return list;
5755    }
5756
5757    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5758            int flags, int userId) {
5759        final int callingUid = Binder.getCallingUid();
5760        if (userId != UserHandle.getCallingUserId()) {
5761            // Check if the caller is holding permissions for cross-user requests.
5762            if (checkComponentPermission(
5763                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5764                    Binder.getCallingPid(), callingUid, -1, true)
5765                    != PackageManager.PERMISSION_GRANTED) {
5766                String msg = "Permission Denial: "
5767                        + "Request to get recent tasks for user " + userId
5768                        + " but is calling from user " + UserHandle.getUserId(callingUid)
5769                        + "; this requires "
5770                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5771                Slog.w(TAG, msg);
5772                throw new SecurityException(msg);
5773            } else {
5774                if (userId == UserHandle.USER_CURRENT) {
5775                    userId = mCurrentUserId;
5776                }
5777            }
5778        }
5779
5780        synchronized (this) {
5781            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5782                    "getRecentTasks()");
5783            final boolean detailed = checkCallingPermission(
5784                    android.Manifest.permission.GET_DETAILED_TASKS)
5785                    == PackageManager.PERMISSION_GRANTED;
5786
5787            IPackageManager pm = AppGlobals.getPackageManager();
5788
5789            final int N = mRecentTasks.size();
5790            ArrayList<ActivityManager.RecentTaskInfo> res
5791                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5792                            maxNum < N ? maxNum : N);
5793            for (int i=0; i<N && maxNum > 0; i++) {
5794                TaskRecord tr = mRecentTasks.get(i);
5795                // Only add calling user's recent tasks
5796                if (tr.userId != userId) continue;
5797                // Return the entry if desired by the caller.  We always return
5798                // the first entry, because callers always expect this to be the
5799                // foreground app.  We may filter others if the caller has
5800                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5801                // we should exclude the entry.
5802
5803                if (i == 0
5804                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5805                        || (tr.intent == null)
5806                        || ((tr.intent.getFlags()
5807                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5808                    ActivityManager.RecentTaskInfo rti
5809                            = new ActivityManager.RecentTaskInfo();
5810                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5811                    rti.persistentId = tr.taskId;
5812                    rti.baseIntent = new Intent(
5813                            tr.intent != null ? tr.intent : tr.affinityIntent);
5814                    if (!detailed) {
5815                        rti.baseIntent.replaceExtras((Bundle)null);
5816                    }
5817                    rti.origActivity = tr.origActivity;
5818                    rti.description = tr.lastDescription;
5819
5820                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5821                        // Check whether this activity is currently available.
5822                        try {
5823                            if (rti.origActivity != null) {
5824                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5825                                        == null) {
5826                                    continue;
5827                                }
5828                            } else if (rti.baseIntent != null) {
5829                                if (pm.queryIntentActivities(rti.baseIntent,
5830                                        null, 0, userId) == null) {
5831                                    continue;
5832                                }
5833                            }
5834                        } catch (RemoteException e) {
5835                            // Will never happen.
5836                        }
5837                    }
5838
5839                    res.add(rti);
5840                    maxNum--;
5841                }
5842            }
5843            return res;
5844        }
5845    }
5846
5847    private TaskRecord taskForIdLocked(int id) {
5848        final int N = mRecentTasks.size();
5849        for (int i=0; i<N; i++) {
5850            TaskRecord tr = mRecentTasks.get(i);
5851            if (tr.taskId == id) {
5852                return tr;
5853            }
5854        }
5855        return null;
5856    }
5857
5858    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5859        synchronized (this) {
5860            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5861                    "getTaskThumbnails()");
5862            TaskRecord tr = taskForIdLocked(id);
5863            if (tr != null) {
5864                return mMainStack.getTaskThumbnailsLocked(tr);
5865            }
5866        }
5867        return null;
5868    }
5869
5870    public Bitmap getTaskTopThumbnail(int id) {
5871        synchronized (this) {
5872            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5873                    "getTaskTopThumbnail()");
5874            TaskRecord tr = taskForIdLocked(id);
5875            if (tr != null) {
5876                return mMainStack.getTaskTopThumbnailLocked(tr);
5877            }
5878        }
5879        return null;
5880    }
5881
5882    public boolean removeSubTask(int taskId, int subTaskIndex) {
5883        synchronized (this) {
5884            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5885                    "removeSubTask()");
5886            long ident = Binder.clearCallingIdentity();
5887            try {
5888                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5889                        true) != null;
5890            } finally {
5891                Binder.restoreCallingIdentity(ident);
5892            }
5893        }
5894    }
5895
5896    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5897        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5898        Intent baseIntent = new Intent(
5899                tr.intent != null ? tr.intent : tr.affinityIntent);
5900        ComponentName component = baseIntent.getComponent();
5901        if (component == null) {
5902            Slog.w(TAG, "Now component for base intent of task: " + tr);
5903            return;
5904        }
5905
5906        // Find any running services associated with this app.
5907        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5908
5909        if (killProcesses) {
5910            // Find any running processes associated with this app.
5911            final String pkg = component.getPackageName();
5912            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5913            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5914            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5915                for (int i=0; i<uids.size(); i++) {
5916                    ProcessRecord proc = uids.valueAt(i);
5917                    if (proc.userId != tr.userId) {
5918                        continue;
5919                    }
5920                    if (!proc.pkgList.contains(pkg)) {
5921                        continue;
5922                    }
5923                    procs.add(proc);
5924                }
5925            }
5926
5927            // Kill the running processes.
5928            for (int i=0; i<procs.size(); i++) {
5929                ProcessRecord pr = procs.get(i);
5930                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5931                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5932                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5933                            pr.processName, pr.setAdj, "remove task");
5934                    pr.killedBackground = true;
5935                    Process.killProcessQuiet(pr.pid);
5936                } else {
5937                    pr.waitingToKill = "remove task";
5938                }
5939            }
5940        }
5941    }
5942
5943    public boolean removeTask(int taskId, int flags) {
5944        synchronized (this) {
5945            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5946                    "removeTask()");
5947            long ident = Binder.clearCallingIdentity();
5948            try {
5949                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5950                        false);
5951                if (r != null) {
5952                    mRecentTasks.remove(r.task);
5953                    cleanUpRemovedTaskLocked(r.task, flags);
5954                    return true;
5955                } else {
5956                    TaskRecord tr = null;
5957                    int i=0;
5958                    while (i < mRecentTasks.size()) {
5959                        TaskRecord t = mRecentTasks.get(i);
5960                        if (t.taskId == taskId) {
5961                            tr = t;
5962                            break;
5963                        }
5964                        i++;
5965                    }
5966                    if (tr != null) {
5967                        if (tr.numActivities <= 0) {
5968                            // Caller is just removing a recent task that is
5969                            // not actively running.  That is easy!
5970                            mRecentTasks.remove(i);
5971                            cleanUpRemovedTaskLocked(tr, flags);
5972                            return true;
5973                        } else {
5974                            Slog.w(TAG, "removeTask: task " + taskId
5975                                    + " does not have activities to remove, "
5976                                    + " but numActivities=" + tr.numActivities
5977                                    + ": " + tr);
5978                        }
5979                    }
5980                }
5981            } finally {
5982                Binder.restoreCallingIdentity(ident);
5983            }
5984        }
5985        return false;
5986    }
5987
5988    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5989        int j;
5990        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5991        TaskRecord jt = startTask;
5992
5993        // First look backwards
5994        for (j=startIndex-1; j>=0; j--) {
5995            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5996            if (r.task != jt) {
5997                jt = r.task;
5998                if (affinity.equals(jt.affinity)) {
5999                    return j;
6000                }
6001            }
6002        }
6003
6004        // Now look forwards
6005        final int N = mMainStack.mHistory.size();
6006        jt = startTask;
6007        for (j=startIndex+1; j<N; j++) {
6008            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
6009            if (r.task != jt) {
6010                if (affinity.equals(jt.affinity)) {
6011                    return j;
6012                }
6013                jt = r.task;
6014            }
6015        }
6016
6017        // Might it be at the top?
6018        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
6019            return N-1;
6020        }
6021
6022        return -1;
6023    }
6024
6025    /**
6026     * TODO: Add mController hook
6027     */
6028    public void moveTaskToFront(int task, int flags, Bundle options) {
6029        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6030                "moveTaskToFront()");
6031
6032        synchronized(this) {
6033            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6034                    Binder.getCallingUid(), "Task to front")) {
6035                ActivityOptions.abort(options);
6036                return;
6037            }
6038            final long origId = Binder.clearCallingIdentity();
6039            try {
6040                TaskRecord tr = taskForIdLocked(task);
6041                if (tr != null) {
6042                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6043                        mMainStack.mUserLeaving = true;
6044                    }
6045                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6046                        // Caller wants the home activity moved with it.  To accomplish this,
6047                        // we'll just move the home task to the top first.
6048                        mMainStack.moveHomeToFrontLocked();
6049                    }
6050                    mMainStack.moveTaskToFrontLocked(tr, null, options);
6051                    return;
6052                }
6053                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6054                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
6055                    if (hr.task.taskId == task) {
6056                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6057                            mMainStack.mUserLeaving = true;
6058                        }
6059                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6060                            // Caller wants the home activity moved with it.  To accomplish this,
6061                            // we'll just move the home task to the top first.
6062                            mMainStack.moveHomeToFrontLocked();
6063                        }
6064                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
6065                        return;
6066                    }
6067                }
6068            } finally {
6069                Binder.restoreCallingIdentity(origId);
6070            }
6071            ActivityOptions.abort(options);
6072        }
6073    }
6074
6075    public void moveTaskToBack(int task) {
6076        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6077                "moveTaskToBack()");
6078
6079        synchronized(this) {
6080            if (mMainStack.mResumedActivity != null
6081                    && mMainStack.mResumedActivity.task.taskId == task) {
6082                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6083                        Binder.getCallingUid(), "Task to back")) {
6084                    return;
6085                }
6086            }
6087            final long origId = Binder.clearCallingIdentity();
6088            mMainStack.moveTaskToBackLocked(task, null);
6089            Binder.restoreCallingIdentity(origId);
6090        }
6091    }
6092
6093    /**
6094     * Moves an activity, and all of the other activities within the same task, to the bottom
6095     * of the history stack.  The activity's order within the task is unchanged.
6096     *
6097     * @param token A reference to the activity we wish to move
6098     * @param nonRoot If false then this only works if the activity is the root
6099     *                of a task; if true it will work for any activity in a task.
6100     * @return Returns true if the move completed, false if not.
6101     */
6102    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6103        enforceNotIsolatedCaller("moveActivityTaskToBack");
6104        synchronized(this) {
6105            final long origId = Binder.clearCallingIdentity();
6106            int taskId = getTaskForActivityLocked(token, !nonRoot);
6107            if (taskId >= 0) {
6108                return mMainStack.moveTaskToBackLocked(taskId, null);
6109            }
6110            Binder.restoreCallingIdentity(origId);
6111        }
6112        return false;
6113    }
6114
6115    public void moveTaskBackwards(int task) {
6116        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6117                "moveTaskBackwards()");
6118
6119        synchronized(this) {
6120            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6121                    Binder.getCallingUid(), "Task backwards")) {
6122                return;
6123            }
6124            final long origId = Binder.clearCallingIdentity();
6125            moveTaskBackwardsLocked(task);
6126            Binder.restoreCallingIdentity(origId);
6127        }
6128    }
6129
6130    private final void moveTaskBackwardsLocked(int task) {
6131        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6132    }
6133
6134    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6135        synchronized(this) {
6136            return getTaskForActivityLocked(token, onlyRoot);
6137        }
6138    }
6139
6140    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6141        final int N = mMainStack.mHistory.size();
6142        TaskRecord lastTask = null;
6143        for (int i=0; i<N; i++) {
6144            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6145            if (r.appToken == token) {
6146                if (!onlyRoot || lastTask != r.task) {
6147                    return r.task.taskId;
6148                }
6149                return -1;
6150            }
6151            lastTask = r.task;
6152        }
6153
6154        return -1;
6155    }
6156
6157    // =========================================================
6158    // THUMBNAILS
6159    // =========================================================
6160
6161    public void reportThumbnail(IBinder token,
6162            Bitmap thumbnail, CharSequence description) {
6163        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6164        final long origId = Binder.clearCallingIdentity();
6165        sendPendingThumbnail(null, token, thumbnail, description, true);
6166        Binder.restoreCallingIdentity(origId);
6167    }
6168
6169    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6170            Bitmap thumbnail, CharSequence description, boolean always) {
6171        TaskRecord task = null;
6172        ArrayList receivers = null;
6173
6174        //System.out.println("Send pending thumbnail: " + r);
6175
6176        synchronized(this) {
6177            if (r == null) {
6178                r = mMainStack.isInStackLocked(token);
6179                if (r == null) {
6180                    return;
6181                }
6182            }
6183            if (thumbnail == null && r.thumbHolder != null) {
6184                thumbnail = r.thumbHolder.lastThumbnail;
6185                description = r.thumbHolder.lastDescription;
6186            }
6187            if (thumbnail == null && !always) {
6188                // If there is no thumbnail, and this entry is not actually
6189                // going away, then abort for now and pick up the next
6190                // thumbnail we get.
6191                return;
6192            }
6193            task = r.task;
6194
6195            int N = mPendingThumbnails.size();
6196            int i=0;
6197            while (i<N) {
6198                PendingThumbnailsRecord pr =
6199                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6200                //System.out.println("Looking in " + pr.pendingRecords);
6201                if (pr.pendingRecords.remove(r)) {
6202                    if (receivers == null) {
6203                        receivers = new ArrayList();
6204                    }
6205                    receivers.add(pr);
6206                    if (pr.pendingRecords.size() == 0) {
6207                        pr.finished = true;
6208                        mPendingThumbnails.remove(i);
6209                        N--;
6210                        continue;
6211                    }
6212                }
6213                i++;
6214            }
6215        }
6216
6217        if (receivers != null) {
6218            final int N = receivers.size();
6219            for (int i=0; i<N; i++) {
6220                try {
6221                    PendingThumbnailsRecord pr =
6222                        (PendingThumbnailsRecord)receivers.get(i);
6223                    pr.receiver.newThumbnail(
6224                        task != null ? task.taskId : -1, thumbnail, description);
6225                    if (pr.finished) {
6226                        pr.receiver.finished();
6227                    }
6228                } catch (Exception e) {
6229                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6230                }
6231            }
6232        }
6233    }
6234
6235    // =========================================================
6236    // CONTENT PROVIDERS
6237    // =========================================================
6238
6239    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6240        List<ProviderInfo> providers = null;
6241        try {
6242            providers = AppGlobals.getPackageManager().
6243                queryContentProviders(app.processName, app.uid,
6244                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6245        } catch (RemoteException ex) {
6246        }
6247        if (DEBUG_MU)
6248            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6249        int userId = app.userId;
6250        if (providers != null) {
6251            int N = providers.size();
6252            for (int i=0; i<N; i++) {
6253                ProviderInfo cpi =
6254                    (ProviderInfo)providers.get(i);
6255                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6256                        cpi.name, cpi.flags);
6257                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6258                    // This is a singleton provider, but a user besides the
6259                    // default user is asking to initialize a process it runs
6260                    // in...  well, no, it doesn't actually run in this process,
6261                    // it runs in the process of the default user.  Get rid of it.
6262                    providers.remove(i);
6263                    N--;
6264                    continue;
6265                }
6266
6267                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6268                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6269                if (cpr == null) {
6270                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6271                    mProviderMap.putProviderByClass(comp, cpr);
6272                }
6273                if (DEBUG_MU)
6274                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6275                app.pubProviders.put(cpi.name, cpr);
6276                app.addPackage(cpi.applicationInfo.packageName);
6277                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6278            }
6279        }
6280        return providers;
6281    }
6282
6283    /**
6284     * Check if {@link ProcessRecord} has a possible chance at accessing the
6285     * given {@link ProviderInfo}. Final permission checking is always done
6286     * in {@link ContentProvider}.
6287     */
6288    private final String checkContentProviderPermissionLocked(
6289            ProviderInfo cpi, ProcessRecord r) {
6290        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6291        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6292        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6293                cpi.applicationInfo.uid, cpi.exported)
6294                == PackageManager.PERMISSION_GRANTED) {
6295            return null;
6296        }
6297        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6298                cpi.applicationInfo.uid, cpi.exported)
6299                == PackageManager.PERMISSION_GRANTED) {
6300            return null;
6301        }
6302
6303        PathPermission[] pps = cpi.pathPermissions;
6304        if (pps != null) {
6305            int i = pps.length;
6306            while (i > 0) {
6307                i--;
6308                PathPermission pp = pps[i];
6309                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6310                        cpi.applicationInfo.uid, cpi.exported)
6311                        == PackageManager.PERMISSION_GRANTED) {
6312                    return null;
6313                }
6314                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6315                        cpi.applicationInfo.uid, cpi.exported)
6316                        == PackageManager.PERMISSION_GRANTED) {
6317                    return null;
6318                }
6319            }
6320        }
6321
6322        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6323        if (perms != null) {
6324            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6325                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6326                    return null;
6327                }
6328            }
6329        }
6330
6331        String msg;
6332        if (!cpi.exported) {
6333            msg = "Permission Denial: opening provider " + cpi.name
6334                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6335                    + ", uid=" + callingUid + ") that is not exported from uid "
6336                    + cpi.applicationInfo.uid;
6337        } else {
6338            msg = "Permission Denial: opening provider " + cpi.name
6339                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6340                    + ", uid=" + callingUid + ") requires "
6341                    + cpi.readPermission + " or " + cpi.writePermission;
6342        }
6343        Slog.w(TAG, msg);
6344        return msg;
6345    }
6346
6347    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6348            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6349        if (r != null) {
6350            for (int i=0; i<r.conProviders.size(); i++) {
6351                ContentProviderConnection conn = r.conProviders.get(i);
6352                if (conn.provider == cpr) {
6353                    if (DEBUG_PROVIDER) Slog.v(TAG,
6354                            "Adding provider requested by "
6355                            + r.processName + " from process "
6356                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6357                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6358                    if (stable) {
6359                        conn.stableCount++;
6360                        conn.numStableIncs++;
6361                    } else {
6362                        conn.unstableCount++;
6363                        conn.numUnstableIncs++;
6364                    }
6365                    return conn;
6366                }
6367            }
6368            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6369            if (stable) {
6370                conn.stableCount = 1;
6371                conn.numStableIncs = 1;
6372            } else {
6373                conn.unstableCount = 1;
6374                conn.numUnstableIncs = 1;
6375            }
6376            cpr.connections.add(conn);
6377            r.conProviders.add(conn);
6378            return conn;
6379        }
6380        cpr.addExternalProcessHandleLocked(externalProcessToken);
6381        return null;
6382    }
6383
6384    boolean decProviderCountLocked(ContentProviderConnection conn,
6385            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6386        if (conn != null) {
6387            cpr = conn.provider;
6388            if (DEBUG_PROVIDER) Slog.v(TAG,
6389                    "Removing provider requested by "
6390                    + conn.client.processName + " from process "
6391                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6392                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6393            if (stable) {
6394                conn.stableCount--;
6395            } else {
6396                conn.unstableCount--;
6397            }
6398            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6399                cpr.connections.remove(conn);
6400                conn.client.conProviders.remove(conn);
6401                return true;
6402            }
6403            return false;
6404        }
6405        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6406        return false;
6407    }
6408
6409    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6410            String name, IBinder token, boolean stable, int userId) {
6411        ContentProviderRecord cpr;
6412        ContentProviderConnection conn = null;
6413        ProviderInfo cpi = null;
6414
6415        synchronized(this) {
6416            ProcessRecord r = null;
6417            if (caller != null) {
6418                r = getRecordForAppLocked(caller);
6419                if (r == null) {
6420                    throw new SecurityException(
6421                            "Unable to find app for caller " + caller
6422                          + " (pid=" + Binder.getCallingPid()
6423                          + ") when getting content provider " + name);
6424                }
6425            }
6426
6427            // First check if this content provider has been published...
6428            cpr = mProviderMap.getProviderByName(name, userId);
6429            boolean providerRunning = cpr != null;
6430            if (providerRunning) {
6431                cpi = cpr.info;
6432                String msg;
6433                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6434                    throw new SecurityException(msg);
6435                }
6436
6437                if (r != null && cpr.canRunHere(r)) {
6438                    // This provider has been published or is in the process
6439                    // of being published...  but it is also allowed to run
6440                    // in the caller's process, so don't make a connection
6441                    // and just let the caller instantiate its own instance.
6442                    ContentProviderHolder holder = cpr.newHolder(null);
6443                    // don't give caller the provider object, it needs
6444                    // to make its own.
6445                    holder.provider = null;
6446                    return holder;
6447                }
6448
6449                final long origId = Binder.clearCallingIdentity();
6450
6451                // In this case the provider instance already exists, so we can
6452                // return it right away.
6453                conn = incProviderCountLocked(r, cpr, token, stable);
6454                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6455                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6456                        // If this is a perceptible app accessing the provider,
6457                        // make sure to count it as being accessed and thus
6458                        // back up on the LRU list.  This is good because
6459                        // content providers are often expensive to start.
6460                        updateLruProcessLocked(cpr.proc, false, true);
6461                    }
6462                }
6463
6464                if (cpr.proc != null) {
6465                    if (false) {
6466                        if (cpr.name.flattenToShortString().equals(
6467                                "com.android.providers.calendar/.CalendarProvider2")) {
6468                            Slog.v(TAG, "****************** KILLING "
6469                                + cpr.name.flattenToShortString());
6470                            Process.killProcess(cpr.proc.pid);
6471                        }
6472                    }
6473                    boolean success = updateOomAdjLocked(cpr.proc);
6474                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6475                    // NOTE: there is still a race here where a signal could be
6476                    // pending on the process even though we managed to update its
6477                    // adj level.  Not sure what to do about this, but at least
6478                    // the race is now smaller.
6479                    if (!success) {
6480                        // Uh oh...  it looks like the provider's process
6481                        // has been killed on us.  We need to wait for a new
6482                        // process to be started, and make sure its death
6483                        // doesn't kill our process.
6484                        Slog.i(TAG,
6485                                "Existing provider " + cpr.name.flattenToShortString()
6486                                + " is crashing; detaching " + r);
6487                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6488                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6489                        if (!lastRef) {
6490                            // This wasn't the last ref our process had on
6491                            // the provider...  we have now been killed, bail.
6492                            return null;
6493                        }
6494                        providerRunning = false;
6495                        conn = null;
6496                    }
6497                }
6498
6499                Binder.restoreCallingIdentity(origId);
6500            }
6501
6502            boolean singleton;
6503            if (!providerRunning) {
6504                try {
6505                    cpi = AppGlobals.getPackageManager().
6506                        resolveContentProvider(name,
6507                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6508                } catch (RemoteException ex) {
6509                }
6510                if (cpi == null) {
6511                    return null;
6512                }
6513                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6514                        cpi.name, cpi.flags);
6515                if (singleton) {
6516                    userId = 0;
6517                }
6518                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6519
6520                String msg;
6521                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6522                    throw new SecurityException(msg);
6523                }
6524
6525                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6526                        && !cpi.processName.equals("system")) {
6527                    // If this content provider does not run in the system
6528                    // process, and the system is not yet ready to run other
6529                    // processes, then fail fast instead of hanging.
6530                    throw new IllegalArgumentException(
6531                            "Attempt to launch content provider before system ready");
6532                }
6533
6534                // Make sure that the user who owns this provider is started.  If not,
6535                // we don't want to allow it to run.
6536                if (mStartedUsers.get(userId) == null) {
6537                    Slog.w(TAG, "Unable to launch app "
6538                            + cpi.applicationInfo.packageName + "/"
6539                            + cpi.applicationInfo.uid + " for provider "
6540                            + name + ": user " + userId + " is stopped");
6541                    return null;
6542                }
6543
6544                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6545                cpr = mProviderMap.getProviderByClass(comp, userId);
6546                final boolean firstClass = cpr == null;
6547                if (firstClass) {
6548                    try {
6549                        ApplicationInfo ai =
6550                            AppGlobals.getPackageManager().
6551                                getApplicationInfo(
6552                                        cpi.applicationInfo.packageName,
6553                                        STOCK_PM_FLAGS, userId);
6554                        if (ai == null) {
6555                            Slog.w(TAG, "No package info for content provider "
6556                                    + cpi.name);
6557                            return null;
6558                        }
6559                        ai = getAppInfoForUser(ai, userId);
6560                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6561                    } catch (RemoteException ex) {
6562                        // pm is in same process, this will never happen.
6563                    }
6564                }
6565
6566                if (r != null && cpr.canRunHere(r)) {
6567                    // If this is a multiprocess provider, then just return its
6568                    // info and allow the caller to instantiate it.  Only do
6569                    // this if the provider is the same user as the caller's
6570                    // process, or can run as root (so can be in any process).
6571                    return cpr.newHolder(null);
6572                }
6573
6574                if (DEBUG_PROVIDER) {
6575                    RuntimeException e = new RuntimeException("here");
6576                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6577                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6578                }
6579
6580                // This is single process, and our app is now connecting to it.
6581                // See if we are already in the process of launching this
6582                // provider.
6583                final int N = mLaunchingProviders.size();
6584                int i;
6585                for (i=0; i<N; i++) {
6586                    if (mLaunchingProviders.get(i) == cpr) {
6587                        break;
6588                    }
6589                }
6590
6591                // If the provider is not already being launched, then get it
6592                // started.
6593                if (i >= N) {
6594                    final long origId = Binder.clearCallingIdentity();
6595
6596                    try {
6597                        // Content provider is now in use, its package can't be stopped.
6598                        try {
6599                            AppGlobals.getPackageManager().setPackageStoppedState(
6600                                    cpr.appInfo.packageName, false, userId);
6601                        } catch (RemoteException e) {
6602                        } catch (IllegalArgumentException e) {
6603                            Slog.w(TAG, "Failed trying to unstop package "
6604                                    + cpr.appInfo.packageName + ": " + e);
6605                        }
6606
6607                        ProcessRecord proc = startProcessLocked(cpi.processName,
6608                                cpr.appInfo, false, 0, "content provider",
6609                                new ComponentName(cpi.applicationInfo.packageName,
6610                                        cpi.name), false, false);
6611                        if (proc == null) {
6612                            Slog.w(TAG, "Unable to launch app "
6613                                    + cpi.applicationInfo.packageName + "/"
6614                                    + cpi.applicationInfo.uid + " for provider "
6615                                    + name + ": process is bad");
6616                            return null;
6617                        }
6618                        cpr.launchingApp = proc;
6619                        mLaunchingProviders.add(cpr);
6620                    } finally {
6621                        Binder.restoreCallingIdentity(origId);
6622                    }
6623                }
6624
6625                // Make sure the provider is published (the same provider class
6626                // may be published under multiple names).
6627                if (firstClass) {
6628                    mProviderMap.putProviderByClass(comp, cpr);
6629                }
6630
6631                mProviderMap.putProviderByName(name, cpr);
6632                conn = incProviderCountLocked(r, cpr, token, stable);
6633                if (conn != null) {
6634                    conn.waiting = true;
6635                }
6636            }
6637        }
6638
6639        // Wait for the provider to be published...
6640        synchronized (cpr) {
6641            while (cpr.provider == null) {
6642                if (cpr.launchingApp == null) {
6643                    Slog.w(TAG, "Unable to launch app "
6644                            + cpi.applicationInfo.packageName + "/"
6645                            + cpi.applicationInfo.uid + " for provider "
6646                            + name + ": launching app became null");
6647                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6648                            cpi.applicationInfo.packageName,
6649                            cpi.applicationInfo.uid, name);
6650                    return null;
6651                }
6652                try {
6653                    if (DEBUG_MU) {
6654                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6655                                + cpr.launchingApp);
6656                    }
6657                    if (conn != null) {
6658                        conn.waiting = true;
6659                    }
6660                    cpr.wait();
6661                } catch (InterruptedException ex) {
6662                } finally {
6663                    if (conn != null) {
6664                        conn.waiting = false;
6665                    }
6666                }
6667            }
6668        }
6669        return cpr != null ? cpr.newHolder(conn) : null;
6670    }
6671
6672    public final ContentProviderHolder getContentProvider(
6673            IApplicationThread caller, String name, int userId, boolean stable) {
6674        enforceNotIsolatedCaller("getContentProvider");
6675        if (caller == null) {
6676            String msg = "null IApplicationThread when getting content provider "
6677                    + name;
6678            Slog.w(TAG, msg);
6679            throw new SecurityException(msg);
6680        }
6681
6682        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6683                false, true, "getContentProvider", null);
6684        return getContentProviderImpl(caller, name, null, stable, userId);
6685    }
6686
6687    public ContentProviderHolder getContentProviderExternal(
6688            String name, int userId, IBinder token) {
6689        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6690            "Do not have permission in call getContentProviderExternal()");
6691        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6692                false, true, "getContentProvider", null);
6693        return getContentProviderExternalUnchecked(name, token, userId);
6694    }
6695
6696    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6697            IBinder token, int userId) {
6698        return getContentProviderImpl(null, name, token, true, userId);
6699    }
6700
6701    /**
6702     * Drop a content provider from a ProcessRecord's bookkeeping
6703     * @param cpr
6704     */
6705    public void removeContentProvider(IBinder connection, boolean stable) {
6706        enforceNotIsolatedCaller("removeContentProvider");
6707        synchronized (this) {
6708            ContentProviderConnection conn;
6709            try {
6710                conn = (ContentProviderConnection)connection;
6711            } catch (ClassCastException e) {
6712                String msg ="removeContentProvider: " + connection
6713                        + " not a ContentProviderConnection";
6714                Slog.w(TAG, msg);
6715                throw new IllegalArgumentException(msg);
6716            }
6717            if (conn == null) {
6718                throw new NullPointerException("connection is null");
6719            }
6720            if (decProviderCountLocked(conn, null, null, stable)) {
6721                updateOomAdjLocked();
6722            }
6723        }
6724    }
6725
6726    public void removeContentProviderExternal(String name, IBinder token) {
6727        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6728            "Do not have permission in call removeContentProviderExternal()");
6729        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6730    }
6731
6732    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6733        synchronized (this) {
6734            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6735            if(cpr == null) {
6736                //remove from mProvidersByClass
6737                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6738                return;
6739            }
6740
6741            //update content provider record entry info
6742            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6743            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6744            if (localCpr.hasExternalProcessHandles()) {
6745                if (localCpr.removeExternalProcessHandleLocked(token)) {
6746                    updateOomAdjLocked();
6747                } else {
6748                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6749                            + " with no external reference for token: "
6750                            + token + ".");
6751                }
6752            } else {
6753                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6754                        + " with no external references.");
6755            }
6756        }
6757    }
6758
6759    public final void publishContentProviders(IApplicationThread caller,
6760            List<ContentProviderHolder> providers) {
6761        if (providers == null) {
6762            return;
6763        }
6764
6765        enforceNotIsolatedCaller("publishContentProviders");
6766        synchronized (this) {
6767            final ProcessRecord r = getRecordForAppLocked(caller);
6768            if (DEBUG_MU)
6769                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6770            if (r == null) {
6771                throw new SecurityException(
6772                        "Unable to find app for caller " + caller
6773                      + " (pid=" + Binder.getCallingPid()
6774                      + ") when publishing content providers");
6775            }
6776
6777            final long origId = Binder.clearCallingIdentity();
6778
6779            final int N = providers.size();
6780            for (int i=0; i<N; i++) {
6781                ContentProviderHolder src = providers.get(i);
6782                if (src == null || src.info == null || src.provider == null) {
6783                    continue;
6784                }
6785                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6786                if (DEBUG_MU)
6787                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6788                if (dst != null) {
6789                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6790                    mProviderMap.putProviderByClass(comp, dst);
6791                    String names[] = dst.info.authority.split(";");
6792                    for (int j = 0; j < names.length; j++) {
6793                        mProviderMap.putProviderByName(names[j], dst);
6794                    }
6795
6796                    int NL = mLaunchingProviders.size();
6797                    int j;
6798                    for (j=0; j<NL; j++) {
6799                        if (mLaunchingProviders.get(j) == dst) {
6800                            mLaunchingProviders.remove(j);
6801                            j--;
6802                            NL--;
6803                        }
6804                    }
6805                    synchronized (dst) {
6806                        dst.provider = src.provider;
6807                        dst.proc = r;
6808                        dst.notifyAll();
6809                    }
6810                    updateOomAdjLocked(r);
6811                }
6812            }
6813
6814            Binder.restoreCallingIdentity(origId);
6815        }
6816    }
6817
6818    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6819        ContentProviderConnection conn;
6820        try {
6821            conn = (ContentProviderConnection)connection;
6822        } catch (ClassCastException e) {
6823            String msg ="refContentProvider: " + connection
6824                    + " not a ContentProviderConnection";
6825            Slog.w(TAG, msg);
6826            throw new IllegalArgumentException(msg);
6827        }
6828        if (conn == null) {
6829            throw new NullPointerException("connection is null");
6830        }
6831
6832        synchronized (this) {
6833            if (stable > 0) {
6834                conn.numStableIncs += stable;
6835            }
6836            stable = conn.stableCount + stable;
6837            if (stable < 0) {
6838                throw new IllegalStateException("stableCount < 0: " + stable);
6839            }
6840
6841            if (unstable > 0) {
6842                conn.numUnstableIncs += unstable;
6843            }
6844            unstable = conn.unstableCount + unstable;
6845            if (unstable < 0) {
6846                throw new IllegalStateException("unstableCount < 0: " + unstable);
6847            }
6848
6849            if ((stable+unstable) <= 0) {
6850                throw new IllegalStateException("ref counts can't go to zero here: stable="
6851                        + stable + " unstable=" + unstable);
6852            }
6853            conn.stableCount = stable;
6854            conn.unstableCount = unstable;
6855            return !conn.dead;
6856        }
6857    }
6858
6859    public void unstableProviderDied(IBinder connection) {
6860        ContentProviderConnection conn;
6861        try {
6862            conn = (ContentProviderConnection)connection;
6863        } catch (ClassCastException e) {
6864            String msg ="refContentProvider: " + connection
6865                    + " not a ContentProviderConnection";
6866            Slog.w(TAG, msg);
6867            throw new IllegalArgumentException(msg);
6868        }
6869        if (conn == null) {
6870            throw new NullPointerException("connection is null");
6871        }
6872
6873        // Safely retrieve the content provider associated with the connection.
6874        IContentProvider provider;
6875        synchronized (this) {
6876            provider = conn.provider.provider;
6877        }
6878
6879        if (provider == null) {
6880            // Um, yeah, we're way ahead of you.
6881            return;
6882        }
6883
6884        // Make sure the caller is being honest with us.
6885        if (provider.asBinder().pingBinder()) {
6886            // Er, no, still looks good to us.
6887            synchronized (this) {
6888                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6889                        + " says " + conn + " died, but we don't agree");
6890                return;
6891            }
6892        }
6893
6894        // Well look at that!  It's dead!
6895        synchronized (this) {
6896            if (conn.provider.provider != provider) {
6897                // But something changed...  good enough.
6898                return;
6899            }
6900
6901            ProcessRecord proc = conn.provider.proc;
6902            if (proc == null || proc.thread == null) {
6903                // Seems like the process is already cleaned up.
6904                return;
6905            }
6906
6907            // As far as we're concerned, this is just like receiving a
6908            // death notification...  just a bit prematurely.
6909            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6910                    + ") early provider death");
6911            final long ident = Binder.clearCallingIdentity();
6912            try {
6913                appDiedLocked(proc, proc.pid, proc.thread);
6914            } finally {
6915                Binder.restoreCallingIdentity(ident);
6916            }
6917        }
6918    }
6919
6920    public static final void installSystemProviders() {
6921        List<ProviderInfo> providers;
6922        synchronized (mSelf) {
6923            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6924            providers = mSelf.generateApplicationProvidersLocked(app);
6925            if (providers != null) {
6926                for (int i=providers.size()-1; i>=0; i--) {
6927                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6928                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6929                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6930                                + ": not system .apk");
6931                        providers.remove(i);
6932                    }
6933                }
6934            }
6935        }
6936        if (providers != null) {
6937            mSystemThread.installSystemProviders(providers);
6938        }
6939
6940        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6941
6942        mSelf.mUsageStatsService.monitorPackages();
6943    }
6944
6945    /**
6946     * Allows app to retrieve the MIME type of a URI without having permission
6947     * to access its content provider.
6948     *
6949     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6950     *
6951     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6952     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6953     */
6954    public String getProviderMimeType(Uri uri, int userId) {
6955        enforceNotIsolatedCaller("getProviderMimeType");
6956        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
6957                userId, false, true, "getProviderMimeType", null);
6958        final String name = uri.getAuthority();
6959        final long ident = Binder.clearCallingIdentity();
6960        ContentProviderHolder holder = null;
6961
6962        try {
6963            holder = getContentProviderExternalUnchecked(name, null, userId);
6964            if (holder != null) {
6965                return holder.provider.getType(uri);
6966            }
6967        } catch (RemoteException e) {
6968            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6969            return null;
6970        } finally {
6971            if (holder != null) {
6972                removeContentProviderExternalUnchecked(name, null, userId);
6973            }
6974            Binder.restoreCallingIdentity(ident);
6975        }
6976
6977        return null;
6978    }
6979
6980    // =========================================================
6981    // GLOBAL MANAGEMENT
6982    // =========================================================
6983
6984    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6985            ApplicationInfo info, String customProcess, boolean isolated) {
6986        String proc = customProcess != null ? customProcess : info.processName;
6987        BatteryStatsImpl.Uid.Proc ps = null;
6988        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6989        int uid = info.uid;
6990        if (isolated) {
6991            int userId = UserHandle.getUserId(uid);
6992            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6993            uid = 0;
6994            while (true) {
6995                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6996                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6997                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6998                }
6999                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
7000                mNextIsolatedProcessUid++;
7001                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
7002                    // No process for this uid, use it.
7003                    break;
7004                }
7005                stepsLeft--;
7006                if (stepsLeft <= 0) {
7007                    return null;
7008                }
7009            }
7010        }
7011        synchronized (stats) {
7012            ps = stats.getProcessStatsLocked(info.uid, proc);
7013        }
7014        return new ProcessRecord(ps, thread, info, proc, uid);
7015    }
7016
7017    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
7018        ProcessRecord app;
7019        if (!isolated) {
7020            app = getProcessRecordLocked(info.processName, info.uid);
7021        } else {
7022            app = null;
7023        }
7024
7025        if (app == null) {
7026            app = newProcessRecordLocked(null, info, null, isolated);
7027            mProcessNames.put(info.processName, app.uid, app);
7028            if (isolated) {
7029                mIsolatedProcesses.put(app.uid, app);
7030            }
7031            updateLruProcessLocked(app, true, true);
7032        }
7033
7034        // This package really, really can not be stopped.
7035        try {
7036            AppGlobals.getPackageManager().setPackageStoppedState(
7037                    info.packageName, false, UserHandle.getUserId(app.uid));
7038        } catch (RemoteException e) {
7039        } catch (IllegalArgumentException e) {
7040            Slog.w(TAG, "Failed trying to unstop package "
7041                    + info.packageName + ": " + e);
7042        }
7043
7044        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7045                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7046            app.persistent = true;
7047            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
7048        }
7049        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7050            mPersistentStartingProcesses.add(app);
7051            startProcessLocked(app, "added application", app.processName);
7052        }
7053
7054        return app;
7055    }
7056
7057    public void unhandledBack() {
7058        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7059                "unhandledBack()");
7060
7061        synchronized(this) {
7062            int count = mMainStack.mHistory.size();
7063            if (DEBUG_SWITCH) Slog.d(
7064                TAG, "Performing unhandledBack(): stack size = " + count);
7065            if (count > 1) {
7066                final long origId = Binder.clearCallingIdentity();
7067                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
7068                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
7069                Binder.restoreCallingIdentity(origId);
7070            }
7071        }
7072    }
7073
7074    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7075        enforceNotIsolatedCaller("openContentUri");
7076        final int userId = UserHandle.getCallingUserId();
7077        String name = uri.getAuthority();
7078        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
7079        ParcelFileDescriptor pfd = null;
7080        if (cph != null) {
7081            // We record the binder invoker's uid in thread-local storage before
7082            // going to the content provider to open the file.  Later, in the code
7083            // that handles all permissions checks, we look for this uid and use
7084            // that rather than the Activity Manager's own uid.  The effect is that
7085            // we do the check against the caller's permissions even though it looks
7086            // to the content provider like the Activity Manager itself is making
7087            // the request.
7088            sCallerIdentity.set(new Identity(
7089                    Binder.getCallingPid(), Binder.getCallingUid()));
7090            try {
7091                pfd = cph.provider.openFile(uri, "r");
7092            } catch (FileNotFoundException e) {
7093                // do nothing; pfd will be returned null
7094            } finally {
7095                // Ensure that whatever happens, we clean up the identity state
7096                sCallerIdentity.remove();
7097            }
7098
7099            // We've got the fd now, so we're done with the provider.
7100            removeContentProviderExternalUnchecked(name, null, userId);
7101        } else {
7102            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7103        }
7104        return pfd;
7105    }
7106
7107    // Actually is sleeping or shutting down or whatever else in the future
7108    // is an inactive state.
7109    public boolean isSleeping() {
7110        return mSleeping || mShuttingDown;
7111    }
7112
7113    public void goingToSleep() {
7114        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7115                != PackageManager.PERMISSION_GRANTED) {
7116            throw new SecurityException("Requires permission "
7117                    + android.Manifest.permission.DEVICE_POWER);
7118        }
7119
7120        synchronized(this) {
7121            mWentToSleep = true;
7122            updateEventDispatchingLocked();
7123
7124            if (!mSleeping) {
7125                mSleeping = true;
7126                mMainStack.stopIfSleepingLocked();
7127
7128                // Initialize the wake times of all processes.
7129                checkExcessivePowerUsageLocked(false);
7130                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7131                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7132                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7133            }
7134        }
7135    }
7136
7137    public boolean shutdown(int timeout) {
7138        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7139                != PackageManager.PERMISSION_GRANTED) {
7140            throw new SecurityException("Requires permission "
7141                    + android.Manifest.permission.SHUTDOWN);
7142        }
7143
7144        boolean timedout = false;
7145
7146        synchronized(this) {
7147            mShuttingDown = true;
7148            updateEventDispatchingLocked();
7149
7150            if (mMainStack.mResumedActivity != null) {
7151                mMainStack.stopIfSleepingLocked();
7152                final long endTime = System.currentTimeMillis() + timeout;
7153                while (mMainStack.mResumedActivity != null
7154                        || mMainStack.mPausingActivity != null) {
7155                    long delay = endTime - System.currentTimeMillis();
7156                    if (delay <= 0) {
7157                        Slog.w(TAG, "Activity manager shutdown timed out");
7158                        timedout = true;
7159                        break;
7160                    }
7161                    try {
7162                        this.wait();
7163                    } catch (InterruptedException e) {
7164                    }
7165                }
7166            }
7167        }
7168
7169        mUsageStatsService.shutdown();
7170        mBatteryStatsService.shutdown();
7171
7172        return timedout;
7173    }
7174
7175    public final void activitySlept(IBinder token) {
7176        if (localLOGV) Slog.v(
7177            TAG, "Activity slept: token=" + token);
7178
7179        ActivityRecord r = null;
7180
7181        final long origId = Binder.clearCallingIdentity();
7182
7183        synchronized (this) {
7184            r = mMainStack.isInStackLocked(token);
7185            if (r != null) {
7186                mMainStack.activitySleptLocked(r);
7187            }
7188        }
7189
7190        Binder.restoreCallingIdentity(origId);
7191    }
7192
7193    private void comeOutOfSleepIfNeededLocked() {
7194        if (!mWentToSleep && !mLockScreenShown) {
7195            if (mSleeping) {
7196                mSleeping = false;
7197                mMainStack.awakeFromSleepingLocked();
7198                mMainStack.resumeTopActivityLocked(null);
7199            }
7200        }
7201    }
7202
7203    public void wakingUp() {
7204        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7205                != PackageManager.PERMISSION_GRANTED) {
7206            throw new SecurityException("Requires permission "
7207                    + android.Manifest.permission.DEVICE_POWER);
7208        }
7209
7210        synchronized(this) {
7211            mWentToSleep = false;
7212            updateEventDispatchingLocked();
7213            comeOutOfSleepIfNeededLocked();
7214        }
7215    }
7216
7217    private void updateEventDispatchingLocked() {
7218        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7219    }
7220
7221    public void setLockScreenShown(boolean shown) {
7222        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7223                != PackageManager.PERMISSION_GRANTED) {
7224            throw new SecurityException("Requires permission "
7225                    + android.Manifest.permission.DEVICE_POWER);
7226        }
7227
7228        synchronized(this) {
7229            mLockScreenShown = shown;
7230            comeOutOfSleepIfNeededLocked();
7231        }
7232    }
7233
7234    public void stopAppSwitches() {
7235        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7236                != PackageManager.PERMISSION_GRANTED) {
7237            throw new SecurityException("Requires permission "
7238                    + android.Manifest.permission.STOP_APP_SWITCHES);
7239        }
7240
7241        synchronized(this) {
7242            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7243                    + APP_SWITCH_DELAY_TIME;
7244            mDidAppSwitch = false;
7245            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7246            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7247            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7248        }
7249    }
7250
7251    public void resumeAppSwitches() {
7252        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7253                != PackageManager.PERMISSION_GRANTED) {
7254            throw new SecurityException("Requires permission "
7255                    + android.Manifest.permission.STOP_APP_SWITCHES);
7256        }
7257
7258        synchronized(this) {
7259            // Note that we don't execute any pending app switches... we will
7260            // let those wait until either the timeout, or the next start
7261            // activity request.
7262            mAppSwitchesAllowedTime = 0;
7263        }
7264    }
7265
7266    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7267            String name) {
7268        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7269            return true;
7270        }
7271
7272        final int perm = checkComponentPermission(
7273                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7274                callingUid, -1, true);
7275        if (perm == PackageManager.PERMISSION_GRANTED) {
7276            return true;
7277        }
7278
7279        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7280        return false;
7281    }
7282
7283    public void setDebugApp(String packageName, boolean waitForDebugger,
7284            boolean persistent) {
7285        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7286                "setDebugApp()");
7287
7288        // Note that this is not really thread safe if there are multiple
7289        // callers into it at the same time, but that's not a situation we
7290        // care about.
7291        if (persistent) {
7292            final ContentResolver resolver = mContext.getContentResolver();
7293            Settings.System.putString(
7294                resolver, Settings.System.DEBUG_APP,
7295                packageName);
7296            Settings.System.putInt(
7297                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7298                waitForDebugger ? 1 : 0);
7299        }
7300
7301        synchronized (this) {
7302            if (!persistent) {
7303                mOrigDebugApp = mDebugApp;
7304                mOrigWaitForDebugger = mWaitForDebugger;
7305            }
7306            mDebugApp = packageName;
7307            mWaitForDebugger = waitForDebugger;
7308            mDebugTransient = !persistent;
7309            if (packageName != null) {
7310                final long origId = Binder.clearCallingIdentity();
7311                forceStopPackageLocked(packageName, -1, false, false, true, true,
7312                        UserHandle.USER_ALL);
7313                Binder.restoreCallingIdentity(origId);
7314            }
7315        }
7316    }
7317
7318    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7319        synchronized (this) {
7320            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7321            if (!isDebuggable) {
7322                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7323                    throw new SecurityException("Process not debuggable: " + app.packageName);
7324                }
7325            }
7326
7327            mOpenGlTraceApp = processName;
7328        }
7329    }
7330
7331    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7332            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7333        synchronized (this) {
7334            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7335            if (!isDebuggable) {
7336                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7337                    throw new SecurityException("Process not debuggable: " + app.packageName);
7338                }
7339            }
7340            mProfileApp = processName;
7341            mProfileFile = profileFile;
7342            if (mProfileFd != null) {
7343                try {
7344                    mProfileFd.close();
7345                } catch (IOException e) {
7346                }
7347                mProfileFd = null;
7348            }
7349            mProfileFd = profileFd;
7350            mProfileType = 0;
7351            mAutoStopProfiler = autoStopProfiler;
7352        }
7353    }
7354
7355    public void setAlwaysFinish(boolean enabled) {
7356        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7357                "setAlwaysFinish()");
7358
7359        Settings.System.putInt(
7360                mContext.getContentResolver(),
7361                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7362
7363        synchronized (this) {
7364            mAlwaysFinishActivities = enabled;
7365        }
7366    }
7367
7368    public void setActivityController(IActivityController controller) {
7369        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7370                "setActivityController()");
7371        synchronized (this) {
7372            mController = controller;
7373        }
7374    }
7375
7376    public boolean isUserAMonkey() {
7377        // For now the fact that there is a controller implies
7378        // we have a monkey.
7379        synchronized (this) {
7380            return mController != null;
7381        }
7382    }
7383
7384    public void registerProcessObserver(IProcessObserver observer) {
7385        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7386                "registerProcessObserver()");
7387        synchronized (this) {
7388            mProcessObservers.register(observer);
7389        }
7390    }
7391
7392    public void unregisterProcessObserver(IProcessObserver observer) {
7393        synchronized (this) {
7394            mProcessObservers.unregister(observer);
7395        }
7396    }
7397
7398    public void setImmersive(IBinder token, boolean immersive) {
7399        synchronized(this) {
7400            ActivityRecord r = mMainStack.isInStackLocked(token);
7401            if (r == null) {
7402                throw new IllegalArgumentException();
7403            }
7404            r.immersive = immersive;
7405        }
7406    }
7407
7408    public boolean isImmersive(IBinder token) {
7409        synchronized (this) {
7410            ActivityRecord r = mMainStack.isInStackLocked(token);
7411            if (r == null) {
7412                throw new IllegalArgumentException();
7413            }
7414            return r.immersive;
7415        }
7416    }
7417
7418    public boolean isTopActivityImmersive() {
7419        enforceNotIsolatedCaller("startActivity");
7420        synchronized (this) {
7421            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7422            return (r != null) ? r.immersive : false;
7423        }
7424    }
7425
7426    public final void enterSafeMode() {
7427        synchronized(this) {
7428            // It only makes sense to do this before the system is ready
7429            // and started launching other packages.
7430            if (!mSystemReady) {
7431                try {
7432                    AppGlobals.getPackageManager().enterSafeMode();
7433                } catch (RemoteException e) {
7434                }
7435            }
7436        }
7437    }
7438
7439    public final void showSafeModeOverlay() {
7440        View v = LayoutInflater.from(mContext).inflate(
7441                com.android.internal.R.layout.safe_mode, null);
7442        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7443        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7444        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7445        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7446        lp.gravity = Gravity.BOTTOM | Gravity.START;
7447        lp.format = v.getBackground().getOpacity();
7448        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7449                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7450        ((WindowManager)mContext.getSystemService(
7451                Context.WINDOW_SERVICE)).addView(v, lp);
7452    }
7453
7454    public void noteWakeupAlarm(IIntentSender sender) {
7455        if (!(sender instanceof PendingIntentRecord)) {
7456            return;
7457        }
7458        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7459        synchronized (stats) {
7460            if (mBatteryStatsService.isOnBattery()) {
7461                mBatteryStatsService.enforceCallingPermission();
7462                PendingIntentRecord rec = (PendingIntentRecord)sender;
7463                int MY_UID = Binder.getCallingUid();
7464                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7465                BatteryStatsImpl.Uid.Pkg pkg =
7466                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7467                pkg.incWakeupsLocked();
7468            }
7469        }
7470    }
7471
7472    public boolean killPids(int[] pids, String pReason, boolean secure) {
7473        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7474            throw new SecurityException("killPids only available to the system");
7475        }
7476        String reason = (pReason == null) ? "Unknown" : pReason;
7477        // XXX Note: don't acquire main activity lock here, because the window
7478        // manager calls in with its locks held.
7479
7480        boolean killed = false;
7481        synchronized (mPidsSelfLocked) {
7482            int[] types = new int[pids.length];
7483            int worstType = 0;
7484            for (int i=0; i<pids.length; i++) {
7485                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7486                if (proc != null) {
7487                    int type = proc.setAdj;
7488                    types[i] = type;
7489                    if (type > worstType) {
7490                        worstType = type;
7491                    }
7492                }
7493            }
7494
7495            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7496            // then constrain it so we will kill all hidden procs.
7497            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7498                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7499                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7500            }
7501
7502            // If this is not a secure call, don't let it kill processes that
7503            // are important.
7504            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7505                worstType = ProcessList.SERVICE_ADJ;
7506            }
7507
7508            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7509            for (int i=0; i<pids.length; i++) {
7510                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7511                if (proc == null) {
7512                    continue;
7513                }
7514                int adj = proc.setAdj;
7515                if (adj >= worstType && !proc.killedBackground) {
7516                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7517                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7518                            proc.processName, adj, reason);
7519                    killed = true;
7520                    proc.killedBackground = true;
7521                    Process.killProcessQuiet(pids[i]);
7522                }
7523            }
7524        }
7525        return killed;
7526    }
7527
7528    @Override
7529    public boolean killProcessesBelowForeground(String reason) {
7530        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7531            throw new SecurityException("killProcessesBelowForeground() only available to system");
7532        }
7533
7534        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7535    }
7536
7537    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7538        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7539            throw new SecurityException("killProcessesBelowAdj() only available to system");
7540        }
7541
7542        boolean killed = false;
7543        synchronized (mPidsSelfLocked) {
7544            final int size = mPidsSelfLocked.size();
7545            for (int i = 0; i < size; i++) {
7546                final int pid = mPidsSelfLocked.keyAt(i);
7547                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7548                if (proc == null) continue;
7549
7550                final int adj = proc.setAdj;
7551                if (adj > belowAdj && !proc.killedBackground) {
7552                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7553                    EventLog.writeEvent(
7554                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7555                    killed = true;
7556                    proc.killedBackground = true;
7557                    Process.killProcessQuiet(pid);
7558                }
7559            }
7560        }
7561        return killed;
7562    }
7563
7564    public final void startRunning(String pkg, String cls, String action,
7565            String data) {
7566        synchronized(this) {
7567            if (mStartRunning) {
7568                return;
7569            }
7570            mStartRunning = true;
7571            mTopComponent = pkg != null && cls != null
7572                    ? new ComponentName(pkg, cls) : null;
7573            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7574            mTopData = data;
7575            if (!mSystemReady) {
7576                return;
7577            }
7578        }
7579
7580        systemReady(null);
7581    }
7582
7583    private void retrieveSettings() {
7584        final ContentResolver resolver = mContext.getContentResolver();
7585        String debugApp = Settings.System.getString(
7586            resolver, Settings.System.DEBUG_APP);
7587        boolean waitForDebugger = Settings.System.getInt(
7588            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7589        boolean alwaysFinishActivities = Settings.System.getInt(
7590            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7591
7592        Configuration configuration = new Configuration();
7593        Settings.System.getConfiguration(resolver, configuration);
7594
7595        synchronized (this) {
7596            mDebugApp = mOrigDebugApp = debugApp;
7597            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7598            mAlwaysFinishActivities = alwaysFinishActivities;
7599            // This happens before any activities are started, so we can
7600            // change mConfiguration in-place.
7601            updateConfigurationLocked(configuration, null, false, true);
7602            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7603        }
7604    }
7605
7606    public boolean testIsSystemReady() {
7607        // no need to synchronize(this) just to read & return the value
7608        return mSystemReady;
7609    }
7610
7611    private static File getCalledPreBootReceiversFile() {
7612        File dataDir = Environment.getDataDirectory();
7613        File systemDir = new File(dataDir, "system");
7614        File fname = new File(systemDir, "called_pre_boots.dat");
7615        return fname;
7616    }
7617
7618    static final int LAST_DONE_VERSION = 10000;
7619
7620    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7621        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7622        File file = getCalledPreBootReceiversFile();
7623        FileInputStream fis = null;
7624        try {
7625            fis = new FileInputStream(file);
7626            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7627            int fvers = dis.readInt();
7628            if (fvers == LAST_DONE_VERSION) {
7629                String vers = dis.readUTF();
7630                String codename = dis.readUTF();
7631                String build = dis.readUTF();
7632                if (android.os.Build.VERSION.RELEASE.equals(vers)
7633                        && android.os.Build.VERSION.CODENAME.equals(codename)
7634                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7635                    int num = dis.readInt();
7636                    while (num > 0) {
7637                        num--;
7638                        String pkg = dis.readUTF();
7639                        String cls = dis.readUTF();
7640                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7641                    }
7642                }
7643            }
7644        } catch (FileNotFoundException e) {
7645        } catch (IOException e) {
7646            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7647        } finally {
7648            if (fis != null) {
7649                try {
7650                    fis.close();
7651                } catch (IOException e) {
7652                }
7653            }
7654        }
7655        return lastDoneReceivers;
7656    }
7657
7658    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7659        File file = getCalledPreBootReceiversFile();
7660        FileOutputStream fos = null;
7661        DataOutputStream dos = null;
7662        try {
7663            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7664            fos = new FileOutputStream(file);
7665            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7666            dos.writeInt(LAST_DONE_VERSION);
7667            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7668            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7669            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7670            dos.writeInt(list.size());
7671            for (int i=0; i<list.size(); i++) {
7672                dos.writeUTF(list.get(i).getPackageName());
7673                dos.writeUTF(list.get(i).getClassName());
7674            }
7675        } catch (IOException e) {
7676            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7677            file.delete();
7678        } finally {
7679            FileUtils.sync(fos);
7680            if (dos != null) {
7681                try {
7682                    dos.close();
7683                } catch (IOException e) {
7684                    // TODO Auto-generated catch block
7685                    e.printStackTrace();
7686                }
7687            }
7688        }
7689    }
7690
7691    public void systemReady(final Runnable goingCallback) {
7692        synchronized(this) {
7693            if (mSystemReady) {
7694                if (goingCallback != null) goingCallback.run();
7695                return;
7696            }
7697
7698            // Check to see if there are any update receivers to run.
7699            if (!mDidUpdate) {
7700                if (mWaitingUpdate) {
7701                    return;
7702                }
7703                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7704                List<ResolveInfo> ris = null;
7705                try {
7706                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7707                            intent, null, 0, 0);
7708                } catch (RemoteException e) {
7709                }
7710                if (ris != null) {
7711                    for (int i=ris.size()-1; i>=0; i--) {
7712                        if ((ris.get(i).activityInfo.applicationInfo.flags
7713                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7714                            ris.remove(i);
7715                        }
7716                    }
7717                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7718
7719                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7720
7721                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7722                    for (int i=0; i<ris.size(); i++) {
7723                        ActivityInfo ai = ris.get(i).activityInfo;
7724                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7725                        if (lastDoneReceivers.contains(comp)) {
7726                            ris.remove(i);
7727                            i--;
7728                        }
7729                    }
7730
7731                    final int[] users = getUsersLocked();
7732                    for (int i=0; i<ris.size(); i++) {
7733                        ActivityInfo ai = ris.get(i).activityInfo;
7734                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7735                        doneReceivers.add(comp);
7736                        intent.setComponent(comp);
7737                        for (int j=0; j<users.length; j++) {
7738                            IIntentReceiver finisher = null;
7739                            if (i == ris.size()-1 && j == users.length-1) {
7740                                finisher = new IIntentReceiver.Stub() {
7741                                    public void performReceive(Intent intent, int resultCode,
7742                                            String data, Bundle extras, boolean ordered,
7743                                            boolean sticky, int sendingUser) {
7744                                        // The raw IIntentReceiver interface is called
7745                                        // with the AM lock held, so redispatch to
7746                                        // execute our code without the lock.
7747                                        mHandler.post(new Runnable() {
7748                                            public void run() {
7749                                                synchronized (ActivityManagerService.this) {
7750                                                    mDidUpdate = true;
7751                                                }
7752                                                writeLastDonePreBootReceivers(doneReceivers);
7753                                                showBootMessage(mContext.getText(
7754                                                        R.string.android_upgrading_complete),
7755                                                        false);
7756                                                systemReady(goingCallback);
7757                                            }
7758                                        });
7759                                    }
7760                                };
7761                            }
7762                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
7763                                    + " for user " + users[j]);
7764                            broadcastIntentLocked(null, null, intent, null, finisher,
7765                                    0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7766                                    users[j]);
7767                            if (finisher != null) {
7768                                mWaitingUpdate = true;
7769                            }
7770                        }
7771                    }
7772                }
7773                if (mWaitingUpdate) {
7774                    return;
7775                }
7776                mDidUpdate = true;
7777            }
7778
7779            mSystemReady = true;
7780            if (!mStartRunning) {
7781                return;
7782            }
7783        }
7784
7785        ArrayList<ProcessRecord> procsToKill = null;
7786        synchronized(mPidsSelfLocked) {
7787            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7788                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7789                if (!isAllowedWhileBooting(proc.info)){
7790                    if (procsToKill == null) {
7791                        procsToKill = new ArrayList<ProcessRecord>();
7792                    }
7793                    procsToKill.add(proc);
7794                }
7795            }
7796        }
7797
7798        synchronized(this) {
7799            if (procsToKill != null) {
7800                for (int i=procsToKill.size()-1; i>=0; i--) {
7801                    ProcessRecord proc = procsToKill.get(i);
7802                    Slog.i(TAG, "Removing system update proc: " + proc);
7803                    removeProcessLocked(proc, true, false, "system update done");
7804                }
7805            }
7806
7807            // Now that we have cleaned up any update processes, we
7808            // are ready to start launching real processes and know that
7809            // we won't trample on them any more.
7810            mProcessesReady = true;
7811        }
7812
7813        Slog.i(TAG, "System now ready");
7814        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7815            SystemClock.uptimeMillis());
7816
7817        synchronized(this) {
7818            // Make sure we have no pre-ready processes sitting around.
7819
7820            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7821                ResolveInfo ri = mContext.getPackageManager()
7822                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7823                                STOCK_PM_FLAGS);
7824                CharSequence errorMsg = null;
7825                if (ri != null) {
7826                    ActivityInfo ai = ri.activityInfo;
7827                    ApplicationInfo app = ai.applicationInfo;
7828                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7829                        mTopAction = Intent.ACTION_FACTORY_TEST;
7830                        mTopData = null;
7831                        mTopComponent = new ComponentName(app.packageName,
7832                                ai.name);
7833                    } else {
7834                        errorMsg = mContext.getResources().getText(
7835                                com.android.internal.R.string.factorytest_not_system);
7836                    }
7837                } else {
7838                    errorMsg = mContext.getResources().getText(
7839                            com.android.internal.R.string.factorytest_no_action);
7840                }
7841                if (errorMsg != null) {
7842                    mTopAction = null;
7843                    mTopData = null;
7844                    mTopComponent = null;
7845                    Message msg = Message.obtain();
7846                    msg.what = SHOW_FACTORY_ERROR_MSG;
7847                    msg.getData().putCharSequence("msg", errorMsg);
7848                    mHandler.sendMessage(msg);
7849                }
7850            }
7851        }
7852
7853        retrieveSettings();
7854
7855        if (goingCallback != null) goingCallback.run();
7856
7857        synchronized (this) {
7858            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7859                try {
7860                    List apps = AppGlobals.getPackageManager().
7861                        getPersistentApplications(STOCK_PM_FLAGS);
7862                    if (apps != null) {
7863                        int N = apps.size();
7864                        int i;
7865                        for (i=0; i<N; i++) {
7866                            ApplicationInfo info
7867                                = (ApplicationInfo)apps.get(i);
7868                            if (info != null &&
7869                                    !info.packageName.equals("android")) {
7870                                addAppLocked(info, false);
7871                            }
7872                        }
7873                    }
7874                } catch (RemoteException ex) {
7875                    // pm is in same process, this will never happen.
7876                }
7877            }
7878
7879            // Start up initial activity.
7880            mBooting = true;
7881
7882            try {
7883                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7884                    Message msg = Message.obtain();
7885                    msg.what = SHOW_UID_ERROR_MSG;
7886                    mHandler.sendMessage(msg);
7887                }
7888            } catch (RemoteException e) {
7889            }
7890
7891            long ident = Binder.clearCallingIdentity();
7892            try {
7893                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
7894                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
7895                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7896                broadcastIntentLocked(null, null, intent,
7897                        null, null, 0, null, null, null,
7898                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
7899            } finally {
7900                Binder.restoreCallingIdentity(ident);
7901            }
7902            mMainStack.resumeTopActivityLocked(null);
7903            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
7904        }
7905    }
7906
7907    private boolean makeAppCrashingLocked(ProcessRecord app,
7908            String shortMsg, String longMsg, String stackTrace) {
7909        app.crashing = true;
7910        app.crashingReport = generateProcessError(app,
7911                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7912        startAppProblemLocked(app);
7913        app.stopFreezingAllLocked();
7914        return handleAppCrashLocked(app);
7915    }
7916
7917    private void makeAppNotRespondingLocked(ProcessRecord app,
7918            String activity, String shortMsg, String longMsg) {
7919        app.notResponding = true;
7920        app.notRespondingReport = generateProcessError(app,
7921                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7922                activity, shortMsg, longMsg, null);
7923        startAppProblemLocked(app);
7924        app.stopFreezingAllLocked();
7925    }
7926
7927    /**
7928     * Generate a process error record, suitable for attachment to a ProcessRecord.
7929     *
7930     * @param app The ProcessRecord in which the error occurred.
7931     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7932     *                      ActivityManager.AppErrorStateInfo
7933     * @param activity The activity associated with the crash, if known.
7934     * @param shortMsg Short message describing the crash.
7935     * @param longMsg Long message describing the crash.
7936     * @param stackTrace Full crash stack trace, may be null.
7937     *
7938     * @return Returns a fully-formed AppErrorStateInfo record.
7939     */
7940    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7941            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7942        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7943
7944        report.condition = condition;
7945        report.processName = app.processName;
7946        report.pid = app.pid;
7947        report.uid = app.info.uid;
7948        report.tag = activity;
7949        report.shortMsg = shortMsg;
7950        report.longMsg = longMsg;
7951        report.stackTrace = stackTrace;
7952
7953        return report;
7954    }
7955
7956    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7957        synchronized (this) {
7958            app.crashing = false;
7959            app.crashingReport = null;
7960            app.notResponding = false;
7961            app.notRespondingReport = null;
7962            if (app.anrDialog == fromDialog) {
7963                app.anrDialog = null;
7964            }
7965            if (app.waitDialog == fromDialog) {
7966                app.waitDialog = null;
7967            }
7968            if (app.pid > 0 && app.pid != MY_PID) {
7969                handleAppCrashLocked(app);
7970                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7971                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7972                        app.processName, app.setAdj, "user's request after error");
7973                Process.killProcessQuiet(app.pid);
7974            }
7975        }
7976    }
7977
7978    private boolean handleAppCrashLocked(ProcessRecord app) {
7979        if (mHeadless) {
7980            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7981            return false;
7982        }
7983        long now = SystemClock.uptimeMillis();
7984
7985        Long crashTime;
7986        if (!app.isolated) {
7987            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7988        } else {
7989            crashTime = null;
7990        }
7991        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7992            // This process loses!
7993            Slog.w(TAG, "Process " + app.info.processName
7994                    + " has crashed too many times: killing!");
7995            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7996                    app.info.processName, app.uid);
7997            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7998                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7999                if (r.app == app) {
8000                    Slog.w(TAG, "  Force finishing activity "
8001                        + r.intent.getComponent().flattenToShortString());
8002                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
8003                            null, "crashed", false);
8004                }
8005            }
8006            if (!app.persistent) {
8007                // We don't want to start this process again until the user
8008                // explicitly does so...  but for persistent process, we really
8009                // need to keep it running.  If a persistent process is actually
8010                // repeatedly crashing, then badness for everyone.
8011                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
8012                        app.info.processName);
8013                if (!app.isolated) {
8014                    // XXX We don't have a way to mark isolated processes
8015                    // as bad, since they don't have a peristent identity.
8016                    mBadProcesses.put(app.info.processName, app.uid, now);
8017                    mProcessCrashTimes.remove(app.info.processName, app.uid);
8018                }
8019                app.bad = true;
8020                app.removed = true;
8021                // Don't let services in this process be restarted and potentially
8022                // annoy the user repeatedly.  Unless it is persistent, since those
8023                // processes run critical code.
8024                removeProcessLocked(app, false, false, "crash");
8025                mMainStack.resumeTopActivityLocked(null);
8026                return false;
8027            }
8028            mMainStack.resumeTopActivityLocked(null);
8029        } else {
8030            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
8031            if (r != null && r.app == app) {
8032                // If the top running activity is from this crashing
8033                // process, then terminate it to avoid getting in a loop.
8034                Slog.w(TAG, "  Force finishing activity "
8035                        + r.intent.getComponent().flattenToShortString());
8036                int index = mMainStack.indexOfActivityLocked(r);
8037                r.stack.finishActivityLocked(r, index,
8038                        Activity.RESULT_CANCELED, null, "crashed", false);
8039                // Also terminate any activities below it that aren't yet
8040                // stopped, to avoid a situation where one will get
8041                // re-start our crashing activity once it gets resumed again.
8042                index--;
8043                if (index >= 0) {
8044                    r = (ActivityRecord)mMainStack.mHistory.get(index);
8045                    if (r.state == ActivityState.RESUMED
8046                            || r.state == ActivityState.PAUSING
8047                            || r.state == ActivityState.PAUSED) {
8048                        if (!r.isHomeActivity || mHomeProcess != r.app) {
8049                            Slog.w(TAG, "  Force finishing activity "
8050                                    + r.intent.getComponent().flattenToShortString());
8051                            r.stack.finishActivityLocked(r, index,
8052                                    Activity.RESULT_CANCELED, null, "crashed", false);
8053                        }
8054                    }
8055                }
8056            }
8057        }
8058
8059        // Bump up the crash count of any services currently running in the proc.
8060        if (app.services.size() != 0) {
8061            // Any services running in the application need to be placed
8062            // back in the pending list.
8063            Iterator<ServiceRecord> it = app.services.iterator();
8064            while (it.hasNext()) {
8065                ServiceRecord sr = it.next();
8066                sr.crashCount++;
8067            }
8068        }
8069
8070        // If the crashing process is what we consider to be the "home process" and it has been
8071        // replaced by a third-party app, clear the package preferred activities from packages
8072        // with a home activity running in the process to prevent a repeatedly crashing app
8073        // from blocking the user to manually clear the list.
8074        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8075                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8076            Iterator it = mHomeProcess.activities.iterator();
8077            while (it.hasNext()) {
8078                ActivityRecord r = (ActivityRecord)it.next();
8079                if (r.isHomeActivity) {
8080                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8081                    try {
8082                        ActivityThread.getPackageManager()
8083                                .clearPackagePreferredActivities(r.packageName);
8084                    } catch (RemoteException c) {
8085                        // pm is in same process, this will never happen.
8086                    }
8087                }
8088            }
8089        }
8090
8091        if (!app.isolated) {
8092            // XXX Can't keep track of crash times for isolated processes,
8093            // because they don't have a perisistent identity.
8094            mProcessCrashTimes.put(app.info.processName, app.uid, now);
8095        }
8096
8097        return true;
8098    }
8099
8100    void startAppProblemLocked(ProcessRecord app) {
8101        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8102                mContext, app.info.packageName, app.info.flags);
8103        skipCurrentReceiverLocked(app);
8104    }
8105
8106    void skipCurrentReceiverLocked(ProcessRecord app) {
8107        for (BroadcastQueue queue : mBroadcastQueues) {
8108            queue.skipCurrentReceiverLocked(app);
8109        }
8110    }
8111
8112    /**
8113     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8114     * The application process will exit immediately after this call returns.
8115     * @param app object of the crashing app, null for the system server
8116     * @param crashInfo describing the exception
8117     */
8118    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8119        ProcessRecord r = findAppProcess(app, "Crash");
8120        final String processName = app == null ? "system_server"
8121                : (r == null ? "unknown" : r.processName);
8122
8123        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8124                processName,
8125                r == null ? -1 : r.info.flags,
8126                crashInfo.exceptionClassName,
8127                crashInfo.exceptionMessage,
8128                crashInfo.throwFileName,
8129                crashInfo.throwLineNumber);
8130
8131        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
8132
8133        crashApplication(r, crashInfo);
8134    }
8135
8136    public void handleApplicationStrictModeViolation(
8137            IBinder app,
8138            int violationMask,
8139            StrictMode.ViolationInfo info) {
8140        ProcessRecord r = findAppProcess(app, "StrictMode");
8141        if (r == null) {
8142            return;
8143        }
8144
8145        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8146            Integer stackFingerprint = info.hashCode();
8147            boolean logIt = true;
8148            synchronized (mAlreadyLoggedViolatedStacks) {
8149                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8150                    logIt = false;
8151                    // TODO: sub-sample into EventLog for these, with
8152                    // the info.durationMillis?  Then we'd get
8153                    // the relative pain numbers, without logging all
8154                    // the stack traces repeatedly.  We'd want to do
8155                    // likewise in the client code, which also does
8156                    // dup suppression, before the Binder call.
8157                } else {
8158                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8159                        mAlreadyLoggedViolatedStacks.clear();
8160                    }
8161                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8162                }
8163            }
8164            if (logIt) {
8165                logStrictModeViolationToDropBox(r, info);
8166            }
8167        }
8168
8169        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8170            AppErrorResult result = new AppErrorResult();
8171            synchronized (this) {
8172                final long origId = Binder.clearCallingIdentity();
8173
8174                Message msg = Message.obtain();
8175                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8176                HashMap<String, Object> data = new HashMap<String, Object>();
8177                data.put("result", result);
8178                data.put("app", r);
8179                data.put("violationMask", violationMask);
8180                data.put("info", info);
8181                msg.obj = data;
8182                mHandler.sendMessage(msg);
8183
8184                Binder.restoreCallingIdentity(origId);
8185            }
8186            int res = result.get();
8187            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8188        }
8189    }
8190
8191    // Depending on the policy in effect, there could be a bunch of
8192    // these in quick succession so we try to batch these together to
8193    // minimize disk writes, number of dropbox entries, and maximize
8194    // compression, by having more fewer, larger records.
8195    private void logStrictModeViolationToDropBox(
8196            ProcessRecord process,
8197            StrictMode.ViolationInfo info) {
8198        if (info == null) {
8199            return;
8200        }
8201        final boolean isSystemApp = process == null ||
8202                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8203                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8204        final String processName = process == null ? "unknown" : process.processName;
8205        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8206        final DropBoxManager dbox = (DropBoxManager)
8207                mContext.getSystemService(Context.DROPBOX_SERVICE);
8208
8209        // Exit early if the dropbox isn't configured to accept this report type.
8210        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8211
8212        boolean bufferWasEmpty;
8213        boolean needsFlush;
8214        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8215        synchronized (sb) {
8216            bufferWasEmpty = sb.length() == 0;
8217            appendDropBoxProcessHeaders(process, processName, sb);
8218            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8219            sb.append("System-App: ").append(isSystemApp).append("\n");
8220            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8221            if (info.violationNumThisLoop != 0) {
8222                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8223            }
8224            if (info.numAnimationsRunning != 0) {
8225                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8226            }
8227            if (info.broadcastIntentAction != null) {
8228                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8229            }
8230            if (info.durationMillis != -1) {
8231                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8232            }
8233            if (info.numInstances != -1) {
8234                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8235            }
8236            if (info.tags != null) {
8237                for (String tag : info.tags) {
8238                    sb.append("Span-Tag: ").append(tag).append("\n");
8239                }
8240            }
8241            sb.append("\n");
8242            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8243                sb.append(info.crashInfo.stackTrace);
8244            }
8245            sb.append("\n");
8246
8247            // Only buffer up to ~64k.  Various logging bits truncate
8248            // things at 128k.
8249            needsFlush = (sb.length() > 64 * 1024);
8250        }
8251
8252        // Flush immediately if the buffer's grown too large, or this
8253        // is a non-system app.  Non-system apps are isolated with a
8254        // different tag & policy and not batched.
8255        //
8256        // Batching is useful during internal testing with
8257        // StrictMode settings turned up high.  Without batching,
8258        // thousands of separate files could be created on boot.
8259        if (!isSystemApp || needsFlush) {
8260            new Thread("Error dump: " + dropboxTag) {
8261                @Override
8262                public void run() {
8263                    String report;
8264                    synchronized (sb) {
8265                        report = sb.toString();
8266                        sb.delete(0, sb.length());
8267                        sb.trimToSize();
8268                    }
8269                    if (report.length() != 0) {
8270                        dbox.addText(dropboxTag, report);
8271                    }
8272                }
8273            }.start();
8274            return;
8275        }
8276
8277        // System app batching:
8278        if (!bufferWasEmpty) {
8279            // An existing dropbox-writing thread is outstanding, so
8280            // we don't need to start it up.  The existing thread will
8281            // catch the buffer appends we just did.
8282            return;
8283        }
8284
8285        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8286        // (After this point, we shouldn't access AMS internal data structures.)
8287        new Thread("Error dump: " + dropboxTag) {
8288            @Override
8289            public void run() {
8290                // 5 second sleep to let stacks arrive and be batched together
8291                try {
8292                    Thread.sleep(5000);  // 5 seconds
8293                } catch (InterruptedException e) {}
8294
8295                String errorReport;
8296                synchronized (mStrictModeBuffer) {
8297                    errorReport = mStrictModeBuffer.toString();
8298                    if (errorReport.length() == 0) {
8299                        return;
8300                    }
8301                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8302                    mStrictModeBuffer.trimToSize();
8303                }
8304                dbox.addText(dropboxTag, errorReport);
8305            }
8306        }.start();
8307    }
8308
8309    /**
8310     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8311     * @param app object of the crashing app, null for the system server
8312     * @param tag reported by the caller
8313     * @param crashInfo describing the context of the error
8314     * @return true if the process should exit immediately (WTF is fatal)
8315     */
8316    public boolean handleApplicationWtf(IBinder app, String tag,
8317            ApplicationErrorReport.CrashInfo crashInfo) {
8318        ProcessRecord r = findAppProcess(app, "WTF");
8319        final String processName = app == null ? "system_server"
8320                : (r == null ? "unknown" : r.processName);
8321
8322        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8323                processName,
8324                r == null ? -1 : r.info.flags,
8325                tag, crashInfo.exceptionMessage);
8326
8327        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8328
8329        if (r != null && r.pid != Process.myPid() &&
8330                Settings.Secure.getInt(mContext.getContentResolver(),
8331                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8332            crashApplication(r, crashInfo);
8333            return true;
8334        } else {
8335            return false;
8336        }
8337    }
8338
8339    /**
8340     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8341     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8342     */
8343    private ProcessRecord findAppProcess(IBinder app, String reason) {
8344        if (app == null) {
8345            return null;
8346        }
8347
8348        synchronized (this) {
8349            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8350                final int NA = apps.size();
8351                for (int ia=0; ia<NA; ia++) {
8352                    ProcessRecord p = apps.valueAt(ia);
8353                    if (p.thread != null && p.thread.asBinder() == app) {
8354                        return p;
8355                    }
8356                }
8357            }
8358
8359            Slog.w(TAG, "Can't find mystery application for " + reason
8360                    + " from pid=" + Binder.getCallingPid()
8361                    + " uid=" + Binder.getCallingUid() + ": " + app);
8362            return null;
8363        }
8364    }
8365
8366    /**
8367     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8368     * to append various headers to the dropbox log text.
8369     */
8370    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8371            StringBuilder sb) {
8372        // Watchdog thread ends up invoking this function (with
8373        // a null ProcessRecord) to add the stack file to dropbox.
8374        // Do not acquire a lock on this (am) in such cases, as it
8375        // could cause a potential deadlock, if and when watchdog
8376        // is invoked due to unavailability of lock on am and it
8377        // would prevent watchdog from killing system_server.
8378        if (process == null) {
8379            sb.append("Process: ").append(processName).append("\n");
8380            return;
8381        }
8382        // Note: ProcessRecord 'process' is guarded by the service
8383        // instance.  (notably process.pkgList, which could otherwise change
8384        // concurrently during execution of this method)
8385        synchronized (this) {
8386            sb.append("Process: ").append(processName).append("\n");
8387            int flags = process.info.flags;
8388            IPackageManager pm = AppGlobals.getPackageManager();
8389            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8390            for (String pkg : process.pkgList) {
8391                sb.append("Package: ").append(pkg);
8392                try {
8393                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8394                    if (pi != null) {
8395                        sb.append(" v").append(pi.versionCode);
8396                        if (pi.versionName != null) {
8397                            sb.append(" (").append(pi.versionName).append(")");
8398                        }
8399                    }
8400                } catch (RemoteException e) {
8401                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8402                }
8403                sb.append("\n");
8404            }
8405        }
8406    }
8407
8408    private static String processClass(ProcessRecord process) {
8409        if (process == null || process.pid == MY_PID) {
8410            return "system_server";
8411        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8412            return "system_app";
8413        } else {
8414            return "data_app";
8415        }
8416    }
8417
8418    /**
8419     * Write a description of an error (crash, WTF, ANR) to the drop box.
8420     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8421     * @param process which caused the error, null means the system server
8422     * @param activity which triggered the error, null if unknown
8423     * @param parent activity related to the error, null if unknown
8424     * @param subject line related to the error, null if absent
8425     * @param report in long form describing the error, null if absent
8426     * @param logFile to include in the report, null if none
8427     * @param crashInfo giving an application stack trace, null if absent
8428     */
8429    public void addErrorToDropBox(String eventType,
8430            ProcessRecord process, String processName, ActivityRecord activity,
8431            ActivityRecord parent, String subject,
8432            final String report, final File logFile,
8433            final ApplicationErrorReport.CrashInfo crashInfo) {
8434        // NOTE -- this must never acquire the ActivityManagerService lock,
8435        // otherwise the watchdog may be prevented from resetting the system.
8436
8437        final String dropboxTag = processClass(process) + "_" + eventType;
8438        final DropBoxManager dbox = (DropBoxManager)
8439                mContext.getSystemService(Context.DROPBOX_SERVICE);
8440
8441        // Exit early if the dropbox isn't configured to accept this report type.
8442        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8443
8444        final StringBuilder sb = new StringBuilder(1024);
8445        appendDropBoxProcessHeaders(process, processName, sb);
8446        if (activity != null) {
8447            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8448        }
8449        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8450            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8451        }
8452        if (parent != null && parent != activity) {
8453            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8454        }
8455        if (subject != null) {
8456            sb.append("Subject: ").append(subject).append("\n");
8457        }
8458        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8459        if (Debug.isDebuggerConnected()) {
8460            sb.append("Debugger: Connected\n");
8461        }
8462        sb.append("\n");
8463
8464        // Do the rest in a worker thread to avoid blocking the caller on I/O
8465        // (After this point, we shouldn't access AMS internal data structures.)
8466        Thread worker = new Thread("Error dump: " + dropboxTag) {
8467            @Override
8468            public void run() {
8469                if (report != null) {
8470                    sb.append(report);
8471                }
8472                if (logFile != null) {
8473                    try {
8474                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8475                    } catch (IOException e) {
8476                        Slog.e(TAG, "Error reading " + logFile, e);
8477                    }
8478                }
8479                if (crashInfo != null && crashInfo.stackTrace != null) {
8480                    sb.append(crashInfo.stackTrace);
8481                }
8482
8483                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8484                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8485                if (lines > 0) {
8486                    sb.append("\n");
8487
8488                    // Merge several logcat streams, and take the last N lines
8489                    InputStreamReader input = null;
8490                    try {
8491                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8492                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8493                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8494
8495                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8496                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8497                        input = new InputStreamReader(logcat.getInputStream());
8498
8499                        int num;
8500                        char[] buf = new char[8192];
8501                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8502                    } catch (IOException e) {
8503                        Slog.e(TAG, "Error running logcat", e);
8504                    } finally {
8505                        if (input != null) try { input.close(); } catch (IOException e) {}
8506                    }
8507                }
8508
8509                dbox.addText(dropboxTag, sb.toString());
8510            }
8511        };
8512
8513        if (process == null) {
8514            // If process is null, we are being called from some internal code
8515            // and may be about to die -- run this synchronously.
8516            worker.run();
8517        } else {
8518            worker.start();
8519        }
8520    }
8521
8522    /**
8523     * Bring up the "unexpected error" dialog box for a crashing app.
8524     * Deal with edge cases (intercepts from instrumented applications,
8525     * ActivityController, error intent receivers, that sort of thing).
8526     * @param r the application crashing
8527     * @param crashInfo describing the failure
8528     */
8529    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8530        long timeMillis = System.currentTimeMillis();
8531        String shortMsg = crashInfo.exceptionClassName;
8532        String longMsg = crashInfo.exceptionMessage;
8533        String stackTrace = crashInfo.stackTrace;
8534        if (shortMsg != null && longMsg != null) {
8535            longMsg = shortMsg + ": " + longMsg;
8536        } else if (shortMsg != null) {
8537            longMsg = shortMsg;
8538        }
8539
8540        AppErrorResult result = new AppErrorResult();
8541        synchronized (this) {
8542            if (mController != null) {
8543                try {
8544                    String name = r != null ? r.processName : null;
8545                    int pid = r != null ? r.pid : Binder.getCallingPid();
8546                    if (!mController.appCrashed(name, pid,
8547                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8548                        Slog.w(TAG, "Force-killing crashed app " + name
8549                                + " at watcher's request");
8550                        Process.killProcess(pid);
8551                        return;
8552                    }
8553                } catch (RemoteException e) {
8554                    mController = null;
8555                }
8556            }
8557
8558            final long origId = Binder.clearCallingIdentity();
8559
8560            // If this process is running instrumentation, finish it.
8561            if (r != null && r.instrumentationClass != null) {
8562                Slog.w(TAG, "Error in app " + r.processName
8563                      + " running instrumentation " + r.instrumentationClass + ":");
8564                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8565                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8566                Bundle info = new Bundle();
8567                info.putString("shortMsg", shortMsg);
8568                info.putString("longMsg", longMsg);
8569                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8570                Binder.restoreCallingIdentity(origId);
8571                return;
8572            }
8573
8574            // If we can't identify the process or it's already exceeded its crash quota,
8575            // quit right away without showing a crash dialog.
8576            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8577                Binder.restoreCallingIdentity(origId);
8578                return;
8579            }
8580
8581            Message msg = Message.obtain();
8582            msg.what = SHOW_ERROR_MSG;
8583            HashMap data = new HashMap();
8584            data.put("result", result);
8585            data.put("app", r);
8586            msg.obj = data;
8587            mHandler.sendMessage(msg);
8588
8589            Binder.restoreCallingIdentity(origId);
8590        }
8591
8592        int res = result.get();
8593
8594        Intent appErrorIntent = null;
8595        synchronized (this) {
8596            if (r != null && !r.isolated) {
8597                // XXX Can't keep track of crash time for isolated processes,
8598                // since they don't have a persistent identity.
8599                mProcessCrashTimes.put(r.info.processName, r.uid,
8600                        SystemClock.uptimeMillis());
8601            }
8602            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8603                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8604            }
8605        }
8606
8607        if (appErrorIntent != null) {
8608            try {
8609                mContext.startActivity(appErrorIntent);
8610            } catch (ActivityNotFoundException e) {
8611                Slog.w(TAG, "bug report receiver dissappeared", e);
8612            }
8613        }
8614    }
8615
8616    Intent createAppErrorIntentLocked(ProcessRecord r,
8617            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8618        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8619        if (report == null) {
8620            return null;
8621        }
8622        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8623        result.setComponent(r.errorReportReceiver);
8624        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8625        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8626        return result;
8627    }
8628
8629    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8630            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8631        if (r.errorReportReceiver == null) {
8632            return null;
8633        }
8634
8635        if (!r.crashing && !r.notResponding) {
8636            return null;
8637        }
8638
8639        ApplicationErrorReport report = new ApplicationErrorReport();
8640        report.packageName = r.info.packageName;
8641        report.installerPackageName = r.errorReportReceiver.getPackageName();
8642        report.processName = r.processName;
8643        report.time = timeMillis;
8644        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8645
8646        if (r.crashing) {
8647            report.type = ApplicationErrorReport.TYPE_CRASH;
8648            report.crashInfo = crashInfo;
8649        } else if (r.notResponding) {
8650            report.type = ApplicationErrorReport.TYPE_ANR;
8651            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8652
8653            report.anrInfo.activity = r.notRespondingReport.tag;
8654            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8655            report.anrInfo.info = r.notRespondingReport.longMsg;
8656        }
8657
8658        return report;
8659    }
8660
8661    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8662        enforceNotIsolatedCaller("getProcessesInErrorState");
8663        // assume our apps are happy - lazy create the list
8664        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8665
8666        final boolean allUsers = ActivityManager.checkUidPermission(
8667                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8668                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8669        int userId = UserHandle.getUserId(Binder.getCallingUid());
8670
8671        synchronized (this) {
8672
8673            // iterate across all processes
8674            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8675                ProcessRecord app = mLruProcesses.get(i);
8676                if (!allUsers && app.userId != userId) {
8677                    continue;
8678                }
8679                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8680                    // This one's in trouble, so we'll generate a report for it
8681                    // crashes are higher priority (in case there's a crash *and* an anr)
8682                    ActivityManager.ProcessErrorStateInfo report = null;
8683                    if (app.crashing) {
8684                        report = app.crashingReport;
8685                    } else if (app.notResponding) {
8686                        report = app.notRespondingReport;
8687                    }
8688
8689                    if (report != null) {
8690                        if (errList == null) {
8691                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8692                        }
8693                        errList.add(report);
8694                    } else {
8695                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8696                                " crashing = " + app.crashing +
8697                                " notResponding = " + app.notResponding);
8698                    }
8699                }
8700            }
8701        }
8702
8703        return errList;
8704    }
8705
8706    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8707        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8708            if (currApp != null) {
8709                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8710            }
8711            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8712        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8713            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8714        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8715            if (currApp != null) {
8716                currApp.lru = 0;
8717            }
8718            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8719        } else if (adj >= ProcessList.SERVICE_ADJ) {
8720            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8721        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8722            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8723        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8724            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8725        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8726            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8727        } else {
8728            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8729        }
8730    }
8731
8732    private void fillInProcMemInfo(ProcessRecord app,
8733            ActivityManager.RunningAppProcessInfo outInfo) {
8734        outInfo.pid = app.pid;
8735        outInfo.uid = app.info.uid;
8736        if (mHeavyWeightProcess == app) {
8737            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8738        }
8739        if (app.persistent) {
8740            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8741        }
8742        if (app.hasActivities) {
8743            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8744        }
8745        outInfo.lastTrimLevel = app.trimMemoryLevel;
8746        int adj = app.curAdj;
8747        outInfo.importance = oomAdjToImportance(adj, outInfo);
8748        outInfo.importanceReasonCode = app.adjTypeCode;
8749    }
8750
8751    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8752        enforceNotIsolatedCaller("getRunningAppProcesses");
8753        // Lazy instantiation of list
8754        List<ActivityManager.RunningAppProcessInfo> runList = null;
8755        final boolean allUsers = ActivityManager.checkUidPermission(
8756                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8757                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8758        int userId = UserHandle.getUserId(Binder.getCallingUid());
8759        synchronized (this) {
8760            // Iterate across all processes
8761            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8762                ProcessRecord app = mLruProcesses.get(i);
8763                if (!allUsers && app.userId != userId) {
8764                    continue;
8765                }
8766                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8767                    // Generate process state info for running application
8768                    ActivityManager.RunningAppProcessInfo currApp =
8769                        new ActivityManager.RunningAppProcessInfo(app.processName,
8770                                app.pid, app.getPackageList());
8771                    fillInProcMemInfo(app, currApp);
8772                    if (app.adjSource instanceof ProcessRecord) {
8773                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8774                        currApp.importanceReasonImportance = oomAdjToImportance(
8775                                app.adjSourceOom, null);
8776                    } else if (app.adjSource instanceof ActivityRecord) {
8777                        ActivityRecord r = (ActivityRecord)app.adjSource;
8778                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8779                    }
8780                    if (app.adjTarget instanceof ComponentName) {
8781                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8782                    }
8783                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8784                    //        + " lru=" + currApp.lru);
8785                    if (runList == null) {
8786                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8787                    }
8788                    runList.add(currApp);
8789                }
8790            }
8791        }
8792        return runList;
8793    }
8794
8795    public List<ApplicationInfo> getRunningExternalApplications() {
8796        enforceNotIsolatedCaller("getRunningExternalApplications");
8797        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8798        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8799        if (runningApps != null && runningApps.size() > 0) {
8800            Set<String> extList = new HashSet<String>();
8801            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8802                if (app.pkgList != null) {
8803                    for (String pkg : app.pkgList) {
8804                        extList.add(pkg);
8805                    }
8806                }
8807            }
8808            IPackageManager pm = AppGlobals.getPackageManager();
8809            for (String pkg : extList) {
8810                try {
8811                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8812                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8813                        retList.add(info);
8814                    }
8815                } catch (RemoteException e) {
8816                }
8817            }
8818        }
8819        return retList;
8820    }
8821
8822    @Override
8823    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8824        enforceNotIsolatedCaller("getMyMemoryState");
8825        synchronized (this) {
8826            ProcessRecord proc;
8827            synchronized (mPidsSelfLocked) {
8828                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8829            }
8830            fillInProcMemInfo(proc, outInfo);
8831        }
8832    }
8833
8834    @Override
8835    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8836        if (checkCallingPermission(android.Manifest.permission.DUMP)
8837                != PackageManager.PERMISSION_GRANTED) {
8838            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8839                    + Binder.getCallingPid()
8840                    + ", uid=" + Binder.getCallingUid()
8841                    + " without permission "
8842                    + android.Manifest.permission.DUMP);
8843            return;
8844        }
8845
8846        boolean dumpAll = false;
8847        boolean dumpClient = false;
8848        String dumpPackage = null;
8849
8850        int opti = 0;
8851        while (opti < args.length) {
8852            String opt = args[opti];
8853            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8854                break;
8855            }
8856            opti++;
8857            if ("-a".equals(opt)) {
8858                dumpAll = true;
8859            } else if ("-c".equals(opt)) {
8860                dumpClient = true;
8861            } else if ("-h".equals(opt)) {
8862                pw.println("Activity manager dump options:");
8863                pw.println("  [-a] [-c] [-h] [cmd] ...");
8864                pw.println("  cmd may be one of:");
8865                pw.println("    a[ctivities]: activity stack state");
8866                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8867                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8868                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8869                pw.println("    o[om]: out of memory management");
8870                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8871                pw.println("    provider [COMP_SPEC]: provider client-side state");
8872                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8873                pw.println("    service [COMP_SPEC]: service client-side state");
8874                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8875                pw.println("    all: dump all activities");
8876                pw.println("    top: dump the top activity");
8877                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8878                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8879                pw.println("    a partial substring in a component name, a");
8880                pw.println("    hex object identifier.");
8881                pw.println("  -a: include all available server state.");
8882                pw.println("  -c: include client state.");
8883                return;
8884            } else {
8885                pw.println("Unknown argument: " + opt + "; use -h for help");
8886            }
8887        }
8888
8889        long origId = Binder.clearCallingIdentity();
8890        boolean more = false;
8891        // Is the caller requesting to dump a particular piece of data?
8892        if (opti < args.length) {
8893            String cmd = args[opti];
8894            opti++;
8895            if ("activities".equals(cmd) || "a".equals(cmd)) {
8896                synchronized (this) {
8897                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8898                }
8899            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8900                String[] newArgs;
8901                String name;
8902                if (opti >= args.length) {
8903                    name = null;
8904                    newArgs = EMPTY_STRING_ARRAY;
8905                } else {
8906                    name = args[opti];
8907                    opti++;
8908                    newArgs = new String[args.length - opti];
8909                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8910                            args.length - opti);
8911                }
8912                synchronized (this) {
8913                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8914                }
8915            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8916                String[] newArgs;
8917                String name;
8918                if (opti >= args.length) {
8919                    name = null;
8920                    newArgs = EMPTY_STRING_ARRAY;
8921                } else {
8922                    name = args[opti];
8923                    opti++;
8924                    newArgs = new String[args.length - opti];
8925                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8926                            args.length - opti);
8927                }
8928                synchronized (this) {
8929                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8930                }
8931            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8932                String[] newArgs;
8933                String name;
8934                if (opti >= args.length) {
8935                    name = null;
8936                    newArgs = EMPTY_STRING_ARRAY;
8937                } else {
8938                    name = args[opti];
8939                    opti++;
8940                    newArgs = new String[args.length - opti];
8941                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8942                            args.length - opti);
8943                }
8944                synchronized (this) {
8945                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8946                }
8947            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8948                synchronized (this) {
8949                    dumpOomLocked(fd, pw, args, opti, true);
8950                }
8951            } else if ("provider".equals(cmd)) {
8952                String[] newArgs;
8953                String name;
8954                if (opti >= args.length) {
8955                    name = null;
8956                    newArgs = EMPTY_STRING_ARRAY;
8957                } else {
8958                    name = args[opti];
8959                    opti++;
8960                    newArgs = new String[args.length - opti];
8961                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8962                }
8963                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8964                    pw.println("No providers match: " + name);
8965                    pw.println("Use -h for help.");
8966                }
8967            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8968                synchronized (this) {
8969                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8970                }
8971            } else if ("service".equals(cmd)) {
8972                String[] newArgs;
8973                String name;
8974                if (opti >= args.length) {
8975                    name = null;
8976                    newArgs = EMPTY_STRING_ARRAY;
8977                } else {
8978                    name = args[opti];
8979                    opti++;
8980                    newArgs = new String[args.length - opti];
8981                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8982                            args.length - opti);
8983                }
8984                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8985                    pw.println("No services match: " + name);
8986                    pw.println("Use -h for help.");
8987                }
8988            } else if ("package".equals(cmd)) {
8989                String[] newArgs;
8990                if (opti >= args.length) {
8991                    pw.println("package: no package name specified");
8992                    pw.println("Use -h for help.");
8993                } else {
8994                    dumpPackage = args[opti];
8995                    opti++;
8996                    newArgs = new String[args.length - opti];
8997                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8998                            args.length - opti);
8999                    args = newArgs;
9000                    opti = 0;
9001                    more = true;
9002                }
9003            } else if ("services".equals(cmd) || "s".equals(cmd)) {
9004                synchronized (this) {
9005                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
9006                }
9007            } else {
9008                // Dumping a single activity?
9009                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
9010                    pw.println("Bad activity command, or no activities match: " + cmd);
9011                    pw.println("Use -h for help.");
9012                }
9013            }
9014            if (!more) {
9015                Binder.restoreCallingIdentity(origId);
9016                return;
9017            }
9018        }
9019
9020        // No piece of data specified, dump everything.
9021        synchronized (this) {
9022            boolean needSep;
9023            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9024            if (needSep) {
9025                pw.println(" ");
9026            }
9027            if (dumpAll) {
9028                pw.println("-------------------------------------------------------------------------------");
9029            }
9030            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9031            if (needSep) {
9032                pw.println(" ");
9033            }
9034            if (dumpAll) {
9035                pw.println("-------------------------------------------------------------------------------");
9036            }
9037            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9038            if (needSep) {
9039                pw.println(" ");
9040            }
9041            if (dumpAll) {
9042                pw.println("-------------------------------------------------------------------------------");
9043            }
9044            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9045            if (needSep) {
9046                pw.println(" ");
9047            }
9048            if (dumpAll) {
9049                pw.println("-------------------------------------------------------------------------------");
9050            }
9051            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9052            if (needSep) {
9053                pw.println(" ");
9054            }
9055            if (dumpAll) {
9056                pw.println("-------------------------------------------------------------------------------");
9057            }
9058            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9059        }
9060        Binder.restoreCallingIdentity(origId);
9061    }
9062
9063    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9064            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9065        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9066        pw.println("  Main stack:");
9067        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
9068                dumpPackage);
9069        pw.println(" ");
9070        pw.println("  Running activities (most recent first):");
9071        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
9072                dumpPackage);
9073        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
9074            pw.println(" ");
9075            pw.println("  Activities waiting for another to become visible:");
9076            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
9077                    !dumpAll, false, dumpPackage);
9078        }
9079        if (mMainStack.mStoppingActivities.size() > 0) {
9080            pw.println(" ");
9081            pw.println("  Activities waiting to stop:");
9082            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
9083                    !dumpAll, false, dumpPackage);
9084        }
9085        if (mMainStack.mGoingToSleepActivities.size() > 0) {
9086            pw.println(" ");
9087            pw.println("  Activities waiting to sleep:");
9088            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
9089                    !dumpAll, false, dumpPackage);
9090        }
9091        if (mMainStack.mFinishingActivities.size() > 0) {
9092            pw.println(" ");
9093            pw.println("  Activities waiting to finish:");
9094            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
9095                    !dumpAll, false, dumpPackage);
9096        }
9097
9098        pw.println(" ");
9099        if (mMainStack.mPausingActivity != null) {
9100            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
9101        }
9102        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
9103        pw.println("  mFocusedActivity: " + mFocusedActivity);
9104        if (dumpAll) {
9105            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9106            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
9107            pw.println("  mDismissKeyguardOnNextActivity: "
9108                    + mMainStack.mDismissKeyguardOnNextActivity);
9109        }
9110
9111        if (mRecentTasks.size() > 0) {
9112            pw.println();
9113            pw.println("  Recent tasks:");
9114
9115            final int N = mRecentTasks.size();
9116            for (int i=0; i<N; i++) {
9117                TaskRecord tr = mRecentTasks.get(i);
9118                if (dumpPackage != null) {
9119                    if (tr.realActivity == null ||
9120                            !dumpPackage.equals(tr.realActivity)) {
9121                        continue;
9122                    }
9123                }
9124                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9125                        pw.println(tr);
9126                if (dumpAll) {
9127                    mRecentTasks.get(i).dump(pw, "    ");
9128                }
9129            }
9130        }
9131
9132        if (dumpAll) {
9133            pw.println(" ");
9134            pw.println("  mCurTask: " + mCurTask);
9135        }
9136
9137        return true;
9138    }
9139
9140    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9141            int opti, boolean dumpAll, String dumpPackage) {
9142        boolean needSep = false;
9143        int numPers = 0;
9144
9145        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9146
9147        if (dumpAll) {
9148            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9149                final int NA = procs.size();
9150                for (int ia=0; ia<NA; ia++) {
9151                    ProcessRecord r = procs.valueAt(ia);
9152                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9153                        continue;
9154                    }
9155                    if (!needSep) {
9156                        pw.println("  All known processes:");
9157                        needSep = true;
9158                    }
9159                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9160                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9161                        pw.print(" "); pw.println(r);
9162                    r.dump(pw, "    ");
9163                    if (r.persistent) {
9164                        numPers++;
9165                    }
9166                }
9167            }
9168        }
9169
9170        if (mIsolatedProcesses.size() > 0) {
9171            if (needSep) pw.println(" ");
9172            needSep = true;
9173            pw.println("  Isolated process list (sorted by uid):");
9174            for (int i=0; i<mIsolatedProcesses.size(); i++) {
9175                ProcessRecord r = mIsolatedProcesses.valueAt(i);
9176                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9177                    continue;
9178                }
9179                pw.println(String.format("%sIsolated #%2d: %s",
9180                        "    ", i, r.toString()));
9181            }
9182        }
9183
9184        if (mLruProcesses.size() > 0) {
9185            if (needSep) pw.println(" ");
9186            needSep = true;
9187            pw.println("  Process LRU list (sorted by oom_adj):");
9188            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9189                    "Proc", "PERS", false, dumpPackage);
9190            needSep = true;
9191        }
9192
9193        if (dumpAll) {
9194            synchronized (mPidsSelfLocked) {
9195                boolean printed = false;
9196                for (int i=0; i<mPidsSelfLocked.size(); i++) {
9197                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
9198                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9199                        continue;
9200                    }
9201                    if (!printed) {
9202                        if (needSep) pw.println(" ");
9203                        needSep = true;
9204                        pw.println("  PID mappings:");
9205                        printed = true;
9206                    }
9207                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9208                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9209                }
9210            }
9211        }
9212
9213        if (mForegroundProcesses.size() > 0) {
9214            synchronized (mPidsSelfLocked) {
9215                boolean printed = false;
9216                for (int i=0; i<mForegroundProcesses.size(); i++) {
9217                    ProcessRecord r = mPidsSelfLocked.get(
9218                            mForegroundProcesses.valueAt(i).pid);
9219                    if (dumpPackage != null && (r == null
9220                            || !dumpPackage.equals(r.info.packageName))) {
9221                        continue;
9222                    }
9223                    if (!printed) {
9224                        if (needSep) pw.println(" ");
9225                        needSep = true;
9226                        pw.println("  Foreground Processes:");
9227                        printed = true;
9228                    }
9229                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9230                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9231                }
9232            }
9233        }
9234
9235        if (mPersistentStartingProcesses.size() > 0) {
9236            if (needSep) pw.println(" ");
9237            needSep = true;
9238            pw.println("  Persisent processes that are starting:");
9239            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9240                    "Starting Norm", "Restarting PERS", dumpPackage);
9241        }
9242
9243        if (mRemovedProcesses.size() > 0) {
9244            if (needSep) pw.println(" ");
9245            needSep = true;
9246            pw.println("  Processes that are being removed:");
9247            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9248                    "Removed Norm", "Removed PERS", dumpPackage);
9249        }
9250
9251        if (mProcessesOnHold.size() > 0) {
9252            if (needSep) pw.println(" ");
9253            needSep = true;
9254            pw.println("  Processes that are on old until the system is ready:");
9255            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9256                    "OnHold Norm", "OnHold PERS", dumpPackage);
9257        }
9258
9259        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9260
9261        if (mProcessCrashTimes.getMap().size() > 0) {
9262            boolean printed = false;
9263            long now = SystemClock.uptimeMillis();
9264            for (Map.Entry<String, SparseArray<Long>> procs
9265                    : mProcessCrashTimes.getMap().entrySet()) {
9266                String pname = procs.getKey();
9267                SparseArray<Long> uids = procs.getValue();
9268                final int N = uids.size();
9269                for (int i=0; i<N; i++) {
9270                    int puid = uids.keyAt(i);
9271                    ProcessRecord r = mProcessNames.get(pname, puid);
9272                    if (dumpPackage != null && (r == null
9273                            || !dumpPackage.equals(r.info.packageName))) {
9274                        continue;
9275                    }
9276                    if (!printed) {
9277                        if (needSep) pw.println(" ");
9278                        needSep = true;
9279                        pw.println("  Time since processes crashed:");
9280                        printed = true;
9281                    }
9282                    pw.print("    Process "); pw.print(pname);
9283                            pw.print(" uid "); pw.print(puid);
9284                            pw.print(": last crashed ");
9285                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9286                            pw.println(" ago");
9287                }
9288            }
9289        }
9290
9291        if (mBadProcesses.getMap().size() > 0) {
9292            boolean printed = false;
9293            for (Map.Entry<String, SparseArray<Long>> procs
9294                    : mBadProcesses.getMap().entrySet()) {
9295                String pname = procs.getKey();
9296                SparseArray<Long> uids = procs.getValue();
9297                final int N = uids.size();
9298                for (int i=0; i<N; i++) {
9299                    int puid = uids.keyAt(i);
9300                    ProcessRecord r = mProcessNames.get(pname, puid);
9301                    if (dumpPackage != null && (r == null
9302                            || !dumpPackage.equals(r.info.packageName))) {
9303                        continue;
9304                    }
9305                    if (!printed) {
9306                        if (needSep) pw.println(" ");
9307                        needSep = true;
9308                        pw.println("  Bad processes:");
9309                    }
9310                    pw.print("    Bad process "); pw.print(pname);
9311                            pw.print(" uid "); pw.print(puid);
9312                            pw.print(": crashed at time ");
9313                            pw.println(uids.valueAt(i));
9314                }
9315            }
9316        }
9317
9318        pw.println();
9319        pw.println("  mStartedUsers:");
9320        for (int i=0; i<mStartedUsers.size(); i++) {
9321            UserStartedState uss = mStartedUsers.valueAt(i);
9322            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9323                    pw.print(": "); uss.dump("", pw);
9324        }
9325        pw.print("  mUserLru: [");
9326        for (int i=0; i<mUserLru.size(); i++) {
9327            if (i > 0) pw.print(", ");
9328            pw.print(mUserLru.get(i));
9329        }
9330        pw.println("]");
9331        if (dumpAll) {
9332            pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
9333        }
9334        pw.println("  mHomeProcess: " + mHomeProcess);
9335        pw.println("  mPreviousProcess: " + mPreviousProcess);
9336        if (dumpAll) {
9337            StringBuilder sb = new StringBuilder(128);
9338            sb.append("  mPreviousProcessVisibleTime: ");
9339            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9340            pw.println(sb);
9341        }
9342        if (mHeavyWeightProcess != null) {
9343            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9344        }
9345        pw.println("  mConfiguration: " + mConfiguration);
9346        if (dumpAll) {
9347            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9348            if (mCompatModePackages.getPackages().size() > 0) {
9349                boolean printed = false;
9350                for (Map.Entry<String, Integer> entry
9351                        : mCompatModePackages.getPackages().entrySet()) {
9352                    String pkg = entry.getKey();
9353                    int mode = entry.getValue();
9354                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9355                        continue;
9356                    }
9357                    if (!printed) {
9358                        pw.println("  mScreenCompatPackages:");
9359                        printed = true;
9360                    }
9361                    pw.print("    "); pw.print(pkg); pw.print(": ");
9362                            pw.print(mode); pw.println();
9363                }
9364            }
9365        }
9366        if (mSleeping || mWentToSleep || mLockScreenShown) {
9367            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9368                    + " mLockScreenShown " + mLockScreenShown);
9369        }
9370        if (mShuttingDown) {
9371            pw.println("  mShuttingDown=" + mShuttingDown);
9372        }
9373        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9374                || mOrigWaitForDebugger) {
9375            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9376                    + " mDebugTransient=" + mDebugTransient
9377                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9378        }
9379        if (mOpenGlTraceApp != null) {
9380            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9381        }
9382        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9383                || mProfileFd != null) {
9384            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9385            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9386            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9387                    + mAutoStopProfiler);
9388        }
9389        if (mAlwaysFinishActivities || mController != null) {
9390            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9391                    + " mController=" + mController);
9392        }
9393        if (dumpAll) {
9394            pw.println("  Total persistent processes: " + numPers);
9395            pw.println("  mStartRunning=" + mStartRunning
9396                    + " mProcessesReady=" + mProcessesReady
9397                    + " mSystemReady=" + mSystemReady);
9398            pw.println("  mBooting=" + mBooting
9399                    + " mBooted=" + mBooted
9400                    + " mFactoryTest=" + mFactoryTest);
9401            pw.print("  mLastPowerCheckRealtime=");
9402                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9403                    pw.println("");
9404            pw.print("  mLastPowerCheckUptime=");
9405                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9406                    pw.println("");
9407            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9408            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9409            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9410            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9411                    + " mNumHiddenProcs=" + mNumHiddenProcs
9412                    + " mNumServiceProcs=" + mNumServiceProcs
9413                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9414        }
9415
9416        return true;
9417    }
9418
9419    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9420            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9421        if (mProcessesToGc.size() > 0) {
9422            boolean printed = false;
9423            long now = SystemClock.uptimeMillis();
9424            for (int i=0; i<mProcessesToGc.size(); i++) {
9425                ProcessRecord proc = mProcessesToGc.get(i);
9426                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9427                    continue;
9428                }
9429                if (!printed) {
9430                    if (needSep) pw.println(" ");
9431                    needSep = true;
9432                    pw.println("  Processes that are waiting to GC:");
9433                    printed = true;
9434                }
9435                pw.print("    Process "); pw.println(proc);
9436                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9437                        pw.print(", last gced=");
9438                        pw.print(now-proc.lastRequestedGc);
9439                        pw.print(" ms ago, last lowMem=");
9440                        pw.print(now-proc.lastLowMemory);
9441                        pw.println(" ms ago");
9442
9443            }
9444        }
9445        return needSep;
9446    }
9447
9448    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9449            int opti, boolean dumpAll) {
9450        boolean needSep = false;
9451
9452        if (mLruProcesses.size() > 0) {
9453            if (needSep) pw.println(" ");
9454            needSep = true;
9455            pw.println("  OOM levels:");
9456            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9457            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9458            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9459            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9460            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9461            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9462            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9463            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9464            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9465            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9466            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9467            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9468            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9469
9470            if (needSep) pw.println(" ");
9471            needSep = true;
9472            pw.println("  Process OOM control:");
9473            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9474                    "Proc", "PERS", true, null);
9475            needSep = true;
9476        }
9477
9478        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9479
9480        pw.println();
9481        pw.println("  mHomeProcess: " + mHomeProcess);
9482        pw.println("  mPreviousProcess: " + mPreviousProcess);
9483        if (mHeavyWeightProcess != null) {
9484            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9485        }
9486
9487        return true;
9488    }
9489
9490    /**
9491     * There are three ways to call this:
9492     *  - no provider specified: dump all the providers
9493     *  - a flattened component name that matched an existing provider was specified as the
9494     *    first arg: dump that one provider
9495     *  - the first arg isn't the flattened component name of an existing provider:
9496     *    dump all providers whose component contains the first arg as a substring
9497     */
9498    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9499            int opti, boolean dumpAll) {
9500        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9501    }
9502
9503    static class ItemMatcher {
9504        ArrayList<ComponentName> components;
9505        ArrayList<String> strings;
9506        ArrayList<Integer> objects;
9507        boolean all;
9508
9509        ItemMatcher() {
9510            all = true;
9511        }
9512
9513        void build(String name) {
9514            ComponentName componentName = ComponentName.unflattenFromString(name);
9515            if (componentName != null) {
9516                if (components == null) {
9517                    components = new ArrayList<ComponentName>();
9518                }
9519                components.add(componentName);
9520                all = false;
9521            } else {
9522                int objectId = 0;
9523                // Not a '/' separated full component name; maybe an object ID?
9524                try {
9525                    objectId = Integer.parseInt(name, 16);
9526                    if (objects == null) {
9527                        objects = new ArrayList<Integer>();
9528                    }
9529                    objects.add(objectId);
9530                    all = false;
9531                } catch (RuntimeException e) {
9532                    // Not an integer; just do string match.
9533                    if (strings == null) {
9534                        strings = new ArrayList<String>();
9535                    }
9536                    strings.add(name);
9537                    all = false;
9538                }
9539            }
9540        }
9541
9542        int build(String[] args, int opti) {
9543            for (; opti<args.length; opti++) {
9544                String name = args[opti];
9545                if ("--".equals(name)) {
9546                    return opti+1;
9547                }
9548                build(name);
9549            }
9550            return opti;
9551        }
9552
9553        boolean match(Object object, ComponentName comp) {
9554            if (all) {
9555                return true;
9556            }
9557            if (components != null) {
9558                for (int i=0; i<components.size(); i++) {
9559                    if (components.get(i).equals(comp)) {
9560                        return true;
9561                    }
9562                }
9563            }
9564            if (objects != null) {
9565                for (int i=0; i<objects.size(); i++) {
9566                    if (System.identityHashCode(object) == objects.get(i)) {
9567                        return true;
9568                    }
9569                }
9570            }
9571            if (strings != null) {
9572                String flat = comp.flattenToString();
9573                for (int i=0; i<strings.size(); i++) {
9574                    if (flat.contains(strings.get(i))) {
9575                        return true;
9576                    }
9577                }
9578            }
9579            return false;
9580        }
9581    }
9582
9583    /**
9584     * There are three things that cmd can be:
9585     *  - a flattened component name that matches an existing activity
9586     *  - the cmd arg isn't the flattened component name of an existing activity:
9587     *    dump all activity whose component contains the cmd as a substring
9588     *  - A hex number of the ActivityRecord object instance.
9589     */
9590    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9591            int opti, boolean dumpAll) {
9592        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9593
9594        if ("all".equals(name)) {
9595            synchronized (this) {
9596                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9597                    activities.add(r1);
9598                }
9599            }
9600        } else if ("top".equals(name)) {
9601            synchronized (this) {
9602                final int N = mMainStack.mHistory.size();
9603                if (N > 0) {
9604                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9605                }
9606            }
9607        } else {
9608            ItemMatcher matcher = new ItemMatcher();
9609            matcher.build(name);
9610
9611            synchronized (this) {
9612                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9613                    if (matcher.match(r1, r1.intent.getComponent())) {
9614                        activities.add(r1);
9615                    }
9616                }
9617            }
9618        }
9619
9620        if (activities.size() <= 0) {
9621            return false;
9622        }
9623
9624        String[] newArgs = new String[args.length - opti];
9625        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9626
9627        TaskRecord lastTask = null;
9628        boolean needSep = false;
9629        for (int i=activities.size()-1; i>=0; i--) {
9630            ActivityRecord r = (ActivityRecord)activities.get(i);
9631            if (needSep) {
9632                pw.println();
9633            }
9634            needSep = true;
9635            synchronized (this) {
9636                if (lastTask != r.task) {
9637                    lastTask = r.task;
9638                    pw.print("TASK "); pw.print(lastTask.affinity);
9639                            pw.print(" id="); pw.println(lastTask.taskId);
9640                    if (dumpAll) {
9641                        lastTask.dump(pw, "  ");
9642                    }
9643                }
9644            }
9645            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9646        }
9647        return true;
9648    }
9649
9650    /**
9651     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9652     * there is a thread associated with the activity.
9653     */
9654    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9655            final ActivityRecord r, String[] args, boolean dumpAll) {
9656        String innerPrefix = prefix + "  ";
9657        synchronized (this) {
9658            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9659                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9660                    pw.print(" pid=");
9661                    if (r.app != null) pw.println(r.app.pid);
9662                    else pw.println("(not running)");
9663            if (dumpAll) {
9664                r.dump(pw, innerPrefix);
9665            }
9666        }
9667        if (r.app != null && r.app.thread != null) {
9668            // flush anything that is already in the PrintWriter since the thread is going
9669            // to write to the file descriptor directly
9670            pw.flush();
9671            try {
9672                TransferPipe tp = new TransferPipe();
9673                try {
9674                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9675                            r.appToken, innerPrefix, args);
9676                    tp.go(fd);
9677                } finally {
9678                    tp.kill();
9679                }
9680            } catch (IOException e) {
9681                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9682            } catch (RemoteException e) {
9683                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9684            }
9685        }
9686    }
9687
9688    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9689            int opti, boolean dumpAll, String dumpPackage) {
9690        boolean needSep = false;
9691        boolean onlyHistory = false;
9692
9693        if ("history".equals(dumpPackage)) {
9694            onlyHistory = true;
9695            dumpPackage = null;
9696        }
9697
9698        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9699        if (!onlyHistory && dumpAll) {
9700            if (mRegisteredReceivers.size() > 0) {
9701                boolean printed = false;
9702                Iterator it = mRegisteredReceivers.values().iterator();
9703                while (it.hasNext()) {
9704                    ReceiverList r = (ReceiverList)it.next();
9705                    if (dumpPackage != null && (r.app == null ||
9706                            !dumpPackage.equals(r.app.info.packageName))) {
9707                        continue;
9708                    }
9709                    if (!printed) {
9710                        pw.println("  Registered Receivers:");
9711                        needSep = true;
9712                        printed = true;
9713                    }
9714                    pw.print("  * "); pw.println(r);
9715                    r.dump(pw, "    ");
9716                }
9717            }
9718
9719            if (mReceiverResolver.dump(pw, needSep ?
9720                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9721                    "    ", dumpPackage, false)) {
9722                needSep = true;
9723            }
9724        }
9725
9726        for (BroadcastQueue q : mBroadcastQueues) {
9727            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9728        }
9729
9730        needSep = true;
9731
9732        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9733            for (int user=0; user<mStickyBroadcasts.size(); user++) {
9734                if (needSep) {
9735                    pw.println();
9736                }
9737                needSep = true;
9738                pw.print("  Sticky broadcasts for user ");
9739                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9740                StringBuilder sb = new StringBuilder(128);
9741                for (Map.Entry<String, ArrayList<Intent>> ent
9742                        : mStickyBroadcasts.valueAt(user).entrySet()) {
9743                    pw.print("  * Sticky action "); pw.print(ent.getKey());
9744                    if (dumpAll) {
9745                        pw.println(":");
9746                        ArrayList<Intent> intents = ent.getValue();
9747                        final int N = intents.size();
9748                        for (int i=0; i<N; i++) {
9749                            sb.setLength(0);
9750                            sb.append("    Intent: ");
9751                            intents.get(i).toShortString(sb, false, true, false, false);
9752                            pw.println(sb.toString());
9753                            Bundle bundle = intents.get(i).getExtras();
9754                            if (bundle != null) {
9755                                pw.print("      ");
9756                                pw.println(bundle.toString());
9757                            }
9758                        }
9759                    } else {
9760                        pw.println("");
9761                    }
9762                }
9763            }
9764        }
9765
9766        if (!onlyHistory && dumpAll) {
9767            pw.println();
9768            for (BroadcastQueue queue : mBroadcastQueues) {
9769                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9770                        + queue.mBroadcastsScheduled);
9771            }
9772            pw.println("  mHandler:");
9773            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9774            needSep = true;
9775        }
9776
9777        return needSep;
9778    }
9779
9780    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9781            int opti, boolean dumpAll, String dumpPackage) {
9782        boolean needSep = true;
9783
9784        ItemMatcher matcher = new ItemMatcher();
9785        matcher.build(args, opti);
9786
9787        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9788
9789        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9790
9791        if (mLaunchingProviders.size() > 0) {
9792            boolean printed = false;
9793            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9794                ContentProviderRecord r = mLaunchingProviders.get(i);
9795                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9796                    continue;
9797                }
9798                if (!printed) {
9799                    if (needSep) pw.println(" ");
9800                    needSep = true;
9801                    pw.println("  Launching content providers:");
9802                    printed = true;
9803                }
9804                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9805                        pw.println(r);
9806            }
9807        }
9808
9809        if (mGrantedUriPermissions.size() > 0) {
9810            if (needSep) pw.println();
9811            needSep = true;
9812            pw.println("Granted Uri Permissions:");
9813            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9814                int uid = mGrantedUriPermissions.keyAt(i);
9815                HashMap<Uri, UriPermission> perms
9816                        = mGrantedUriPermissions.valueAt(i);
9817                pw.print("  * UID "); pw.print(uid);
9818                        pw.println(" holds:");
9819                for (UriPermission perm : perms.values()) {
9820                    pw.print("    "); pw.println(perm);
9821                    if (dumpAll) {
9822                        perm.dump(pw, "      ");
9823                    }
9824                }
9825            }
9826            needSep = true;
9827        }
9828
9829        return needSep;
9830    }
9831
9832    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9833            int opti, boolean dumpAll, String dumpPackage) {
9834        boolean needSep = false;
9835
9836        if (mIntentSenderRecords.size() > 0) {
9837            boolean printed = false;
9838            Iterator<WeakReference<PendingIntentRecord>> it
9839                    = mIntentSenderRecords.values().iterator();
9840            while (it.hasNext()) {
9841                WeakReference<PendingIntentRecord> ref = it.next();
9842                PendingIntentRecord rec = ref != null ? ref.get(): null;
9843                if (dumpPackage != null && (rec == null
9844                        || !dumpPackage.equals(rec.key.packageName))) {
9845                    continue;
9846                }
9847                if (!printed) {
9848                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9849                    printed = true;
9850                }
9851                needSep = true;
9852                if (rec != null) {
9853                    pw.print("  * "); pw.println(rec);
9854                    if (dumpAll) {
9855                        rec.dump(pw, "    ");
9856                    }
9857                } else {
9858                    pw.print("  * "); pw.println(ref);
9859                }
9860            }
9861        }
9862
9863        return needSep;
9864    }
9865
9866    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9867            String prefix, String label, boolean complete, boolean brief, boolean client,
9868            String dumpPackage) {
9869        TaskRecord lastTask = null;
9870        boolean needNL = false;
9871        final String innerPrefix = prefix + "      ";
9872        final String[] args = new String[0];
9873        for (int i=list.size()-1; i>=0; i--) {
9874            final ActivityRecord r = (ActivityRecord)list.get(i);
9875            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9876                continue;
9877            }
9878            final boolean full = !brief && (complete || !r.isInHistory());
9879            if (needNL) {
9880                pw.println(" ");
9881                needNL = false;
9882            }
9883            if (lastTask != r.task) {
9884                lastTask = r.task;
9885                pw.print(prefix);
9886                pw.print(full ? "* " : "  ");
9887                pw.println(lastTask);
9888                if (full) {
9889                    lastTask.dump(pw, prefix + "  ");
9890                } else if (complete) {
9891                    // Complete + brief == give a summary.  Isn't that obvious?!?
9892                    if (lastTask.intent != null) {
9893                        pw.print(prefix); pw.print("  ");
9894                                pw.println(lastTask.intent.toInsecureStringWithClip());
9895                    }
9896                }
9897            }
9898            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9899            pw.print(" #"); pw.print(i); pw.print(": ");
9900            pw.println(r);
9901            if (full) {
9902                r.dump(pw, innerPrefix);
9903            } else if (complete) {
9904                // Complete + brief == give a summary.  Isn't that obvious?!?
9905                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9906                if (r.app != null) {
9907                    pw.print(innerPrefix); pw.println(r.app);
9908                }
9909            }
9910            if (client && r.app != null && r.app.thread != null) {
9911                // flush anything that is already in the PrintWriter since the thread is going
9912                // to write to the file descriptor directly
9913                pw.flush();
9914                try {
9915                    TransferPipe tp = new TransferPipe();
9916                    try {
9917                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9918                                r.appToken, innerPrefix, args);
9919                        // Short timeout, since blocking here can
9920                        // deadlock with the application.
9921                        tp.go(fd, 2000);
9922                    } finally {
9923                        tp.kill();
9924                    }
9925                } catch (IOException e) {
9926                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9927                } catch (RemoteException e) {
9928                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9929                }
9930                needNL = true;
9931            }
9932        }
9933    }
9934
9935    private static String buildOomTag(String prefix, String space, int val, int base) {
9936        if (val == base) {
9937            if (space == null) return prefix;
9938            return prefix + "  ";
9939        }
9940        return prefix + "+" + Integer.toString(val-base);
9941    }
9942
9943    private static final int dumpProcessList(PrintWriter pw,
9944            ActivityManagerService service, List list,
9945            String prefix, String normalLabel, String persistentLabel,
9946            String dumpPackage) {
9947        int numPers = 0;
9948        final int N = list.size()-1;
9949        for (int i=N; i>=0; i--) {
9950            ProcessRecord r = (ProcessRecord)list.get(i);
9951            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9952                continue;
9953            }
9954            pw.println(String.format("%s%s #%2d: %s",
9955                    prefix, (r.persistent ? persistentLabel : normalLabel),
9956                    i, r.toString()));
9957            if (r.persistent) {
9958                numPers++;
9959            }
9960        }
9961        return numPers;
9962    }
9963
9964    private static final boolean dumpProcessOomList(PrintWriter pw,
9965            ActivityManagerService service, List<ProcessRecord> origList,
9966            String prefix, String normalLabel, String persistentLabel,
9967            boolean inclDetails, String dumpPackage) {
9968
9969        ArrayList<Pair<ProcessRecord, Integer>> list
9970                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9971        for (int i=0; i<origList.size(); i++) {
9972            ProcessRecord r = origList.get(i);
9973            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9974                continue;
9975            }
9976            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9977        }
9978
9979        if (list.size() <= 0) {
9980            return false;
9981        }
9982
9983        Comparator<Pair<ProcessRecord, Integer>> comparator
9984                = new Comparator<Pair<ProcessRecord, Integer>>() {
9985            @Override
9986            public int compare(Pair<ProcessRecord, Integer> object1,
9987                    Pair<ProcessRecord, Integer> object2) {
9988                if (object1.first.setAdj != object2.first.setAdj) {
9989                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9990                }
9991                if (object1.second.intValue() != object2.second.intValue()) {
9992                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9993                }
9994                return 0;
9995            }
9996        };
9997
9998        Collections.sort(list, comparator);
9999
10000        final long curRealtime = SystemClock.elapsedRealtime();
10001        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10002        final long curUptime = SystemClock.uptimeMillis();
10003        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10004
10005        for (int i=list.size()-1; i>=0; i--) {
10006            ProcessRecord r = list.get(i).first;
10007            String oomAdj;
10008            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
10009                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
10010            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10011                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
10012            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10013                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
10014            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10015                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
10016            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10017                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
10018            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
10019                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
10020            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10021                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10022            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10023                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10024            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10025                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10026            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10027                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
10028            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10029                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
10030            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10031                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
10032            } else {
10033                oomAdj = Integer.toString(r.setAdj);
10034            }
10035            String schedGroup;
10036            switch (r.setSchedGroup) {
10037                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10038                    schedGroup = "B";
10039                    break;
10040                case Process.THREAD_GROUP_DEFAULT:
10041                    schedGroup = "F";
10042                    break;
10043                default:
10044                    schedGroup = Integer.toString(r.setSchedGroup);
10045                    break;
10046            }
10047            String foreground;
10048            if (r.foregroundActivities) {
10049                foreground = "A";
10050            } else if (r.foregroundServices) {
10051                foreground = "S";
10052            } else {
10053                foreground = " ";
10054            }
10055            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10056                    prefix, (r.persistent ? persistentLabel : normalLabel),
10057                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10058                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10059            if (r.adjSource != null || r.adjTarget != null) {
10060                pw.print(prefix);
10061                pw.print("    ");
10062                if (r.adjTarget instanceof ComponentName) {
10063                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10064                } else if (r.adjTarget != null) {
10065                    pw.print(r.adjTarget.toString());
10066                } else {
10067                    pw.print("{null}");
10068                }
10069                pw.print("<=");
10070                if (r.adjSource instanceof ProcessRecord) {
10071                    pw.print("Proc{");
10072                    pw.print(((ProcessRecord)r.adjSource).toShortString());
10073                    pw.println("}");
10074                } else if (r.adjSource != null) {
10075                    pw.println(r.adjSource.toString());
10076                } else {
10077                    pw.println("{null}");
10078                }
10079            }
10080            if (inclDetails) {
10081                pw.print(prefix);
10082                pw.print("    ");
10083                pw.print("oom: max="); pw.print(r.maxAdj);
10084                pw.print(" hidden="); pw.print(r.hiddenAdj);
10085                pw.print(" empty="); pw.print(r.emptyAdj);
10086                pw.print(" curRaw="); pw.print(r.curRawAdj);
10087                pw.print(" setRaw="); pw.print(r.setRawAdj);
10088                pw.print(" cur="); pw.print(r.curAdj);
10089                pw.print(" set="); pw.println(r.setAdj);
10090                pw.print(prefix);
10091                pw.print("    ");
10092                pw.print("keeping="); pw.print(r.keeping);
10093                pw.print(" hidden="); pw.print(r.hidden);
10094                pw.print(" empty="); pw.print(r.empty);
10095                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10096
10097                if (!r.keeping) {
10098                    if (r.lastWakeTime != 0) {
10099                        long wtime;
10100                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10101                        synchronized (stats) {
10102                            wtime = stats.getProcessWakeTime(r.info.uid,
10103                                    r.pid, curRealtime);
10104                        }
10105                        long timeUsed = wtime - r.lastWakeTime;
10106                        pw.print(prefix);
10107                        pw.print("    ");
10108                        pw.print("keep awake over ");
10109                        TimeUtils.formatDuration(realtimeSince, pw);
10110                        pw.print(" used ");
10111                        TimeUtils.formatDuration(timeUsed, pw);
10112                        pw.print(" (");
10113                        pw.print((timeUsed*100)/realtimeSince);
10114                        pw.println("%)");
10115                    }
10116                    if (r.lastCpuTime != 0) {
10117                        long timeUsed = r.curCpuTime - r.lastCpuTime;
10118                        pw.print(prefix);
10119                        pw.print("    ");
10120                        pw.print("run cpu over ");
10121                        TimeUtils.formatDuration(uptimeSince, pw);
10122                        pw.print(" used ");
10123                        TimeUtils.formatDuration(timeUsed, pw);
10124                        pw.print(" (");
10125                        pw.print((timeUsed*100)/uptimeSince);
10126                        pw.println("%)");
10127                    }
10128                }
10129            }
10130        }
10131        return true;
10132    }
10133
10134    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10135        ArrayList<ProcessRecord> procs;
10136        synchronized (this) {
10137            if (args != null && args.length > start
10138                    && args[start].charAt(0) != '-') {
10139                procs = new ArrayList<ProcessRecord>();
10140                int pid = -1;
10141                try {
10142                    pid = Integer.parseInt(args[start]);
10143                } catch (NumberFormatException e) {
10144
10145                }
10146                for (int i=mLruProcesses.size()-1; i>=0; i--) {
10147                    ProcessRecord proc = mLruProcesses.get(i);
10148                    if (proc.pid == pid) {
10149                        procs.add(proc);
10150                    } else if (proc.processName.equals(args[start])) {
10151                        procs.add(proc);
10152                    }
10153                }
10154                if (procs.size() <= 0) {
10155                    pw.println("No process found for: " + args[start]);
10156                    return null;
10157                }
10158            } else {
10159                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10160            }
10161        }
10162        return procs;
10163    }
10164
10165    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10166            PrintWriter pw, String[] args) {
10167        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10168        if (procs == null) {
10169            return;
10170        }
10171
10172        long uptime = SystemClock.uptimeMillis();
10173        long realtime = SystemClock.elapsedRealtime();
10174        pw.println("Applications Graphics Acceleration Info:");
10175        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10176
10177        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10178            ProcessRecord r = procs.get(i);
10179            if (r.thread != null) {
10180                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10181                pw.flush();
10182                try {
10183                    TransferPipe tp = new TransferPipe();
10184                    try {
10185                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10186                        tp.go(fd);
10187                    } finally {
10188                        tp.kill();
10189                    }
10190                } catch (IOException e) {
10191                    pw.println("Failure while dumping the app: " + r);
10192                    pw.flush();
10193                } catch (RemoteException e) {
10194                    pw.println("Got a RemoteException while dumping the app " + r);
10195                    pw.flush();
10196                }
10197            }
10198        }
10199    }
10200
10201    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10202        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10203        if (procs == null) {
10204            return;
10205        }
10206
10207        pw.println("Applications Database Info:");
10208
10209        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10210            ProcessRecord r = procs.get(i);
10211            if (r.thread != null) {
10212                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10213                pw.flush();
10214                try {
10215                    TransferPipe tp = new TransferPipe();
10216                    try {
10217                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10218                        tp.go(fd);
10219                    } finally {
10220                        tp.kill();
10221                    }
10222                } catch (IOException e) {
10223                    pw.println("Failure while dumping the app: " + r);
10224                    pw.flush();
10225                } catch (RemoteException e) {
10226                    pw.println("Got a RemoteException while dumping the app " + r);
10227                    pw.flush();
10228                }
10229            }
10230        }
10231    }
10232
10233    final static class MemItem {
10234        final String label;
10235        final String shortLabel;
10236        final long pss;
10237        final int id;
10238        ArrayList<MemItem> subitems;
10239
10240        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10241            label = _label;
10242            shortLabel = _shortLabel;
10243            pss = _pss;
10244            id = _id;
10245        }
10246    }
10247
10248    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10249            boolean sort) {
10250        if (sort) {
10251            Collections.sort(items, new Comparator<MemItem>() {
10252                @Override
10253                public int compare(MemItem lhs, MemItem rhs) {
10254                    if (lhs.pss < rhs.pss) {
10255                        return 1;
10256                    } else if (lhs.pss > rhs.pss) {
10257                        return -1;
10258                    }
10259                    return 0;
10260                }
10261            });
10262        }
10263
10264        for (int i=0; i<items.size(); i++) {
10265            MemItem mi = items.get(i);
10266            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10267            if (mi.subitems != null) {
10268                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10269            }
10270        }
10271    }
10272
10273    // These are in KB.
10274    static final long[] DUMP_MEM_BUCKETS = new long[] {
10275        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10276        120*1024, 160*1024, 200*1024,
10277        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10278        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10279    };
10280
10281    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10282            boolean stackLike) {
10283        int start = label.lastIndexOf('.');
10284        if (start >= 0) start++;
10285        else start = 0;
10286        int end = label.length();
10287        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10288            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10289                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10290                out.append(bucket);
10291                out.append(stackLike ? "MB." : "MB ");
10292                out.append(label, start, end);
10293                return;
10294            }
10295        }
10296        out.append(memKB/1024);
10297        out.append(stackLike ? "MB." : "MB ");
10298        out.append(label, start, end);
10299    }
10300
10301    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10302            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10303            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10304            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10305            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10306    };
10307    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10308            "System", "Persistent", "Foreground",
10309            "Visible", "Perceptible", "Heavy Weight",
10310            "Backup", "A Services", "Home", "Previous",
10311            "B Services", "Background"
10312    };
10313
10314    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10315            PrintWriter pw, String prefix, String[] args, boolean brief,
10316            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10317        boolean dumpAll = false;
10318        boolean oomOnly = false;
10319
10320        int opti = 0;
10321        while (opti < args.length) {
10322            String opt = args[opti];
10323            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10324                break;
10325            }
10326            opti++;
10327            if ("-a".equals(opt)) {
10328                dumpAll = true;
10329            } else if ("--oom".equals(opt)) {
10330                oomOnly = true;
10331            } else if ("-h".equals(opt)) {
10332                pw.println("meminfo dump options: [-a] [--oom] [process]");
10333                pw.println("  -a: include all available information for each process.");
10334                pw.println("  --oom: only show processes organized by oom adj.");
10335                pw.println("If [process] is specified it can be the name or ");
10336                pw.println("pid of a specific process to dump.");
10337                return;
10338            } else {
10339                pw.println("Unknown argument: " + opt + "; use -h for help");
10340            }
10341        }
10342
10343        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10344        if (procs == null) {
10345            return;
10346        }
10347
10348        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10349        long uptime = SystemClock.uptimeMillis();
10350        long realtime = SystemClock.elapsedRealtime();
10351
10352        if (procs.size() == 1 || isCheckinRequest) {
10353            dumpAll = true;
10354        }
10355
10356        if (isCheckinRequest) {
10357            // short checkin version
10358            pw.println(uptime + "," + realtime);
10359            pw.flush();
10360        } else {
10361            pw.println("Applications Memory Usage (kB):");
10362            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10363        }
10364
10365        String[] innerArgs = new String[args.length-opti];
10366        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10367
10368        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10369        long nativePss=0, dalvikPss=0, otherPss=0;
10370        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10371
10372        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10373        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10374                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10375
10376        long totalPss = 0;
10377
10378        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10379            ProcessRecord r = procs.get(i);
10380            if (r.thread != null) {
10381                if (!isCheckinRequest && dumpAll) {
10382                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10383                    pw.flush();
10384                }
10385                Debug.MemoryInfo mi = null;
10386                if (dumpAll) {
10387                    try {
10388                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10389                    } catch (RemoteException e) {
10390                        if (!isCheckinRequest) {
10391                            pw.println("Got RemoteException!");
10392                            pw.flush();
10393                        }
10394                    }
10395                } else {
10396                    mi = new Debug.MemoryInfo();
10397                    Debug.getMemoryInfo(r.pid, mi);
10398                }
10399
10400                if (!isCheckinRequest && mi != null) {
10401                    long myTotalPss = mi.getTotalPss();
10402                    totalPss += myTotalPss;
10403                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10404                            r.processName, myTotalPss, 0);
10405                    procMems.add(pssItem);
10406
10407                    nativePss += mi.nativePss;
10408                    dalvikPss += mi.dalvikPss;
10409                    otherPss += mi.otherPss;
10410                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10411                        long mem = mi.getOtherPss(j);
10412                        miscPss[j] += mem;
10413                        otherPss -= mem;
10414                    }
10415
10416                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10417                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10418                                || oomIndex == (oomPss.length-1)) {
10419                            oomPss[oomIndex] += myTotalPss;
10420                            if (oomProcs[oomIndex] == null) {
10421                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10422                            }
10423                            oomProcs[oomIndex].add(pssItem);
10424                            break;
10425                        }
10426                    }
10427                }
10428            }
10429        }
10430
10431        if (!isCheckinRequest && procs.size() > 1) {
10432            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10433
10434            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10435            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10436            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10437            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10438                String label = Debug.MemoryInfo.getOtherLabel(j);
10439                catMems.add(new MemItem(label, label, miscPss[j], j));
10440            }
10441
10442            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10443            for (int j=0; j<oomPss.length; j++) {
10444                if (oomPss[j] != 0) {
10445                    String label = DUMP_MEM_OOM_LABEL[j];
10446                    MemItem item = new MemItem(label, label, oomPss[j],
10447                            DUMP_MEM_OOM_ADJ[j]);
10448                    item.subitems = oomProcs[j];
10449                    oomMems.add(item);
10450                }
10451            }
10452
10453            if (outTag != null || outStack != null) {
10454                if (outTag != null) {
10455                    appendMemBucket(outTag, totalPss, "total", false);
10456                }
10457                if (outStack != null) {
10458                    appendMemBucket(outStack, totalPss, "total", true);
10459                }
10460                boolean firstLine = true;
10461                for (int i=0; i<oomMems.size(); i++) {
10462                    MemItem miCat = oomMems.get(i);
10463                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10464                        continue;
10465                    }
10466                    if (miCat.id < ProcessList.SERVICE_ADJ
10467                            || miCat.id == ProcessList.HOME_APP_ADJ
10468                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10469                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10470                            outTag.append(" / ");
10471                        }
10472                        if (outStack != null) {
10473                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10474                                if (firstLine) {
10475                                    outStack.append(":");
10476                                    firstLine = false;
10477                                }
10478                                outStack.append("\n\t at ");
10479                            } else {
10480                                outStack.append("$");
10481                            }
10482                        }
10483                        for (int j=0; j<miCat.subitems.size(); j++) {
10484                            MemItem mi = miCat.subitems.get(j);
10485                            if (j > 0) {
10486                                if (outTag != null) {
10487                                    outTag.append(" ");
10488                                }
10489                                if (outStack != null) {
10490                                    outStack.append("$");
10491                                }
10492                            }
10493                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10494                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10495                            }
10496                            if (outStack != null) {
10497                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10498                            }
10499                        }
10500                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10501                            outStack.append("(");
10502                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10503                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10504                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10505                                    outStack.append(":");
10506                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10507                                }
10508                            }
10509                            outStack.append(")");
10510                        }
10511                    }
10512                }
10513            }
10514
10515            if (!brief && !oomOnly) {
10516                pw.println();
10517                pw.println("Total PSS by process:");
10518                dumpMemItems(pw, "  ", procMems, true);
10519                pw.println();
10520            }
10521            pw.println("Total PSS by OOM adjustment:");
10522            dumpMemItems(pw, "  ", oomMems, false);
10523            if (!oomOnly) {
10524                PrintWriter out = categoryPw != null ? categoryPw : pw;
10525                out.println();
10526                out.println("Total PSS by category:");
10527                dumpMemItems(out, "  ", catMems, true);
10528            }
10529            pw.println();
10530            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10531            final int[] SINGLE_LONG_FORMAT = new int[] {
10532                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10533            };
10534            long[] longOut = new long[1];
10535            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10536                    SINGLE_LONG_FORMAT, null, longOut, null);
10537            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10538            longOut[0] = 0;
10539            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10540                    SINGLE_LONG_FORMAT, null, longOut, null);
10541            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10542            longOut[0] = 0;
10543            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10544                    SINGLE_LONG_FORMAT, null, longOut, null);
10545            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10546            longOut[0] = 0;
10547            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10548                    SINGLE_LONG_FORMAT, null, longOut, null);
10549            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10550            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10551                    pw.print(shared); pw.println(" kB");
10552            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10553                    pw.print(voltile); pw.println(" kB volatile");
10554        }
10555    }
10556
10557    /**
10558     * Searches array of arguments for the specified string
10559     * @param args array of argument strings
10560     * @param value value to search for
10561     * @return true if the value is contained in the array
10562     */
10563    private static boolean scanArgs(String[] args, String value) {
10564        if (args != null) {
10565            for (String arg : args) {
10566                if (value.equals(arg)) {
10567                    return true;
10568                }
10569            }
10570        }
10571        return false;
10572    }
10573
10574    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10575            ContentProviderRecord cpr, boolean always) {
10576        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10577
10578        if (!inLaunching || always) {
10579            synchronized (cpr) {
10580                cpr.launchingApp = null;
10581                cpr.notifyAll();
10582            }
10583            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10584            String names[] = cpr.info.authority.split(";");
10585            for (int j = 0; j < names.length; j++) {
10586                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10587            }
10588        }
10589
10590        for (int i=0; i<cpr.connections.size(); i++) {
10591            ContentProviderConnection conn = cpr.connections.get(i);
10592            if (conn.waiting) {
10593                // If this connection is waiting for the provider, then we don't
10594                // need to mess with its process unless we are always removing
10595                // or for some reason the provider is not currently launching.
10596                if (inLaunching && !always) {
10597                    continue;
10598                }
10599            }
10600            ProcessRecord capp = conn.client;
10601            conn.dead = true;
10602            if (conn.stableCount > 0) {
10603                if (!capp.persistent && capp.thread != null
10604                        && capp.pid != 0
10605                        && capp.pid != MY_PID) {
10606                    Slog.i(TAG, "Kill " + capp.processName
10607                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10608                            + " in dying process " + (proc != null ? proc.processName : "??"));
10609                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10610                            capp.processName, capp.setAdj, "dying provider "
10611                                    + cpr.name.toShortString());
10612                    Process.killProcessQuiet(capp.pid);
10613                }
10614            } else if (capp.thread != null && conn.provider.provider != null) {
10615                try {
10616                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10617                } catch (RemoteException e) {
10618                }
10619                // In the protocol here, we don't expect the client to correctly
10620                // clean up this connection, we'll just remove it.
10621                cpr.connections.remove(i);
10622                conn.client.conProviders.remove(conn);
10623            }
10624        }
10625
10626        if (inLaunching && always) {
10627            mLaunchingProviders.remove(cpr);
10628        }
10629        return inLaunching;
10630    }
10631
10632    /**
10633     * Main code for cleaning up a process when it has gone away.  This is
10634     * called both as a result of the process dying, or directly when stopping
10635     * a process when running in single process mode.
10636     */
10637    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10638            boolean restarting, boolean allowRestart, int index) {
10639        if (index >= 0) {
10640            mLruProcesses.remove(index);
10641        }
10642
10643        mProcessesToGc.remove(app);
10644
10645        // Dismiss any open dialogs.
10646        if (app.crashDialog != null) {
10647            app.crashDialog.dismiss();
10648            app.crashDialog = null;
10649        }
10650        if (app.anrDialog != null) {
10651            app.anrDialog.dismiss();
10652            app.anrDialog = null;
10653        }
10654        if (app.waitDialog != null) {
10655            app.waitDialog.dismiss();
10656            app.waitDialog = null;
10657        }
10658
10659        app.crashing = false;
10660        app.notResponding = false;
10661
10662        app.resetPackageList();
10663        app.unlinkDeathRecipient();
10664        app.thread = null;
10665        app.forcingToForeground = null;
10666        app.foregroundServices = false;
10667        app.foregroundActivities = false;
10668        app.hasShownUi = false;
10669        app.hasAboveClient = false;
10670
10671        mServices.killServicesLocked(app, allowRestart);
10672
10673        boolean restart = false;
10674
10675        // Remove published content providers.
10676        if (!app.pubProviders.isEmpty()) {
10677            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10678            while (it.hasNext()) {
10679                ContentProviderRecord cpr = it.next();
10680
10681                final boolean always = app.bad || !allowRestart;
10682                if (removeDyingProviderLocked(app, cpr, always) || always) {
10683                    // We left the provider in the launching list, need to
10684                    // restart it.
10685                    restart = true;
10686                }
10687
10688                cpr.provider = null;
10689                cpr.proc = null;
10690            }
10691            app.pubProviders.clear();
10692        }
10693
10694        // Take care of any launching providers waiting for this process.
10695        if (checkAppInLaunchingProvidersLocked(app, false)) {
10696            restart = true;
10697        }
10698
10699        // Unregister from connected content providers.
10700        if (!app.conProviders.isEmpty()) {
10701            for (int i=0; i<app.conProviders.size(); i++) {
10702                ContentProviderConnection conn = app.conProviders.get(i);
10703                conn.provider.connections.remove(conn);
10704            }
10705            app.conProviders.clear();
10706        }
10707
10708        // At this point there may be remaining entries in mLaunchingProviders
10709        // where we were the only one waiting, so they are no longer of use.
10710        // Look for these and clean up if found.
10711        // XXX Commented out for now.  Trying to figure out a way to reproduce
10712        // the actual situation to identify what is actually going on.
10713        if (false) {
10714            for (int i=0; i<mLaunchingProviders.size(); i++) {
10715                ContentProviderRecord cpr = (ContentProviderRecord)
10716                        mLaunchingProviders.get(i);
10717                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10718                    synchronized (cpr) {
10719                        cpr.launchingApp = null;
10720                        cpr.notifyAll();
10721                    }
10722                }
10723            }
10724        }
10725
10726        skipCurrentReceiverLocked(app);
10727
10728        // Unregister any receivers.
10729        if (app.receivers.size() > 0) {
10730            Iterator<ReceiverList> it = app.receivers.iterator();
10731            while (it.hasNext()) {
10732                removeReceiverLocked(it.next());
10733            }
10734            app.receivers.clear();
10735        }
10736
10737        // If the app is undergoing backup, tell the backup manager about it
10738        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10739            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10740            try {
10741                IBackupManager bm = IBackupManager.Stub.asInterface(
10742                        ServiceManager.getService(Context.BACKUP_SERVICE));
10743                bm.agentDisconnected(app.info.packageName);
10744            } catch (RemoteException e) {
10745                // can't happen; backup manager is local
10746            }
10747        }
10748
10749        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10750            ProcessChangeItem item = mPendingProcessChanges.get(i);
10751            if (item.pid == app.pid) {
10752                mPendingProcessChanges.remove(i);
10753                mAvailProcessChanges.add(item);
10754            }
10755        }
10756        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10757
10758        // If the caller is restarting this app, then leave it in its
10759        // current lists and let the caller take care of it.
10760        if (restarting) {
10761            return;
10762        }
10763
10764        if (!app.persistent || app.isolated) {
10765            if (DEBUG_PROCESSES) Slog.v(TAG,
10766                    "Removing non-persistent process during cleanup: " + app);
10767            mProcessNames.remove(app.processName, app.uid);
10768            mIsolatedProcesses.remove(app.uid);
10769            if (mHeavyWeightProcess == app) {
10770                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10771                        mHeavyWeightProcess.userId, 0));
10772                mHeavyWeightProcess = null;
10773            }
10774        } else if (!app.removed) {
10775            // This app is persistent, so we need to keep its record around.
10776            // If it is not already on the pending app list, add it there
10777            // and start a new process for it.
10778            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10779                mPersistentStartingProcesses.add(app);
10780                restart = true;
10781            }
10782        }
10783        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10784                "Clean-up removing on hold: " + app);
10785        mProcessesOnHold.remove(app);
10786
10787        if (app == mHomeProcess) {
10788            mHomeProcess = null;
10789        }
10790        if (app == mPreviousProcess) {
10791            mPreviousProcess = null;
10792        }
10793
10794        if (restart && !app.isolated) {
10795            // We have components that still need to be running in the
10796            // process, so re-launch it.
10797            mProcessNames.put(app.processName, app.uid, app);
10798            startProcessLocked(app, "restart", app.processName);
10799        } else if (app.pid > 0 && app.pid != MY_PID) {
10800            // Goodbye!
10801            synchronized (mPidsSelfLocked) {
10802                mPidsSelfLocked.remove(app.pid);
10803                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10804            }
10805            app.setPid(0);
10806        }
10807    }
10808
10809    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10810        // Look through the content providers we are waiting to have launched,
10811        // and if any run in this process then either schedule a restart of
10812        // the process or kill the client waiting for it if this process has
10813        // gone bad.
10814        int NL = mLaunchingProviders.size();
10815        boolean restart = false;
10816        for (int i=0; i<NL; i++) {
10817            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10818            if (cpr.launchingApp == app) {
10819                if (!alwaysBad && !app.bad) {
10820                    restart = true;
10821                } else {
10822                    removeDyingProviderLocked(app, cpr, true);
10823                    // cpr should have been removed from mLaunchingProviders
10824                    NL = mLaunchingProviders.size();
10825                    i--;
10826                }
10827            }
10828        }
10829        return restart;
10830    }
10831
10832    // =========================================================
10833    // SERVICES
10834    // =========================================================
10835
10836    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10837            int flags) {
10838        enforceNotIsolatedCaller("getServices");
10839        synchronized (this) {
10840            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10841        }
10842    }
10843
10844    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10845        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10846        synchronized (this) {
10847            return mServices.getRunningServiceControlPanelLocked(name);
10848        }
10849    }
10850
10851    public ComponentName startService(IApplicationThread caller, Intent service,
10852            String resolvedType, int userId) {
10853        enforceNotIsolatedCaller("startService");
10854        // Refuse possible leaked file descriptors
10855        if (service != null && service.hasFileDescriptors() == true) {
10856            throw new IllegalArgumentException("File descriptors passed in Intent");
10857        }
10858
10859        if (DEBUG_SERVICE)
10860            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10861        synchronized(this) {
10862            final int callingPid = Binder.getCallingPid();
10863            final int callingUid = Binder.getCallingUid();
10864            checkValidCaller(callingUid, userId);
10865            final long origId = Binder.clearCallingIdentity();
10866            ComponentName res = mServices.startServiceLocked(caller, service,
10867                    resolvedType, callingPid, callingUid, userId);
10868            Binder.restoreCallingIdentity(origId);
10869            return res;
10870        }
10871    }
10872
10873    ComponentName startServiceInPackage(int uid,
10874            Intent service, String resolvedType, int userId) {
10875        synchronized(this) {
10876            if (DEBUG_SERVICE)
10877                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10878            final long origId = Binder.clearCallingIdentity();
10879            ComponentName res = mServices.startServiceLocked(null, service,
10880                    resolvedType, -1, uid, userId);
10881            Binder.restoreCallingIdentity(origId);
10882            return res;
10883        }
10884    }
10885
10886    public int stopService(IApplicationThread caller, Intent service,
10887            String resolvedType, int userId) {
10888        enforceNotIsolatedCaller("stopService");
10889        // Refuse possible leaked file descriptors
10890        if (service != null && service.hasFileDescriptors() == true) {
10891            throw new IllegalArgumentException("File descriptors passed in Intent");
10892        }
10893
10894        checkValidCaller(Binder.getCallingUid(), userId);
10895
10896        synchronized(this) {
10897            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10898        }
10899    }
10900
10901    public IBinder peekService(Intent service, String resolvedType) {
10902        enforceNotIsolatedCaller("peekService");
10903        // Refuse possible leaked file descriptors
10904        if (service != null && service.hasFileDescriptors() == true) {
10905            throw new IllegalArgumentException("File descriptors passed in Intent");
10906        }
10907        synchronized(this) {
10908            return mServices.peekServiceLocked(service, resolvedType);
10909        }
10910    }
10911
10912    public boolean stopServiceToken(ComponentName className, IBinder token,
10913            int startId) {
10914        synchronized(this) {
10915            return mServices.stopServiceTokenLocked(className, token, startId);
10916        }
10917    }
10918
10919    public void setServiceForeground(ComponentName className, IBinder token,
10920            int id, Notification notification, boolean removeNotification) {
10921        synchronized(this) {
10922            mServices.setServiceForegroundLocked(className, token, id, notification,
10923                    removeNotification);
10924        }
10925    }
10926
10927    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
10928            boolean requireFull, String name, String callerPackage) {
10929        synchronized(this) {
10930            return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll,
10931                    requireFull, name, callerPackage);
10932        }
10933    }
10934
10935    int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll,
10936            boolean requireFull, String name, String callerPackage) {
10937        final int callingUserId = UserHandle.getUserId(callingUid);
10938        if (callingUserId != userId) {
10939            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10940                if ((requireFull || checkComponentPermission(
10941                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10942                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
10943                        && checkComponentPermission(
10944                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10945                                callingPid, callingUid, -1, true)
10946                                != PackageManager.PERMISSION_GRANTED) {
10947                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
10948                        // In this case, they would like to just execute as their
10949                        // owner user instead of failing.
10950                        userId = callingUserId;
10951                    } else {
10952                        StringBuilder builder = new StringBuilder(128);
10953                        builder.append("Permission Denial: ");
10954                        builder.append(name);
10955                        if (callerPackage != null) {
10956                            builder.append(" from ");
10957                            builder.append(callerPackage);
10958                        }
10959                        builder.append(" asks to run as user ");
10960                        builder.append(userId);
10961                        builder.append(" but is calling from user ");
10962                        builder.append(UserHandle.getUserId(callingUid));
10963                        builder.append("; this requires ");
10964                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
10965                        if (!requireFull) {
10966                            builder.append(" or ");
10967                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
10968                        }
10969                        String msg = builder.toString();
10970                        Slog.w(TAG, msg);
10971                        throw new SecurityException(msg);
10972                    }
10973                }
10974            }
10975            if (userId == UserHandle.USER_CURRENT
10976                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
10977                userId = mCurrentUserId;
10978            }
10979            if (!allowAll && userId < 0) {
10980                throw new IllegalArgumentException(
10981                        "Call does not support special user #" + userId);
10982            }
10983        }
10984        return userId;
10985    }
10986
10987    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10988            String className, int flags) {
10989        boolean result = false;
10990        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10991            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10992                if (ActivityManager.checkUidPermission(
10993                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10994                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10995                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10996                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10997                            + " requests FLAG_SINGLE_USER, but app does not hold "
10998                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10999                    Slog.w(TAG, msg);
11000                    throw new SecurityException(msg);
11001                }
11002                result = true;
11003            }
11004        } else if (componentProcessName == aInfo.packageName) {
11005            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
11006        } else if ("system".equals(componentProcessName)) {
11007            result = true;
11008        }
11009        if (DEBUG_MU) {
11010            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
11011                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
11012        }
11013        return result;
11014    }
11015
11016    public int bindService(IApplicationThread caller, IBinder token,
11017            Intent service, String resolvedType,
11018            IServiceConnection connection, int flags, int userId) {
11019        enforceNotIsolatedCaller("bindService");
11020        // Refuse possible leaked file descriptors
11021        if (service != null && service.hasFileDescriptors() == true) {
11022            throw new IllegalArgumentException("File descriptors passed in Intent");
11023        }
11024
11025        synchronized(this) {
11026            return mServices.bindServiceLocked(caller, token, service, resolvedType,
11027                    connection, flags, userId);
11028        }
11029    }
11030
11031    public boolean unbindService(IServiceConnection connection) {
11032        synchronized (this) {
11033            return mServices.unbindServiceLocked(connection);
11034        }
11035    }
11036
11037    public void publishService(IBinder token, Intent intent, IBinder service) {
11038        // Refuse possible leaked file descriptors
11039        if (intent != null && intent.hasFileDescriptors() == true) {
11040            throw new IllegalArgumentException("File descriptors passed in Intent");
11041        }
11042
11043        synchronized(this) {
11044            if (!(token instanceof ServiceRecord)) {
11045                throw new IllegalArgumentException("Invalid service token");
11046            }
11047            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
11048        }
11049    }
11050
11051    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11052        // Refuse possible leaked file descriptors
11053        if (intent != null && intent.hasFileDescriptors() == true) {
11054            throw new IllegalArgumentException("File descriptors passed in Intent");
11055        }
11056
11057        synchronized(this) {
11058            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
11059        }
11060    }
11061
11062    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11063        synchronized(this) {
11064            if (!(token instanceof ServiceRecord)) {
11065                throw new IllegalArgumentException("Invalid service token");
11066            }
11067            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
11068        }
11069    }
11070
11071    // =========================================================
11072    // BACKUP AND RESTORE
11073    // =========================================================
11074
11075    // Cause the target app to be launched if necessary and its backup agent
11076    // instantiated.  The backup agent will invoke backupAgentCreated() on the
11077    // activity manager to announce its creation.
11078    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11079        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
11080        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11081
11082        synchronized(this) {
11083            // !!! TODO: currently no check here that we're already bound
11084            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11085            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11086            synchronized (stats) {
11087                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11088            }
11089
11090            // Backup agent is now in use, its package can't be stopped.
11091            try {
11092                AppGlobals.getPackageManager().setPackageStoppedState(
11093                        app.packageName, false, UserHandle.getUserId(app.uid));
11094            } catch (RemoteException e) {
11095            } catch (IllegalArgumentException e) {
11096                Slog.w(TAG, "Failed trying to unstop package "
11097                        + app.packageName + ": " + e);
11098            }
11099
11100            BackupRecord r = new BackupRecord(ss, app, backupMode);
11101            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11102                    ? new ComponentName(app.packageName, app.backupAgentName)
11103                    : new ComponentName("android", "FullBackupAgent");
11104            // startProcessLocked() returns existing proc's record if it's already running
11105            ProcessRecord proc = startProcessLocked(app.processName, app,
11106                    false, 0, "backup", hostingName, false, false);
11107            if (proc == null) {
11108                Slog.e(TAG, "Unable to start backup agent process " + r);
11109                return false;
11110            }
11111
11112            r.app = proc;
11113            mBackupTarget = r;
11114            mBackupAppName = app.packageName;
11115
11116            // Try not to kill the process during backup
11117            updateOomAdjLocked(proc);
11118
11119            // If the process is already attached, schedule the creation of the backup agent now.
11120            // If it is not yet live, this will be done when it attaches to the framework.
11121            if (proc.thread != null) {
11122                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11123                try {
11124                    proc.thread.scheduleCreateBackupAgent(app,
11125                            compatibilityInfoForPackageLocked(app), backupMode);
11126                } catch (RemoteException e) {
11127                    // Will time out on the backup manager side
11128                }
11129            } else {
11130                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11131            }
11132            // Invariants: at this point, the target app process exists and the application
11133            // is either already running or in the process of coming up.  mBackupTarget and
11134            // mBackupAppName describe the app, so that when it binds back to the AM we
11135            // know that it's scheduled for a backup-agent operation.
11136        }
11137
11138        return true;
11139    }
11140
11141    // A backup agent has just come up
11142    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11143        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11144                + " = " + agent);
11145
11146        synchronized(this) {
11147            if (!agentPackageName.equals(mBackupAppName)) {
11148                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11149                return;
11150            }
11151        }
11152
11153        long oldIdent = Binder.clearCallingIdentity();
11154        try {
11155            IBackupManager bm = IBackupManager.Stub.asInterface(
11156                    ServiceManager.getService(Context.BACKUP_SERVICE));
11157            bm.agentConnected(agentPackageName, agent);
11158        } catch (RemoteException e) {
11159            // can't happen; the backup manager service is local
11160        } catch (Exception e) {
11161            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11162            e.printStackTrace();
11163        } finally {
11164            Binder.restoreCallingIdentity(oldIdent);
11165        }
11166    }
11167
11168    // done with this agent
11169    public void unbindBackupAgent(ApplicationInfo appInfo) {
11170        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11171        if (appInfo == null) {
11172            Slog.w(TAG, "unbind backup agent for null app");
11173            return;
11174        }
11175
11176        synchronized(this) {
11177            if (mBackupAppName == null) {
11178                Slog.w(TAG, "Unbinding backup agent with no active backup");
11179                return;
11180            }
11181
11182            if (!mBackupAppName.equals(appInfo.packageName)) {
11183                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11184                return;
11185            }
11186
11187            ProcessRecord proc = mBackupTarget.app;
11188            mBackupTarget = null;
11189            mBackupAppName = null;
11190
11191            // Not backing this app up any more; reset its OOM adjustment
11192            updateOomAdjLocked(proc);
11193
11194            // If the app crashed during backup, 'thread' will be null here
11195            if (proc.thread != null) {
11196                try {
11197                    proc.thread.scheduleDestroyBackupAgent(appInfo,
11198                            compatibilityInfoForPackageLocked(appInfo));
11199                } catch (Exception e) {
11200                    Slog.e(TAG, "Exception when unbinding backup agent:");
11201                    e.printStackTrace();
11202                }
11203            }
11204        }
11205    }
11206    // =========================================================
11207    // BROADCASTS
11208    // =========================================================
11209
11210    private final List getStickiesLocked(String action, IntentFilter filter,
11211            List cur, int userId) {
11212        final ContentResolver resolver = mContext.getContentResolver();
11213        HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11214        if (stickies == null) {
11215            return cur;
11216        }
11217        final ArrayList<Intent> list = stickies.get(action);
11218        if (list == null) {
11219            return cur;
11220        }
11221        int N = list.size();
11222        for (int i=0; i<N; i++) {
11223            Intent intent = list.get(i);
11224            if (filter.match(resolver, intent, true, TAG) >= 0) {
11225                if (cur == null) {
11226                    cur = new ArrayList<Intent>();
11227                }
11228                cur.add(intent);
11229            }
11230        }
11231        return cur;
11232    }
11233
11234    boolean isPendingBroadcastProcessLocked(int pid) {
11235        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11236                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11237    }
11238
11239    void skipPendingBroadcastLocked(int pid) {
11240            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11241            for (BroadcastQueue queue : mBroadcastQueues) {
11242                queue.skipPendingBroadcastLocked(pid);
11243            }
11244    }
11245
11246    // The app just attached; send any pending broadcasts that it should receive
11247    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11248        boolean didSomething = false;
11249        for (BroadcastQueue queue : mBroadcastQueues) {
11250            didSomething |= queue.sendPendingBroadcastsLocked(app);
11251        }
11252        return didSomething;
11253    }
11254
11255    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11256            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11257        enforceNotIsolatedCaller("registerReceiver");
11258        int callingUid;
11259        int callingPid;
11260        synchronized(this) {
11261            ProcessRecord callerApp = null;
11262            if (caller != null) {
11263                callerApp = getRecordForAppLocked(caller);
11264                if (callerApp == null) {
11265                    throw new SecurityException(
11266                            "Unable to find app for caller " + caller
11267                            + " (pid=" + Binder.getCallingPid()
11268                            + ") when registering receiver " + receiver);
11269                }
11270                if (callerApp.info.uid != Process.SYSTEM_UID &&
11271                        !callerApp.pkgList.contains(callerPackage)) {
11272                    throw new SecurityException("Given caller package " + callerPackage
11273                            + " is not running in process " + callerApp);
11274                }
11275                callingUid = callerApp.info.uid;
11276                callingPid = callerApp.pid;
11277            } else {
11278                callerPackage = null;
11279                callingUid = Binder.getCallingUid();
11280                callingPid = Binder.getCallingPid();
11281            }
11282
11283            userId = this.handleIncomingUserLocked(callingPid, callingUid, userId,
11284                    true, true, "registerReceiver", callerPackage);
11285
11286            List allSticky = null;
11287
11288            // Look for any matching sticky broadcasts...
11289            Iterator actions = filter.actionsIterator();
11290            if (actions != null) {
11291                while (actions.hasNext()) {
11292                    String action = (String)actions.next();
11293                    allSticky = getStickiesLocked(action, filter, allSticky,
11294                            UserHandle.USER_ALL);
11295                    allSticky = getStickiesLocked(action, filter, allSticky,
11296                            UserHandle.getUserId(callingUid));
11297                }
11298            } else {
11299                allSticky = getStickiesLocked(null, filter, allSticky,
11300                        UserHandle.USER_ALL);
11301                allSticky = getStickiesLocked(null, filter, allSticky,
11302                        UserHandle.getUserId(callingUid));
11303            }
11304
11305            // The first sticky in the list is returned directly back to
11306            // the client.
11307            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11308
11309            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11310                    + ": " + sticky);
11311
11312            if (receiver == null) {
11313                return sticky;
11314            }
11315
11316            ReceiverList rl
11317                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11318            if (rl == null) {
11319                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11320                        userId, receiver);
11321                if (rl.app != null) {
11322                    rl.app.receivers.add(rl);
11323                } else {
11324                    try {
11325                        receiver.asBinder().linkToDeath(rl, 0);
11326                    } catch (RemoteException e) {
11327                        return sticky;
11328                    }
11329                    rl.linkedToDeath = true;
11330                }
11331                mRegisteredReceivers.put(receiver.asBinder(), rl);
11332            } else if (rl.uid != callingUid) {
11333                throw new IllegalArgumentException(
11334                        "Receiver requested to register for uid " + callingUid
11335                        + " was previously registered for uid " + rl.uid);
11336            } else if (rl.pid != callingPid) {
11337                throw new IllegalArgumentException(
11338                        "Receiver requested to register for pid " + callingPid
11339                        + " was previously registered for pid " + rl.pid);
11340            } else if (rl.userId != userId) {
11341                throw new IllegalArgumentException(
11342                        "Receiver requested to register for user " + userId
11343                        + " was previously registered for user " + rl.userId);
11344            }
11345            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11346                    permission, callingUid, userId);
11347            rl.add(bf);
11348            if (!bf.debugCheck()) {
11349                Slog.w(TAG, "==> For Dynamic broadast");
11350            }
11351            mReceiverResolver.addFilter(bf);
11352
11353            // Enqueue broadcasts for all existing stickies that match
11354            // this filter.
11355            if (allSticky != null) {
11356                ArrayList receivers = new ArrayList();
11357                receivers.add(bf);
11358
11359                int N = allSticky.size();
11360                for (int i=0; i<N; i++) {
11361                    Intent intent = (Intent)allSticky.get(i);
11362                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11363                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11364                            null, -1, -1, null, receivers, null, 0, null, null,
11365                            false, true, true, -1);
11366                    queue.enqueueParallelBroadcastLocked(r);
11367                    queue.scheduleBroadcastsLocked();
11368                }
11369            }
11370
11371            return sticky;
11372        }
11373    }
11374
11375    public void unregisterReceiver(IIntentReceiver receiver) {
11376        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11377
11378        final long origId = Binder.clearCallingIdentity();
11379        try {
11380            boolean doTrim = false;
11381
11382            synchronized(this) {
11383                ReceiverList rl
11384                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11385                if (rl != null) {
11386                    if (rl.curBroadcast != null) {
11387                        BroadcastRecord r = rl.curBroadcast;
11388                        final boolean doNext = finishReceiverLocked(
11389                                receiver.asBinder(), r.resultCode, r.resultData,
11390                                r.resultExtras, r.resultAbort, true);
11391                        if (doNext) {
11392                            doTrim = true;
11393                            r.queue.processNextBroadcast(false);
11394                        }
11395                    }
11396
11397                    if (rl.app != null) {
11398                        rl.app.receivers.remove(rl);
11399                    }
11400                    removeReceiverLocked(rl);
11401                    if (rl.linkedToDeath) {
11402                        rl.linkedToDeath = false;
11403                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11404                    }
11405                }
11406            }
11407
11408            // If we actually concluded any broadcasts, we might now be able
11409            // to trim the recipients' apps from our working set
11410            if (doTrim) {
11411                trimApplications();
11412                return;
11413            }
11414
11415        } finally {
11416            Binder.restoreCallingIdentity(origId);
11417        }
11418    }
11419
11420    void removeReceiverLocked(ReceiverList rl) {
11421        mRegisteredReceivers.remove(rl.receiver.asBinder());
11422        int N = rl.size();
11423        for (int i=0; i<N; i++) {
11424            mReceiverResolver.removeFilter(rl.get(i));
11425        }
11426    }
11427
11428    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11429        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11430            ProcessRecord r = mLruProcesses.get(i);
11431            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11432                try {
11433                    r.thread.dispatchPackageBroadcast(cmd, packages);
11434                } catch (RemoteException ex) {
11435                }
11436            }
11437        }
11438    }
11439
11440    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11441            int[] users) {
11442        List<ResolveInfo> receivers = null;
11443        try {
11444            HashSet<ComponentName> singleUserReceivers = null;
11445            boolean scannedFirstReceivers = false;
11446            for (int user : users) {
11447                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11448                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11449                if (newReceivers != null && newReceivers.size() == 0) {
11450                    newReceivers = null;
11451                }
11452                if (receivers == null) {
11453                    receivers = newReceivers;
11454                } else if (newReceivers != null) {
11455                    // We need to concatenate the additional receivers
11456                    // found with what we have do far.  This would be easy,
11457                    // but we also need to de-dup any receivers that are
11458                    // singleUser.
11459                    if (!scannedFirstReceivers) {
11460                        // Collect any single user receivers we had already retrieved.
11461                        scannedFirstReceivers = true;
11462                        for (int i=0; i<receivers.size(); i++) {
11463                            ResolveInfo ri = receivers.get(i);
11464                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11465                                ComponentName cn = new ComponentName(
11466                                        ri.activityInfo.packageName, ri.activityInfo.name);
11467                                if (singleUserReceivers == null) {
11468                                    singleUserReceivers = new HashSet<ComponentName>();
11469                                }
11470                                singleUserReceivers.add(cn);
11471                            }
11472                        }
11473                    }
11474                    // Add the new results to the existing results, tracking
11475                    // and de-dupping single user receivers.
11476                    for (int i=0; i<newReceivers.size(); i++) {
11477                        ResolveInfo ri = newReceivers.get(i);
11478                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11479                            ComponentName cn = new ComponentName(
11480                                    ri.activityInfo.packageName, ri.activityInfo.name);
11481                            if (singleUserReceivers == null) {
11482                                singleUserReceivers = new HashSet<ComponentName>();
11483                            }
11484                            if (!singleUserReceivers.contains(cn)) {
11485                                singleUserReceivers.add(cn);
11486                                receivers.add(ri);
11487                            }
11488                        } else {
11489                            receivers.add(ri);
11490                        }
11491                    }
11492                }
11493            }
11494        } catch (RemoteException ex) {
11495            // pm is in same process, this will never happen.
11496        }
11497        return receivers;
11498    }
11499
11500    private final int broadcastIntentLocked(ProcessRecord callerApp,
11501            String callerPackage, Intent intent, String resolvedType,
11502            IIntentReceiver resultTo, int resultCode, String resultData,
11503            Bundle map, String requiredPermission,
11504            boolean ordered, boolean sticky, int callingPid, int callingUid,
11505            int userId) {
11506        intent = new Intent(intent);
11507
11508        // By default broadcasts do not go to stopped apps.
11509        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11510
11511        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11512            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11513            + " ordered=" + ordered + " userid=" + userId);
11514        if ((resultTo != null) && !ordered) {
11515            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11516        }
11517
11518        userId = handleIncomingUserLocked(callingPid, callingUid, userId,
11519                true, false, "broadcast", callerPackage);
11520
11521        // Make sure that the user who is receiving this broadcast is started.
11522        // If not, we will just skip it.
11523        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11524            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
11525                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
11526                Slog.w(TAG, "Skipping broadcast of " + intent
11527                        + ": user " + userId + " is stopped");
11528                return ActivityManager.BROADCAST_SUCCESS;
11529            }
11530        }
11531
11532        /*
11533         * Prevent non-system code (defined here to be non-persistent
11534         * processes) from sending protected broadcasts.
11535         */
11536        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11537            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11538            callingUid == 0) {
11539            // Always okay.
11540        } else if (callerApp == null || !callerApp.persistent) {
11541            try {
11542                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11543                        intent.getAction())) {
11544                    String msg = "Permission Denial: not allowed to send broadcast "
11545                            + intent.getAction() + " from pid="
11546                            + callingPid + ", uid=" + callingUid;
11547                    Slog.w(TAG, msg);
11548                    throw new SecurityException(msg);
11549                }
11550            } catch (RemoteException e) {
11551                Slog.w(TAG, "Remote exception", e);
11552                return ActivityManager.BROADCAST_SUCCESS;
11553            }
11554        }
11555
11556        // Handle special intents: if this broadcast is from the package
11557        // manager about a package being removed, we need to remove all of
11558        // its activities from the history stack.
11559        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11560                intent.getAction());
11561        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11562                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11563                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11564                || uidRemoved) {
11565            if (checkComponentPermission(
11566                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11567                    callingPid, callingUid, -1, true)
11568                    == PackageManager.PERMISSION_GRANTED) {
11569                if (uidRemoved) {
11570                    final Bundle intentExtras = intent.getExtras();
11571                    final int uid = intentExtras != null
11572                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11573                    if (uid >= 0) {
11574                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11575                        synchronized (bs) {
11576                            bs.removeUidStatsLocked(uid);
11577                        }
11578                    }
11579                } else {
11580                    // If resources are unavailable just force stop all
11581                    // those packages and flush the attribute cache as well.
11582                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11583                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11584                        if (list != null && (list.length > 0)) {
11585                            for (String pkg : list) {
11586                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11587                            }
11588                            sendPackageBroadcastLocked(
11589                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11590                        }
11591                    } else {
11592                        Uri data = intent.getData();
11593                        String ssp;
11594                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11595                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11596                                forceStopPackageLocked(ssp,
11597                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11598                                        false, userId);
11599                            }
11600                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11601                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11602                                        new String[] {ssp}, userId);
11603                            }
11604                        }
11605                    }
11606                }
11607            } else {
11608                String msg = "Permission Denial: " + intent.getAction()
11609                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11610                        + ", uid=" + callingUid + ")"
11611                        + " requires "
11612                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11613                Slog.w(TAG, msg);
11614                throw new SecurityException(msg);
11615            }
11616
11617        // Special case for adding a package: by default turn on compatibility
11618        // mode.
11619        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11620            Uri data = intent.getData();
11621            String ssp;
11622            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11623                mCompatModePackages.handlePackageAddedLocked(ssp,
11624                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11625            }
11626        }
11627
11628        /*
11629         * If this is the time zone changed action, queue up a message that will reset the timezone
11630         * of all currently running processes. This message will get queued up before the broadcast
11631         * happens.
11632         */
11633        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11634            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11635        }
11636
11637        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11638            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11639        }
11640
11641        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11642            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11643            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11644        }
11645
11646        // Add to the sticky list if requested.
11647        if (sticky) {
11648            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11649                    callingPid, callingUid)
11650                    != PackageManager.PERMISSION_GRANTED) {
11651                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11652                        + callingPid + ", uid=" + callingUid
11653                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11654                Slog.w(TAG, msg);
11655                throw new SecurityException(msg);
11656            }
11657            if (requiredPermission != null) {
11658                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11659                        + " and enforce permission " + requiredPermission);
11660                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11661            }
11662            if (intent.getComponent() != null) {
11663                throw new SecurityException(
11664                        "Sticky broadcasts can't target a specific component");
11665            }
11666            // We use userId directly here, since the "all" target is maintained
11667            // as a separate set of sticky broadcasts.
11668            if (userId != UserHandle.USER_ALL) {
11669                // But first, if this is not a broadcast to all users, then
11670                // make sure it doesn't conflict with an existing broadcast to
11671                // all users.
11672                HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11673                        UserHandle.USER_ALL);
11674                if (stickies != null) {
11675                    ArrayList<Intent> list = stickies.get(intent.getAction());
11676                    if (list != null) {
11677                        int N = list.size();
11678                        int i;
11679                        for (i=0; i<N; i++) {
11680                            if (intent.filterEquals(list.get(i))) {
11681                                throw new IllegalArgumentException(
11682                                        "Sticky broadcast " + intent + " for user "
11683                                        + userId + " conflicts with existing global broadcast");
11684                            }
11685                        }
11686                    }
11687                }
11688            }
11689            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11690            if (stickies == null) {
11691                stickies = new HashMap<String, ArrayList<Intent>>();
11692                mStickyBroadcasts.put(userId, stickies);
11693            }
11694            ArrayList<Intent> list = stickies.get(intent.getAction());
11695            if (list == null) {
11696                list = new ArrayList<Intent>();
11697                stickies.put(intent.getAction(), list);
11698            }
11699            int N = list.size();
11700            int i;
11701            for (i=0; i<N; i++) {
11702                if (intent.filterEquals(list.get(i))) {
11703                    // This sticky already exists, replace it.
11704                    list.set(i, new Intent(intent));
11705                    break;
11706                }
11707            }
11708            if (i >= N) {
11709                list.add(new Intent(intent));
11710            }
11711        }
11712
11713        int[] users;
11714        if (userId == UserHandle.USER_ALL) {
11715            // Caller wants broadcast to go to all started users.
11716            users = mStartedUserArray;
11717        } else {
11718            // Caller wants broadcast to go to one specific user.
11719            users = mCurrentUserArray;
11720        }
11721
11722        // Figure out who all will receive this broadcast.
11723        List receivers = null;
11724        List<BroadcastFilter> registeredReceivers = null;
11725        // Need to resolve the intent to interested receivers...
11726        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11727                 == 0) {
11728            receivers = collectReceiverComponents(intent, resolvedType, users);
11729        }
11730        if (intent.getComponent() == null) {
11731            registeredReceivers = mReceiverResolver.queryIntent(intent,
11732                    resolvedType, false, userId);
11733        }
11734
11735        final boolean replacePending =
11736                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11737
11738        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11739                + " replacePending=" + replacePending);
11740
11741        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11742        if (!ordered && NR > 0) {
11743            // If we are not serializing this broadcast, then send the
11744            // registered receivers separately so they don't wait for the
11745            // components to be launched.
11746            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11747            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11748                    callerPackage, callingPid, callingUid, requiredPermission,
11749                    registeredReceivers, resultTo, resultCode, resultData, map,
11750                    ordered, sticky, false, userId);
11751            if (DEBUG_BROADCAST) Slog.v(
11752                    TAG, "Enqueueing parallel broadcast " + r);
11753            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11754            if (!replaced) {
11755                queue.enqueueParallelBroadcastLocked(r);
11756                queue.scheduleBroadcastsLocked();
11757            }
11758            registeredReceivers = null;
11759            NR = 0;
11760        }
11761
11762        // Merge into one list.
11763        int ir = 0;
11764        if (receivers != null) {
11765            // A special case for PACKAGE_ADDED: do not allow the package
11766            // being added to see this broadcast.  This prevents them from
11767            // using this as a back door to get run as soon as they are
11768            // installed.  Maybe in the future we want to have a special install
11769            // broadcast or such for apps, but we'd like to deliberately make
11770            // this decision.
11771            String skipPackages[] = null;
11772            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11773                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11774                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11775                Uri data = intent.getData();
11776                if (data != null) {
11777                    String pkgName = data.getSchemeSpecificPart();
11778                    if (pkgName != null) {
11779                        skipPackages = new String[] { pkgName };
11780                    }
11781                }
11782            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11783                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11784            }
11785            if (skipPackages != null && (skipPackages.length > 0)) {
11786                for (String skipPackage : skipPackages) {
11787                    if (skipPackage != null) {
11788                        int NT = receivers.size();
11789                        for (int it=0; it<NT; it++) {
11790                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11791                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11792                                receivers.remove(it);
11793                                it--;
11794                                NT--;
11795                            }
11796                        }
11797                    }
11798                }
11799            }
11800
11801            int NT = receivers != null ? receivers.size() : 0;
11802            int it = 0;
11803            ResolveInfo curt = null;
11804            BroadcastFilter curr = null;
11805            while (it < NT && ir < NR) {
11806                if (curt == null) {
11807                    curt = (ResolveInfo)receivers.get(it);
11808                }
11809                if (curr == null) {
11810                    curr = registeredReceivers.get(ir);
11811                }
11812                if (curr.getPriority() >= curt.priority) {
11813                    // Insert this broadcast record into the final list.
11814                    receivers.add(it, curr);
11815                    ir++;
11816                    curr = null;
11817                    it++;
11818                    NT++;
11819                } else {
11820                    // Skip to the next ResolveInfo in the final list.
11821                    it++;
11822                    curt = null;
11823                }
11824            }
11825        }
11826        while (ir < NR) {
11827            if (receivers == null) {
11828                receivers = new ArrayList();
11829            }
11830            receivers.add(registeredReceivers.get(ir));
11831            ir++;
11832        }
11833
11834        if ((receivers != null && receivers.size() > 0)
11835                || resultTo != null) {
11836            BroadcastQueue queue = broadcastQueueForIntent(intent);
11837            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11838                    callerPackage, callingPid, callingUid, requiredPermission,
11839                    receivers, resultTo, resultCode, resultData, map, ordered,
11840                    sticky, false, userId);
11841            if (DEBUG_BROADCAST) Slog.v(
11842                    TAG, "Enqueueing ordered broadcast " + r
11843                    + ": prev had " + queue.mOrderedBroadcasts.size());
11844            if (DEBUG_BROADCAST) {
11845                int seq = r.intent.getIntExtra("seq", -1);
11846                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11847            }
11848            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11849            if (!replaced) {
11850                queue.enqueueOrderedBroadcastLocked(r);
11851                queue.scheduleBroadcastsLocked();
11852            }
11853        }
11854
11855        return ActivityManager.BROADCAST_SUCCESS;
11856    }
11857
11858    final Intent verifyBroadcastLocked(Intent intent) {
11859        // Refuse possible leaked file descriptors
11860        if (intent != null && intent.hasFileDescriptors() == true) {
11861            throw new IllegalArgumentException("File descriptors passed in Intent");
11862        }
11863
11864        int flags = intent.getFlags();
11865
11866        if (!mProcessesReady) {
11867            // if the caller really truly claims to know what they're doing, go
11868            // ahead and allow the broadcast without launching any receivers
11869            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11870                intent = new Intent(intent);
11871                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11872            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11873                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11874                        + " before boot completion");
11875                throw new IllegalStateException("Cannot broadcast before boot completed");
11876            }
11877        }
11878
11879        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11880            throw new IllegalArgumentException(
11881                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11882        }
11883
11884        return intent;
11885    }
11886
11887    public final int broadcastIntent(IApplicationThread caller,
11888            Intent intent, String resolvedType, IIntentReceiver resultTo,
11889            int resultCode, String resultData, Bundle map,
11890            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11891        enforceNotIsolatedCaller("broadcastIntent");
11892        synchronized(this) {
11893            intent = verifyBroadcastLocked(intent);
11894
11895            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11896            final int callingPid = Binder.getCallingPid();
11897            final int callingUid = Binder.getCallingUid();
11898            final long origId = Binder.clearCallingIdentity();
11899            int res = broadcastIntentLocked(callerApp,
11900                    callerApp != null ? callerApp.info.packageName : null,
11901                    intent, resolvedType, resultTo,
11902                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11903                    callingPid, callingUid, userId);
11904            Binder.restoreCallingIdentity(origId);
11905            return res;
11906        }
11907    }
11908
11909    int broadcastIntentInPackage(String packageName, int uid,
11910            Intent intent, String resolvedType, IIntentReceiver resultTo,
11911            int resultCode, String resultData, Bundle map,
11912            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11913        synchronized(this) {
11914            intent = verifyBroadcastLocked(intent);
11915
11916            final long origId = Binder.clearCallingIdentity();
11917            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11918                    resultTo, resultCode, resultData, map, requiredPermission,
11919                    serialized, sticky, -1, uid, userId);
11920            Binder.restoreCallingIdentity(origId);
11921            return res;
11922        }
11923    }
11924
11925    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11926        // Refuse possible leaked file descriptors
11927        if (intent != null && intent.hasFileDescriptors() == true) {
11928            throw new IllegalArgumentException("File descriptors passed in Intent");
11929        }
11930
11931        userId = handleIncomingUserLocked(Binder.getCallingPid(),
11932                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
11933
11934        synchronized(this) {
11935            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11936                    != PackageManager.PERMISSION_GRANTED) {
11937                String msg = "Permission Denial: unbroadcastIntent() from pid="
11938                        + Binder.getCallingPid()
11939                        + ", uid=" + Binder.getCallingUid()
11940                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11941                Slog.w(TAG, msg);
11942                throw new SecurityException(msg);
11943            }
11944            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11945            if (stickies != null) {
11946                ArrayList<Intent> list = stickies.get(intent.getAction());
11947                if (list != null) {
11948                    int N = list.size();
11949                    int i;
11950                    for (i=0; i<N; i++) {
11951                        if (intent.filterEquals(list.get(i))) {
11952                            list.remove(i);
11953                            break;
11954                        }
11955                    }
11956                    if (list.size() <= 0) {
11957                        stickies.remove(intent.getAction());
11958                    }
11959                }
11960                if (stickies.size() <= 0) {
11961                    mStickyBroadcasts.remove(userId);
11962                }
11963            }
11964        }
11965    }
11966
11967    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11968            String resultData, Bundle resultExtras, boolean resultAbort,
11969            boolean explicit) {
11970        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11971        if (r == null) {
11972            Slog.w(TAG, "finishReceiver called but not found on queue");
11973            return false;
11974        }
11975
11976        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11977                explicit);
11978    }
11979
11980    public void finishReceiver(IBinder who, int resultCode, String resultData,
11981            Bundle resultExtras, boolean resultAbort) {
11982        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11983
11984        // Refuse possible leaked file descriptors
11985        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11986            throw new IllegalArgumentException("File descriptors passed in Bundle");
11987        }
11988
11989        final long origId = Binder.clearCallingIdentity();
11990        try {
11991            boolean doNext = false;
11992            BroadcastRecord r = null;
11993
11994            synchronized(this) {
11995                r = broadcastRecordForReceiverLocked(who);
11996                if (r != null) {
11997                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11998                        resultData, resultExtras, resultAbort, true);
11999                }
12000            }
12001
12002            if (doNext) {
12003                r.queue.processNextBroadcast(false);
12004            }
12005            trimApplications();
12006        } finally {
12007            Binder.restoreCallingIdentity(origId);
12008        }
12009    }
12010
12011    // =========================================================
12012    // INSTRUMENTATION
12013    // =========================================================
12014
12015    public boolean startInstrumentation(ComponentName className,
12016            String profileFile, int flags, Bundle arguments,
12017            IInstrumentationWatcher watcher, int userId) {
12018        enforceNotIsolatedCaller("startInstrumentation");
12019        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
12020                userId, false, true, "startInstrumentation", null);
12021        // Refuse possible leaked file descriptors
12022        if (arguments != null && arguments.hasFileDescriptors()) {
12023            throw new IllegalArgumentException("File descriptors passed in Bundle");
12024        }
12025
12026        synchronized(this) {
12027            InstrumentationInfo ii = null;
12028            ApplicationInfo ai = null;
12029            try {
12030                ii = mContext.getPackageManager().getInstrumentationInfo(
12031                    className, STOCK_PM_FLAGS);
12032                ai = AppGlobals.getPackageManager().getApplicationInfo(
12033                        ii.targetPackage, STOCK_PM_FLAGS, userId);
12034            } catch (PackageManager.NameNotFoundException e) {
12035            } catch (RemoteException e) {
12036            }
12037            if (ii == null) {
12038                reportStartInstrumentationFailure(watcher, className,
12039                        "Unable to find instrumentation info for: " + className);
12040                return false;
12041            }
12042            if (ai == null) {
12043                reportStartInstrumentationFailure(watcher, className,
12044                        "Unable to find instrumentation target package: " + ii.targetPackage);
12045                return false;
12046            }
12047
12048            int match = mContext.getPackageManager().checkSignatures(
12049                    ii.targetPackage, ii.packageName);
12050            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12051                String msg = "Permission Denial: starting instrumentation "
12052                        + className + " from pid="
12053                        + Binder.getCallingPid()
12054                        + ", uid=" + Binder.getCallingPid()
12055                        + " not allowed because package " + ii.packageName
12056                        + " does not have a signature matching the target "
12057                        + ii.targetPackage;
12058                reportStartInstrumentationFailure(watcher, className, msg);
12059                throw new SecurityException(msg);
12060            }
12061
12062            final long origId = Binder.clearCallingIdentity();
12063            // Instrumentation can kill and relaunch even persistent processes
12064            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
12065            ProcessRecord app = addAppLocked(ai, false);
12066            app.instrumentationClass = className;
12067            app.instrumentationInfo = ai;
12068            app.instrumentationProfileFile = profileFile;
12069            app.instrumentationArguments = arguments;
12070            app.instrumentationWatcher = watcher;
12071            app.instrumentationResultClass = className;
12072            Binder.restoreCallingIdentity(origId);
12073        }
12074
12075        return true;
12076    }
12077
12078    /**
12079     * Report errors that occur while attempting to start Instrumentation.  Always writes the
12080     * error to the logs, but if somebody is watching, send the report there too.  This enables
12081     * the "am" command to report errors with more information.
12082     *
12083     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12084     * @param cn The component name of the instrumentation.
12085     * @param report The error report.
12086     */
12087    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12088            ComponentName cn, String report) {
12089        Slog.w(TAG, report);
12090        try {
12091            if (watcher != null) {
12092                Bundle results = new Bundle();
12093                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12094                results.putString("Error", report);
12095                watcher.instrumentationStatus(cn, -1, results);
12096            }
12097        } catch (RemoteException e) {
12098            Slog.w(TAG, e);
12099        }
12100    }
12101
12102    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12103        if (app.instrumentationWatcher != null) {
12104            try {
12105                // NOTE:  IInstrumentationWatcher *must* be oneway here
12106                app.instrumentationWatcher.instrumentationFinished(
12107                    app.instrumentationClass,
12108                    resultCode,
12109                    results);
12110            } catch (RemoteException e) {
12111            }
12112        }
12113        app.instrumentationWatcher = null;
12114        app.instrumentationClass = null;
12115        app.instrumentationInfo = null;
12116        app.instrumentationProfileFile = null;
12117        app.instrumentationArguments = null;
12118
12119        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12120    }
12121
12122    public void finishInstrumentation(IApplicationThread target,
12123            int resultCode, Bundle results) {
12124        int userId = UserHandle.getCallingUserId();
12125        // Refuse possible leaked file descriptors
12126        if (results != null && results.hasFileDescriptors()) {
12127            throw new IllegalArgumentException("File descriptors passed in Intent");
12128        }
12129
12130        synchronized(this) {
12131            ProcessRecord app = getRecordForAppLocked(target);
12132            if (app == null) {
12133                Slog.w(TAG, "finishInstrumentation: no app for " + target);
12134                return;
12135            }
12136            final long origId = Binder.clearCallingIdentity();
12137            finishInstrumentationLocked(app, resultCode, results);
12138            Binder.restoreCallingIdentity(origId);
12139        }
12140    }
12141
12142    // =========================================================
12143    // CONFIGURATION
12144    // =========================================================
12145
12146    public ConfigurationInfo getDeviceConfigurationInfo() {
12147        ConfigurationInfo config = new ConfigurationInfo();
12148        synchronized (this) {
12149            config.reqTouchScreen = mConfiguration.touchscreen;
12150            config.reqKeyboardType = mConfiguration.keyboard;
12151            config.reqNavigation = mConfiguration.navigation;
12152            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12153                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12154                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12155            }
12156            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12157                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12158                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12159            }
12160            config.reqGlEsVersion = GL_ES_VERSION;
12161        }
12162        return config;
12163    }
12164
12165    public Configuration getConfiguration() {
12166        Configuration ci;
12167        synchronized(this) {
12168            ci = new Configuration(mConfiguration);
12169        }
12170        return ci;
12171    }
12172
12173    public void updatePersistentConfiguration(Configuration values) {
12174        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12175                "updateConfiguration()");
12176        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12177                "updateConfiguration()");
12178        if (values == null) {
12179            throw new NullPointerException("Configuration must not be null");
12180        }
12181
12182        synchronized(this) {
12183            final long origId = Binder.clearCallingIdentity();
12184            updateConfigurationLocked(values, null, true, false);
12185            Binder.restoreCallingIdentity(origId);
12186        }
12187    }
12188
12189    public void updateConfiguration(Configuration values) {
12190        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12191                "updateConfiguration()");
12192
12193        synchronized(this) {
12194            if (values == null && mWindowManager != null) {
12195                // sentinel: fetch the current configuration from the window manager
12196                values = mWindowManager.computeNewConfiguration();
12197            }
12198
12199            if (mWindowManager != null) {
12200                mProcessList.applyDisplaySize(mWindowManager);
12201            }
12202
12203            final long origId = Binder.clearCallingIdentity();
12204            if (values != null) {
12205                Settings.System.clearConfiguration(values);
12206            }
12207            updateConfigurationLocked(values, null, false, false);
12208            Binder.restoreCallingIdentity(origId);
12209        }
12210    }
12211
12212    /**
12213     * Do either or both things: (1) change the current configuration, and (2)
12214     * make sure the given activity is running with the (now) current
12215     * configuration.  Returns true if the activity has been left running, or
12216     * false if <var>starting</var> is being destroyed to match the new
12217     * configuration.
12218     * @param persistent TODO
12219     */
12220    boolean updateConfigurationLocked(Configuration values,
12221            ActivityRecord starting, boolean persistent, boolean initLocale) {
12222        // do nothing if we are headless
12223        if (mHeadless) return true;
12224
12225        int changes = 0;
12226
12227        boolean kept = true;
12228
12229        if (values != null) {
12230            Configuration newConfig = new Configuration(mConfiguration);
12231            changes = newConfig.updateFrom(values);
12232            if (changes != 0) {
12233                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12234                    Slog.i(TAG, "Updating configuration to: " + values);
12235                }
12236
12237                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12238
12239                if (values.locale != null && !initLocale) {
12240                    saveLocaleLocked(values.locale,
12241                                     !values.locale.equals(mConfiguration.locale),
12242                                     values.userSetLocale);
12243                }
12244
12245                mConfigurationSeq++;
12246                if (mConfigurationSeq <= 0) {
12247                    mConfigurationSeq = 1;
12248                }
12249                newConfig.seq = mConfigurationSeq;
12250                mConfiguration = newConfig;
12251                Slog.i(TAG, "Config changed: " + newConfig);
12252
12253                final Configuration configCopy = new Configuration(mConfiguration);
12254
12255                // TODO: If our config changes, should we auto dismiss any currently
12256                // showing dialogs?
12257                mShowDialogs = shouldShowDialogs(newConfig);
12258
12259                AttributeCache ac = AttributeCache.instance();
12260                if (ac != null) {
12261                    ac.updateConfiguration(configCopy);
12262                }
12263
12264                // Make sure all resources in our process are updated
12265                // right now, so that anyone who is going to retrieve
12266                // resource values after we return will be sure to get
12267                // the new ones.  This is especially important during
12268                // boot, where the first config change needs to guarantee
12269                // all resources have that config before following boot
12270                // code is executed.
12271                mSystemThread.applyConfigurationToResources(configCopy);
12272
12273                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12274                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12275                    msg.obj = new Configuration(configCopy);
12276                    mHandler.sendMessage(msg);
12277                }
12278
12279                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12280                    ProcessRecord app = mLruProcesses.get(i);
12281                    try {
12282                        if (app.thread != null) {
12283                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12284                                    + app.processName + " new config " + mConfiguration);
12285                            app.thread.scheduleConfigurationChanged(configCopy);
12286                        }
12287                    } catch (Exception e) {
12288                    }
12289                }
12290                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12291                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12292                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
12293                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12294                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12295                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12296                    broadcastIntentLocked(null, null,
12297                            new Intent(Intent.ACTION_LOCALE_CHANGED),
12298                            null, null, 0, null, null,
12299                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12300                }
12301            }
12302        }
12303
12304        if (changes != 0 && starting == null) {
12305            // If the configuration changed, and the caller is not already
12306            // in the process of starting an activity, then find the top
12307            // activity to check if its configuration needs to change.
12308            starting = mMainStack.topRunningActivityLocked(null);
12309        }
12310
12311        if (starting != null) {
12312            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12313            // And we need to make sure at this point that all other activities
12314            // are made visible with the correct configuration.
12315            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12316        }
12317
12318        if (values != null && mWindowManager != null) {
12319            mWindowManager.setNewConfiguration(mConfiguration);
12320        }
12321
12322        return kept;
12323    }
12324
12325    /**
12326     * Decide based on the configuration whether we should shouw the ANR,
12327     * crash, etc dialogs.  The idea is that if there is no affordnace to
12328     * press the on-screen buttons, we shouldn't show the dialog.
12329     *
12330     * A thought: SystemUI might also want to get told about this, the Power
12331     * dialog / global actions also might want different behaviors.
12332     */
12333    private static final boolean shouldShowDialogs(Configuration config) {
12334        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12335                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12336    }
12337
12338    /**
12339     * Save the locale.  You must be inside a synchronized (this) block.
12340     */
12341    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12342        if(isDiff) {
12343            SystemProperties.set("user.language", l.getLanguage());
12344            SystemProperties.set("user.region", l.getCountry());
12345        }
12346
12347        if(isPersist) {
12348            SystemProperties.set("persist.sys.language", l.getLanguage());
12349            SystemProperties.set("persist.sys.country", l.getCountry());
12350            SystemProperties.set("persist.sys.localevar", l.getVariant());
12351        }
12352    }
12353
12354    @Override
12355    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12356        ActivityRecord srec = ActivityRecord.forToken(token);
12357        return srec != null && srec.task.affinity != null &&
12358                srec.task.affinity.equals(destAffinity);
12359    }
12360
12361    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12362            Intent resultData) {
12363        ComponentName dest = destIntent.getComponent();
12364
12365        synchronized (this) {
12366            ActivityRecord srec = ActivityRecord.forToken(token);
12367            if (srec == null) {
12368                return false;
12369            }
12370            ArrayList<ActivityRecord> history = srec.stack.mHistory;
12371            final int start = history.indexOf(srec);
12372            if (start < 0) {
12373                // Current activity is not in history stack; do nothing.
12374                return false;
12375            }
12376            int finishTo = start - 1;
12377            ActivityRecord parent = null;
12378            boolean foundParentInTask = false;
12379            if (dest != null) {
12380                TaskRecord tr = srec.task;
12381                for (int i = start - 1; i >= 0; i--) {
12382                    ActivityRecord r = history.get(i);
12383                    if (tr != r.task) {
12384                        // Couldn't find parent in the same task; stop at the one above this.
12385                        // (Root of current task; in-app "home" behavior)
12386                        // Always at least finish the current activity.
12387                        finishTo = Math.min(start - 1, i + 1);
12388                        parent = history.get(finishTo);
12389                        break;
12390                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
12391                            r.info.name.equals(dest.getClassName())) {
12392                        finishTo = i;
12393                        parent = r;
12394                        foundParentInTask = true;
12395                        break;
12396                    }
12397                }
12398            }
12399
12400            if (mController != null) {
12401                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12402                if (next != null) {
12403                    // ask watcher if this is allowed
12404                    boolean resumeOK = true;
12405                    try {
12406                        resumeOK = mController.activityResuming(next.packageName);
12407                    } catch (RemoteException e) {
12408                        mController = null;
12409                    }
12410
12411                    if (!resumeOK) {
12412                        return false;
12413                    }
12414                }
12415            }
12416            final long origId = Binder.clearCallingIdentity();
12417            for (int i = start; i > finishTo; i--) {
12418                ActivityRecord r = history.get(i);
12419                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12420                        "navigate-up", true);
12421                // Only return the supplied result for the first activity finished
12422                resultCode = Activity.RESULT_CANCELED;
12423                resultData = null;
12424            }
12425
12426            if (parent != null && foundParentInTask) {
12427                final int parentLaunchMode = parent.info.launchMode;
12428                final int destIntentFlags = destIntent.getFlags();
12429                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12430                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12431                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12432                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12433                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12434                } else {
12435                    try {
12436                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12437                                destIntent.getComponent(), 0, UserHandle.getCallingUserId());
12438                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12439                                null, aInfo, parent.appToken, null,
12440                                0, -1, parent.launchedFromUid, 0, null, true, null);
12441                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12442                    } catch (RemoteException e) {
12443                        foundParentInTask = false;
12444                    }
12445                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12446                            resultData, "navigate-up", true);
12447                }
12448            }
12449            Binder.restoreCallingIdentity(origId);
12450            return foundParentInTask;
12451        }
12452    }
12453
12454    public int getLaunchedFromUid(IBinder activityToken) {
12455        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12456        if (srec == null) {
12457            return -1;
12458        }
12459        return srec.launchedFromUid;
12460    }
12461
12462    // =========================================================
12463    // LIFETIME MANAGEMENT
12464    // =========================================================
12465
12466    // Returns which broadcast queue the app is the current [or imminent] receiver
12467    // on, or 'null' if the app is not an active broadcast recipient.
12468    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12469        BroadcastRecord r = app.curReceiver;
12470        if (r != null) {
12471            return r.queue;
12472        }
12473
12474        // It's not the current receiver, but it might be starting up to become one
12475        synchronized (this) {
12476            for (BroadcastQueue queue : mBroadcastQueues) {
12477                r = queue.mPendingBroadcast;
12478                if (r != null && r.curApp == app) {
12479                    // found it; report which queue it's in
12480                    return queue;
12481                }
12482            }
12483        }
12484
12485        return null;
12486    }
12487
12488    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12489            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12490        if (mAdjSeq == app.adjSeq) {
12491            // This adjustment has already been computed.  If we are calling
12492            // from the top, we may have already computed our adjustment with
12493            // an earlier hidden adjustment that isn't really for us... if
12494            // so, use the new hidden adjustment.
12495            if (!recursed && app.hidden) {
12496                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12497                        app.hasActivities ? hiddenAdj : emptyAdj;
12498            }
12499            return app.curRawAdj;
12500        }
12501
12502        if (app.thread == null) {
12503            app.adjSeq = mAdjSeq;
12504            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12505            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12506        }
12507
12508        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12509        app.adjSource = null;
12510        app.adjTarget = null;
12511        app.empty = false;
12512        app.hidden = false;
12513
12514        final int activitiesSize = app.activities.size();
12515
12516        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12517            // The max adjustment doesn't allow this app to be anything
12518            // below foreground, so it is not worth doing work for it.
12519            app.adjType = "fixed";
12520            app.adjSeq = mAdjSeq;
12521            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12522            app.hasActivities = false;
12523            app.foregroundActivities = false;
12524            app.keeping = true;
12525            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12526            // System process can do UI, and when they do we want to have
12527            // them trim their memory after the user leaves the UI.  To
12528            // facilitate this, here we need to determine whether or not it
12529            // is currently showing UI.
12530            app.systemNoUi = true;
12531            if (app == TOP_APP) {
12532                app.systemNoUi = false;
12533                app.hasActivities = true;
12534            } else if (activitiesSize > 0) {
12535                for (int j = 0; j < activitiesSize; j++) {
12536                    final ActivityRecord r = app.activities.get(j);
12537                    if (r.visible) {
12538                        app.systemNoUi = false;
12539                    }
12540                    if (r.app == app) {
12541                        app.hasActivities = true;
12542                    }
12543                }
12544            }
12545            return (app.curAdj=app.maxAdj);
12546        }
12547
12548        app.keeping = false;
12549        app.systemNoUi = false;
12550        app.hasActivities = false;
12551
12552        // Determine the importance of the process, starting with most
12553        // important to least, and assign an appropriate OOM adjustment.
12554        int adj;
12555        int schedGroup;
12556        boolean foregroundActivities = false;
12557        boolean interesting = false;
12558        BroadcastQueue queue;
12559        if (app == TOP_APP) {
12560            // The last app on the list is the foreground app.
12561            adj = ProcessList.FOREGROUND_APP_ADJ;
12562            schedGroup = Process.THREAD_GROUP_DEFAULT;
12563            app.adjType = "top-activity";
12564            foregroundActivities = true;
12565            interesting = true;
12566            app.hasActivities = true;
12567        } else if (app.instrumentationClass != null) {
12568            // Don't want to kill running instrumentation.
12569            adj = ProcessList.FOREGROUND_APP_ADJ;
12570            schedGroup = Process.THREAD_GROUP_DEFAULT;
12571            app.adjType = "instrumentation";
12572            interesting = true;
12573        } else if ((queue = isReceivingBroadcast(app)) != null) {
12574            // An app that is currently receiving a broadcast also
12575            // counts as being in the foreground for OOM killer purposes.
12576            // It's placed in a sched group based on the nature of the
12577            // broadcast as reflected by which queue it's active in.
12578            adj = ProcessList.FOREGROUND_APP_ADJ;
12579            schedGroup = (queue == mFgBroadcastQueue)
12580                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12581            app.adjType = "broadcast";
12582        } else if (app.executingServices.size() > 0) {
12583            // An app that is currently executing a service callback also
12584            // counts as being in the foreground.
12585            adj = ProcessList.FOREGROUND_APP_ADJ;
12586            schedGroup = Process.THREAD_GROUP_DEFAULT;
12587            app.adjType = "exec-service";
12588        } else {
12589            // Assume process is hidden (has activities); we will correct
12590            // later if this is not the case.
12591            adj = hiddenAdj;
12592            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12593            app.hidden = true;
12594            app.adjType = "bg-activities";
12595        }
12596
12597        boolean hasStoppingActivities = false;
12598
12599        // Examine all activities if not already foreground.
12600        if (!foregroundActivities && activitiesSize > 0) {
12601            for (int j = 0; j < activitiesSize; j++) {
12602                final ActivityRecord r = app.activities.get(j);
12603                if (r.visible) {
12604                    // App has a visible activity; only upgrade adjustment.
12605                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12606                        adj = ProcessList.VISIBLE_APP_ADJ;
12607                        app.adjType = "visible";
12608                    }
12609                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12610                    app.hidden = false;
12611                    app.hasActivities = true;
12612                    foregroundActivities = true;
12613                    break;
12614                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12615                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12616                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12617                        app.adjType = "pausing";
12618                    }
12619                    app.hidden = false;
12620                    foregroundActivities = true;
12621                } else if (r.state == ActivityState.STOPPING) {
12622                    // We will apply the actual adjustment later, because
12623                    // we want to allow this process to immediately go through
12624                    // any memory trimming that is in effect.
12625                    app.hidden = false;
12626                    foregroundActivities = true;
12627                    hasStoppingActivities = true;
12628                }
12629                if (r.app == app) {
12630                    app.hasActivities = true;
12631                }
12632            }
12633        }
12634
12635        if (adj == hiddenAdj && !app.hasActivities) {
12636            // Whoops, this process is completely empty as far as we know
12637            // at this point.
12638            adj = emptyAdj;
12639            app.empty = true;
12640            app.adjType = "bg-empty";
12641        }
12642
12643        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12644            if (app.foregroundServices) {
12645                // The user is aware of this app, so make it visible.
12646                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12647                app.hidden = false;
12648                app.adjType = "foreground-service";
12649                schedGroup = Process.THREAD_GROUP_DEFAULT;
12650            } else if (app.forcingToForeground != null) {
12651                // The user is aware of this app, so make it visible.
12652                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12653                app.hidden = false;
12654                app.adjType = "force-foreground";
12655                app.adjSource = app.forcingToForeground;
12656                schedGroup = Process.THREAD_GROUP_DEFAULT;
12657            }
12658        }
12659
12660        if (app.foregroundServices) {
12661            interesting = true;
12662        }
12663
12664        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12665            // We don't want to kill the current heavy-weight process.
12666            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12667            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12668            app.hidden = false;
12669            app.adjType = "heavy";
12670        }
12671
12672        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12673            // This process is hosting what we currently consider to be the
12674            // home app, so we don't want to let it go into the background.
12675            adj = ProcessList.HOME_APP_ADJ;
12676            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12677            app.hidden = false;
12678            app.adjType = "home";
12679        }
12680
12681        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12682                && app.activities.size() > 0) {
12683            // This was the previous process that showed UI to the user.
12684            // We want to try to keep it around more aggressively, to give
12685            // a good experience around switching between two apps.
12686            adj = ProcessList.PREVIOUS_APP_ADJ;
12687            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12688            app.hidden = false;
12689            app.adjType = "previous";
12690        }
12691
12692        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12693                + " reason=" + app.adjType);
12694
12695        // By default, we use the computed adjustment.  It may be changed if
12696        // there are applications dependent on our services or providers, but
12697        // this gives us a baseline and makes sure we don't get into an
12698        // infinite recursion.
12699        app.adjSeq = mAdjSeq;
12700        app.curRawAdj = app.nonStoppingAdj = adj;
12701
12702        if (mBackupTarget != null && app == mBackupTarget.app) {
12703            // If possible we want to avoid killing apps while they're being backed up
12704            if (adj > ProcessList.BACKUP_APP_ADJ) {
12705                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12706                adj = ProcessList.BACKUP_APP_ADJ;
12707                app.adjType = "backup";
12708                app.hidden = false;
12709            }
12710        }
12711
12712        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12713                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12714            final long now = SystemClock.uptimeMillis();
12715            // This process is more important if the top activity is
12716            // bound to the service.
12717            Iterator<ServiceRecord> jt = app.services.iterator();
12718            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12719                ServiceRecord s = jt.next();
12720                if (s.startRequested) {
12721                    if (app.hasShownUi && app != mHomeProcess) {
12722                        // If this process has shown some UI, let it immediately
12723                        // go to the LRU list because it may be pretty heavy with
12724                        // UI stuff.  We'll tag it with a label just to help
12725                        // debug and understand what is going on.
12726                        if (adj > ProcessList.SERVICE_ADJ) {
12727                            app.adjType = "started-bg-ui-services";
12728                        }
12729                    } else {
12730                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12731                            // This service has seen some activity within
12732                            // recent memory, so we will keep its process ahead
12733                            // of the background processes.
12734                            if (adj > ProcessList.SERVICE_ADJ) {
12735                                adj = ProcessList.SERVICE_ADJ;
12736                                app.adjType = "started-services";
12737                                app.hidden = false;
12738                            }
12739                        }
12740                        // If we have let the service slide into the background
12741                        // state, still have some text describing what it is doing
12742                        // even though the service no longer has an impact.
12743                        if (adj > ProcessList.SERVICE_ADJ) {
12744                            app.adjType = "started-bg-services";
12745                        }
12746                    }
12747                    // Don't kill this process because it is doing work; it
12748                    // has said it is doing work.
12749                    app.keeping = true;
12750                }
12751                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12752                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12753                    Iterator<ArrayList<ConnectionRecord>> kt
12754                            = s.connections.values().iterator();
12755                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12756                        ArrayList<ConnectionRecord> clist = kt.next();
12757                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12758                            // XXX should compute this based on the max of
12759                            // all connected clients.
12760                            ConnectionRecord cr = clist.get(i);
12761                            if (cr.binding.client == app) {
12762                                // Binding to ourself is not interesting.
12763                                continue;
12764                            }
12765                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12766                                ProcessRecord client = cr.binding.client;
12767                                int clientAdj = adj;
12768                                int myHiddenAdj = hiddenAdj;
12769                                if (myHiddenAdj > client.hiddenAdj) {
12770                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12771                                        myHiddenAdj = client.hiddenAdj;
12772                                    } else {
12773                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12774                                    }
12775                                }
12776                                int myEmptyAdj = emptyAdj;
12777                                if (myEmptyAdj > client.emptyAdj) {
12778                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12779                                        myEmptyAdj = client.emptyAdj;
12780                                    } else {
12781                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12782                                    }
12783                                }
12784                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12785                                        myEmptyAdj, TOP_APP, true, doingAll);
12786                                String adjType = null;
12787                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12788                                    // Not doing bind OOM management, so treat
12789                                    // this guy more like a started service.
12790                                    if (app.hasShownUi && app != mHomeProcess) {
12791                                        // If this process has shown some UI, let it immediately
12792                                        // go to the LRU list because it may be pretty heavy with
12793                                        // UI stuff.  We'll tag it with a label just to help
12794                                        // debug and understand what is going on.
12795                                        if (adj > clientAdj) {
12796                                            adjType = "bound-bg-ui-services";
12797                                        }
12798                                        app.hidden = false;
12799                                        clientAdj = adj;
12800                                    } else {
12801                                        if (now >= (s.lastActivity
12802                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12803                                            // This service has not seen activity within
12804                                            // recent memory, so allow it to drop to the
12805                                            // LRU list if there is no other reason to keep
12806                                            // it around.  We'll also tag it with a label just
12807                                            // to help debug and undertand what is going on.
12808                                            if (adj > clientAdj) {
12809                                                adjType = "bound-bg-services";
12810                                            }
12811                                            clientAdj = adj;
12812                                        }
12813                                    }
12814                                }
12815                                if (adj > clientAdj) {
12816                                    // If this process has recently shown UI, and
12817                                    // the process that is binding to it is less
12818                                    // important than being visible, then we don't
12819                                    // care about the binding as much as we care
12820                                    // about letting this process get into the LRU
12821                                    // list to be killed and restarted if needed for
12822                                    // memory.
12823                                    if (app.hasShownUi && app != mHomeProcess
12824                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12825                                        adjType = "bound-bg-ui-services";
12826                                    } else {
12827                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12828                                                |Context.BIND_IMPORTANT)) != 0) {
12829                                            adj = clientAdj;
12830                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12831                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12832                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12833                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12834                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12835                                            adj = clientAdj;
12836                                        } else {
12837                                            app.pendingUiClean = true;
12838                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12839                                                adj = ProcessList.VISIBLE_APP_ADJ;
12840                                            }
12841                                        }
12842                                        if (!client.hidden) {
12843                                            app.hidden = false;
12844                                        }
12845                                        if (client.keeping) {
12846                                            app.keeping = true;
12847                                        }
12848                                        adjType = "service";
12849                                    }
12850                                }
12851                                if (adjType != null) {
12852                                    app.adjType = adjType;
12853                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12854                                            .REASON_SERVICE_IN_USE;
12855                                    app.adjSource = cr.binding.client;
12856                                    app.adjSourceOom = clientAdj;
12857                                    app.adjTarget = s.name;
12858                                }
12859                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12860                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12861                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12862                                    }
12863                                }
12864                            }
12865                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12866                                ActivityRecord a = cr.activity;
12867                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12868                                        (a.visible || a.state == ActivityState.RESUMED
12869                                         || a.state == ActivityState.PAUSING)) {
12870                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12871                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12872                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12873                                    }
12874                                    app.hidden = false;
12875                                    app.adjType = "service";
12876                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12877                                            .REASON_SERVICE_IN_USE;
12878                                    app.adjSource = a;
12879                                    app.adjSourceOom = adj;
12880                                    app.adjTarget = s.name;
12881                                }
12882                            }
12883                        }
12884                    }
12885                }
12886            }
12887
12888            // Finally, if this process has active services running in it, we
12889            // would like to avoid killing it unless it would prevent the current
12890            // application from running.  By default we put the process in
12891            // with the rest of the background processes; as we scan through
12892            // its services we may bump it up from there.
12893            if (adj > hiddenAdj) {
12894                adj = hiddenAdj;
12895                app.hidden = false;
12896                app.adjType = "bg-services";
12897            }
12898        }
12899
12900        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12901                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12902            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12903            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12904                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12905                ContentProviderRecord cpr = jt.next();
12906                for (int i = cpr.connections.size()-1;
12907                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12908                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12909                        i--) {
12910                    ContentProviderConnection conn = cpr.connections.get(i);
12911                    ProcessRecord client = conn.client;
12912                    if (client == app) {
12913                        // Being our own client is not interesting.
12914                        continue;
12915                    }
12916                    int myHiddenAdj = hiddenAdj;
12917                    if (myHiddenAdj > client.hiddenAdj) {
12918                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12919                            myHiddenAdj = client.hiddenAdj;
12920                        } else {
12921                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12922                        }
12923                    }
12924                    int myEmptyAdj = emptyAdj;
12925                    if (myEmptyAdj > client.emptyAdj) {
12926                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12927                            myEmptyAdj = client.emptyAdj;
12928                        } else {
12929                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12930                        }
12931                    }
12932                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12933                            myEmptyAdj, TOP_APP, true, doingAll);
12934                    if (adj > clientAdj) {
12935                        if (app.hasShownUi && app != mHomeProcess
12936                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12937                            app.adjType = "bg-ui-provider";
12938                        } else {
12939                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12940                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12941                            app.adjType = "provider";
12942                        }
12943                        if (!client.hidden) {
12944                            app.hidden = false;
12945                        }
12946                        if (client.keeping) {
12947                            app.keeping = true;
12948                        }
12949                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12950                                .REASON_PROVIDER_IN_USE;
12951                        app.adjSource = client;
12952                        app.adjSourceOom = clientAdj;
12953                        app.adjTarget = cpr.name;
12954                    }
12955                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12956                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12957                    }
12958                }
12959                // If the provider has external (non-framework) process
12960                // dependencies, ensure that its adjustment is at least
12961                // FOREGROUND_APP_ADJ.
12962                if (cpr.hasExternalProcessHandles()) {
12963                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12964                        adj = ProcessList.FOREGROUND_APP_ADJ;
12965                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12966                        app.hidden = false;
12967                        app.keeping = true;
12968                        app.adjType = "provider";
12969                        app.adjTarget = cpr.name;
12970                    }
12971                }
12972            }
12973        }
12974
12975        if (adj == ProcessList.SERVICE_ADJ) {
12976            if (doingAll) {
12977                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12978                mNewNumServiceProcs++;
12979            }
12980            if (app.serviceb) {
12981                adj = ProcessList.SERVICE_B_ADJ;
12982            }
12983        } else {
12984            app.serviceb = false;
12985        }
12986
12987        app.nonStoppingAdj = adj;
12988
12989        if (hasStoppingActivities) {
12990            // Only upgrade adjustment.
12991            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12992                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12993                app.adjType = "stopping";
12994            }
12995        }
12996
12997        app.curRawAdj = adj;
12998
12999        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
13000        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13001        if (adj > app.maxAdj) {
13002            adj = app.maxAdj;
13003            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
13004                schedGroup = Process.THREAD_GROUP_DEFAULT;
13005            }
13006        }
13007        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13008            app.keeping = true;
13009        }
13010
13011        if (app.hasAboveClient) {
13012            // If this process has bound to any services with BIND_ABOVE_CLIENT,
13013            // then we need to drop its adjustment to be lower than the service's
13014            // in order to honor the request.  We want to drop it by one adjustment
13015            // level...  but there is special meaning applied to various levels so
13016            // we will skip some of them.
13017            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
13018                // System process will not get dropped, ever
13019            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13020                adj = ProcessList.VISIBLE_APP_ADJ;
13021            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13022                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13023            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13024                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13025            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
13026                adj++;
13027            }
13028        }
13029
13030        int importance = app.memImportance;
13031        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
13032            app.curAdj = adj;
13033            app.curSchedGroup = schedGroup;
13034            if (!interesting) {
13035                // For this reporting, if there is not something explicitly
13036                // interesting in this process then we will push it to the
13037                // background importance.
13038                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13039            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13040                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13041            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
13042                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13043            } else if (adj >= ProcessList.HOME_APP_ADJ) {
13044                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13045            } else if (adj >= ProcessList.SERVICE_ADJ) {
13046                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13047            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13048                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
13049            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
13050                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
13051            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
13052                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
13053            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
13054                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
13055            } else {
13056                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
13057            }
13058        }
13059
13060        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
13061        if (foregroundActivities != app.foregroundActivities) {
13062            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
13063        }
13064        if (changes != 0) {
13065            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
13066            app.memImportance = importance;
13067            app.foregroundActivities = foregroundActivities;
13068            int i = mPendingProcessChanges.size()-1;
13069            ProcessChangeItem item = null;
13070            while (i >= 0) {
13071                item = mPendingProcessChanges.get(i);
13072                if (item.pid == app.pid) {
13073                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
13074                    break;
13075                }
13076                i--;
13077            }
13078            if (i < 0) {
13079                // No existing item in pending changes; need a new one.
13080                final int NA = mAvailProcessChanges.size();
13081                if (NA > 0) {
13082                    item = mAvailProcessChanges.remove(NA-1);
13083                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
13084                } else {
13085                    item = new ProcessChangeItem();
13086                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
13087                }
13088                item.changes = 0;
13089                item.pid = app.pid;
13090                item.uid = app.info.uid;
13091                if (mPendingProcessChanges.size() == 0) {
13092                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
13093                            "*** Enqueueing dispatch processes changed!");
13094                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
13095                }
13096                mPendingProcessChanges.add(item);
13097            }
13098            item.changes |= changes;
13099            item.importance = importance;
13100            item.foregroundActivities = foregroundActivities;
13101            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
13102                    + Integer.toHexString(System.identityHashCode(item))
13103                    + " " + app.toShortString() + ": changes=" + item.changes
13104                    + " importance=" + item.importance
13105                    + " foreground=" + item.foregroundActivities
13106                    + " type=" + app.adjType + " source=" + app.adjSource
13107                    + " target=" + app.adjTarget);
13108        }
13109
13110        return app.curRawAdj;
13111    }
13112
13113    /**
13114     * Ask a given process to GC right now.
13115     */
13116    final void performAppGcLocked(ProcessRecord app) {
13117        try {
13118            app.lastRequestedGc = SystemClock.uptimeMillis();
13119            if (app.thread != null) {
13120                if (app.reportLowMemory) {
13121                    app.reportLowMemory = false;
13122                    app.thread.scheduleLowMemory();
13123                } else {
13124                    app.thread.processInBackground();
13125                }
13126            }
13127        } catch (Exception e) {
13128            // whatever.
13129        }
13130    }
13131
13132    /**
13133     * Returns true if things are idle enough to perform GCs.
13134     */
13135    private final boolean canGcNowLocked() {
13136        boolean processingBroadcasts = false;
13137        for (BroadcastQueue q : mBroadcastQueues) {
13138            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13139                processingBroadcasts = true;
13140            }
13141        }
13142        return !processingBroadcasts
13143                && (mSleeping || (mMainStack.mResumedActivity != null &&
13144                        mMainStack.mResumedActivity.idle));
13145    }
13146
13147    /**
13148     * Perform GCs on all processes that are waiting for it, but only
13149     * if things are idle.
13150     */
13151    final void performAppGcsLocked() {
13152        final int N = mProcessesToGc.size();
13153        if (N <= 0) {
13154            return;
13155        }
13156        if (canGcNowLocked()) {
13157            while (mProcessesToGc.size() > 0) {
13158                ProcessRecord proc = mProcessesToGc.remove(0);
13159                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13160                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13161                            <= SystemClock.uptimeMillis()) {
13162                        // To avoid spamming the system, we will GC processes one
13163                        // at a time, waiting a few seconds between each.
13164                        performAppGcLocked(proc);
13165                        scheduleAppGcsLocked();
13166                        return;
13167                    } else {
13168                        // It hasn't been long enough since we last GCed this
13169                        // process...  put it in the list to wait for its time.
13170                        addProcessToGcListLocked(proc);
13171                        break;
13172                    }
13173                }
13174            }
13175
13176            scheduleAppGcsLocked();
13177        }
13178    }
13179
13180    /**
13181     * If all looks good, perform GCs on all processes waiting for them.
13182     */
13183    final void performAppGcsIfAppropriateLocked() {
13184        if (canGcNowLocked()) {
13185            performAppGcsLocked();
13186            return;
13187        }
13188        // Still not idle, wait some more.
13189        scheduleAppGcsLocked();
13190    }
13191
13192    /**
13193     * Schedule the execution of all pending app GCs.
13194     */
13195    final void scheduleAppGcsLocked() {
13196        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13197
13198        if (mProcessesToGc.size() > 0) {
13199            // Schedule a GC for the time to the next process.
13200            ProcessRecord proc = mProcessesToGc.get(0);
13201            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13202
13203            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13204            long now = SystemClock.uptimeMillis();
13205            if (when < (now+GC_TIMEOUT)) {
13206                when = now + GC_TIMEOUT;
13207            }
13208            mHandler.sendMessageAtTime(msg, when);
13209        }
13210    }
13211
13212    /**
13213     * Add a process to the array of processes waiting to be GCed.  Keeps the
13214     * list in sorted order by the last GC time.  The process can't already be
13215     * on the list.
13216     */
13217    final void addProcessToGcListLocked(ProcessRecord proc) {
13218        boolean added = false;
13219        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13220            if (mProcessesToGc.get(i).lastRequestedGc <
13221                    proc.lastRequestedGc) {
13222                added = true;
13223                mProcessesToGc.add(i+1, proc);
13224                break;
13225            }
13226        }
13227        if (!added) {
13228            mProcessesToGc.add(0, proc);
13229        }
13230    }
13231
13232    /**
13233     * Set up to ask a process to GC itself.  This will either do it
13234     * immediately, or put it on the list of processes to gc the next
13235     * time things are idle.
13236     */
13237    final void scheduleAppGcLocked(ProcessRecord app) {
13238        long now = SystemClock.uptimeMillis();
13239        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13240            return;
13241        }
13242        if (!mProcessesToGc.contains(app)) {
13243            addProcessToGcListLocked(app);
13244            scheduleAppGcsLocked();
13245        }
13246    }
13247
13248    final void checkExcessivePowerUsageLocked(boolean doKills) {
13249        updateCpuStatsNow();
13250
13251        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13252        boolean doWakeKills = doKills;
13253        boolean doCpuKills = doKills;
13254        if (mLastPowerCheckRealtime == 0) {
13255            doWakeKills = false;
13256        }
13257        if (mLastPowerCheckUptime == 0) {
13258            doCpuKills = false;
13259        }
13260        if (stats.isScreenOn()) {
13261            doWakeKills = false;
13262        }
13263        final long curRealtime = SystemClock.elapsedRealtime();
13264        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13265        final long curUptime = SystemClock.uptimeMillis();
13266        final long uptimeSince = curUptime - mLastPowerCheckUptime;
13267        mLastPowerCheckRealtime = curRealtime;
13268        mLastPowerCheckUptime = curUptime;
13269        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13270            doWakeKills = false;
13271        }
13272        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13273            doCpuKills = false;
13274        }
13275        int i = mLruProcesses.size();
13276        while (i > 0) {
13277            i--;
13278            ProcessRecord app = mLruProcesses.get(i);
13279            if (!app.keeping) {
13280                long wtime;
13281                synchronized (stats) {
13282                    wtime = stats.getProcessWakeTime(app.info.uid,
13283                            app.pid, curRealtime);
13284                }
13285                long wtimeUsed = wtime - app.lastWakeTime;
13286                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13287                if (DEBUG_POWER) {
13288                    StringBuilder sb = new StringBuilder(128);
13289                    sb.append("Wake for ");
13290                    app.toShortString(sb);
13291                    sb.append(": over ");
13292                    TimeUtils.formatDuration(realtimeSince, sb);
13293                    sb.append(" used ");
13294                    TimeUtils.formatDuration(wtimeUsed, sb);
13295                    sb.append(" (");
13296                    sb.append((wtimeUsed*100)/realtimeSince);
13297                    sb.append("%)");
13298                    Slog.i(TAG, sb.toString());
13299                    sb.setLength(0);
13300                    sb.append("CPU for ");
13301                    app.toShortString(sb);
13302                    sb.append(": over ");
13303                    TimeUtils.formatDuration(uptimeSince, sb);
13304                    sb.append(" used ");
13305                    TimeUtils.formatDuration(cputimeUsed, sb);
13306                    sb.append(" (");
13307                    sb.append((cputimeUsed*100)/uptimeSince);
13308                    sb.append("%)");
13309                    Slog.i(TAG, sb.toString());
13310                }
13311                // If a process has held a wake lock for more
13312                // than 50% of the time during this period,
13313                // that sounds bad.  Kill!
13314                if (doWakeKills && realtimeSince > 0
13315                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13316                    synchronized (stats) {
13317                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13318                                realtimeSince, wtimeUsed);
13319                    }
13320                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13321                            + " (pid " + app.pid + "): held " + wtimeUsed
13322                            + " during " + realtimeSince);
13323                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13324                            app.processName, app.setAdj, "excessive wake lock");
13325                    Process.killProcessQuiet(app.pid);
13326                } else if (doCpuKills && uptimeSince > 0
13327                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13328                    synchronized (stats) {
13329                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13330                                uptimeSince, cputimeUsed);
13331                    }
13332                    Slog.w(TAG, "Excessive CPU in " + app.processName
13333                            + " (pid " + app.pid + "): used " + cputimeUsed
13334                            + " during " + uptimeSince);
13335                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13336                            app.processName, app.setAdj, "excessive cpu");
13337                    Process.killProcessQuiet(app.pid);
13338                } else {
13339                    app.lastWakeTime = wtime;
13340                    app.lastCpuTime = app.curCpuTime;
13341                }
13342            }
13343        }
13344    }
13345
13346    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13347            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13348        app.hiddenAdj = hiddenAdj;
13349        app.emptyAdj = emptyAdj;
13350
13351        if (app.thread == null) {
13352            return false;
13353        }
13354
13355        final boolean wasKeeping = app.keeping;
13356
13357        boolean success = true;
13358
13359        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13360
13361        if (app.curRawAdj != app.setRawAdj) {
13362            if (wasKeeping && !app.keeping) {
13363                // This app is no longer something we want to keep.  Note
13364                // its current wake lock time to later know to kill it if
13365                // it is not behaving well.
13366                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13367                synchronized (stats) {
13368                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13369                            app.pid, SystemClock.elapsedRealtime());
13370                }
13371                app.lastCpuTime = app.curCpuTime;
13372            }
13373
13374            app.setRawAdj = app.curRawAdj;
13375        }
13376
13377        if (app.curAdj != app.setAdj) {
13378            if (Process.setOomAdj(app.pid, app.curAdj)) {
13379                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13380                    TAG, "Set " + app.pid + " " + app.processName +
13381                    " adj " + app.curAdj + ": " + app.adjType);
13382                app.setAdj = app.curAdj;
13383            } else {
13384                success = false;
13385                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13386            }
13387        }
13388        if (app.setSchedGroup != app.curSchedGroup) {
13389            app.setSchedGroup = app.curSchedGroup;
13390            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13391                    "Setting process group of " + app.processName
13392                    + " to " + app.curSchedGroup);
13393            if (app.waitingToKill != null &&
13394                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13395                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13396                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13397                        app.processName, app.setAdj, app.waitingToKill);
13398                app.killedBackground = true;
13399                Process.killProcessQuiet(app.pid);
13400                success = false;
13401            } else {
13402                if (true) {
13403                    long oldId = Binder.clearCallingIdentity();
13404                    try {
13405                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13406                    } catch (Exception e) {
13407                        Slog.w(TAG, "Failed setting process group of " + app.pid
13408                                + " to " + app.curSchedGroup);
13409                        e.printStackTrace();
13410                    } finally {
13411                        Binder.restoreCallingIdentity(oldId);
13412                    }
13413                } else {
13414                    if (app.thread != null) {
13415                        try {
13416                            app.thread.setSchedulingGroup(app.curSchedGroup);
13417                        } catch (RemoteException e) {
13418                        }
13419                    }
13420                }
13421            }
13422        }
13423        return success;
13424    }
13425
13426    private final ActivityRecord resumedAppLocked() {
13427        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13428        if (resumedActivity == null || resumedActivity.app == null) {
13429            resumedActivity = mMainStack.mPausingActivity;
13430            if (resumedActivity == null || resumedActivity.app == null) {
13431                resumedActivity = mMainStack.topRunningActivityLocked(null);
13432            }
13433        }
13434        return resumedActivity;
13435    }
13436
13437    final boolean updateOomAdjLocked(ProcessRecord app) {
13438        final ActivityRecord TOP_ACT = resumedAppLocked();
13439        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13440        int curAdj = app.curAdj;
13441        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13442            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13443
13444        mAdjSeq++;
13445
13446        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
13447                TOP_APP, false);
13448        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13449            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13450        if (nowHidden != wasHidden) {
13451            // Changed to/from hidden state, so apps after it in the LRU
13452            // list may also be changed.
13453            updateOomAdjLocked();
13454        }
13455        return success;
13456    }
13457
13458    final void updateOomAdjLocked() {
13459        final ActivityRecord TOP_ACT = resumedAppLocked();
13460        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13461
13462        if (false) {
13463            RuntimeException e = new RuntimeException();
13464            e.fillInStackTrace();
13465            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13466        }
13467
13468        mAdjSeq++;
13469        mNewNumServiceProcs = 0;
13470
13471        // Let's determine how many processes we have running vs.
13472        // how many slots we have for background processes; we may want
13473        // to put multiple processes in a slot of there are enough of
13474        // them.
13475        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13476                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13477        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
13478        if (emptyFactor < 1) emptyFactor = 1;
13479        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13480        if (hiddenFactor < 1) hiddenFactor = 1;
13481        int stepHidden = 0;
13482        int stepEmpty = 0;
13483        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13484        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13485        int numHidden = 0;
13486        int numEmpty = 0;
13487        int numTrimming = 0;
13488
13489        mNumNonHiddenProcs = 0;
13490        mNumHiddenProcs = 0;
13491
13492        // First update the OOM adjustment for each of the
13493        // application processes based on their current state.
13494        int i = mLruProcesses.size();
13495        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13496        int nextHiddenAdj = curHiddenAdj+1;
13497        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13498        int nextEmptyAdj = curEmptyAdj+2;
13499        while (i > 0) {
13500            i--;
13501            ProcessRecord app = mLruProcesses.get(i);
13502            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13503            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
13504            if (!app.killedBackground) {
13505                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13506                    // This process was assigned as a hidden process...  step the
13507                    // hidden level.
13508                    mNumHiddenProcs++;
13509                    if (curHiddenAdj != nextHiddenAdj) {
13510                        stepHidden++;
13511                        if (stepHidden >= hiddenFactor) {
13512                            stepHidden = 0;
13513                            curHiddenAdj = nextHiddenAdj;
13514                            nextHiddenAdj += 2;
13515                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13516                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13517                            }
13518                        }
13519                    }
13520                    numHidden++;
13521                    if (numHidden > hiddenProcessLimit) {
13522                        Slog.i(TAG, "No longer want " + app.processName
13523                                + " (pid " + app.pid + "): hidden #" + numHidden);
13524                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13525                                app.processName, app.setAdj, "too many background");
13526                        app.killedBackground = true;
13527                        Process.killProcessQuiet(app.pid);
13528                    }
13529                } else {
13530                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13531                        // This process was assigned as an empty process...  step the
13532                        // empty level.
13533                        if (curEmptyAdj != nextEmptyAdj) {
13534                            stepEmpty++;
13535                            if (stepEmpty >= emptyFactor) {
13536                                stepEmpty = 0;
13537                                curEmptyAdj = nextEmptyAdj;
13538                                nextEmptyAdj += 2;
13539                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13540                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13541                                }
13542                            }
13543                        }
13544                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13545                        mNumNonHiddenProcs++;
13546                    }
13547                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13548                        numEmpty++;
13549                        if (numEmpty > emptyProcessLimit) {
13550                            Slog.i(TAG, "No longer want " + app.processName
13551                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13552                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13553                                    app.processName, app.setAdj, "too many background");
13554                            app.killedBackground = true;
13555                            Process.killProcessQuiet(app.pid);
13556                        }
13557                    }
13558                }
13559                if (app.isolated && app.services.size() <= 0) {
13560                    // If this is an isolated process, and there are no
13561                    // services running in it, then the process is no longer
13562                    // needed.  We agressively kill these because we can by
13563                    // definition not re-use the same process again, and it is
13564                    // good to avoid having whatever code was running in them
13565                    // left sitting around after no longer needed.
13566                    Slog.i(TAG, "Isolated process " + app.processName
13567                            + " (pid " + app.pid + ") no longer needed");
13568                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13569                            app.processName, app.setAdj, "isolated not needed");
13570                    app.killedBackground = true;
13571                    Process.killProcessQuiet(app.pid);
13572                }
13573                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13574                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13575                        && !app.killedBackground) {
13576                    numTrimming++;
13577                }
13578            }
13579        }
13580
13581        mNumServiceProcs = mNewNumServiceProcs;
13582
13583        // Now determine the memory trimming level of background processes.
13584        // Unfortunately we need to start at the back of the list to do this
13585        // properly.  We only do this if the number of background apps we
13586        // are managing to keep around is less than half the maximum we desire;
13587        // if we are keeping a good number around, we'll let them use whatever
13588        // memory they want.
13589        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13590                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13591            final int numHiddenAndEmpty = numHidden + numEmpty;
13592            final int N = mLruProcesses.size();
13593            int factor = numTrimming/3;
13594            int minFactor = 2;
13595            if (mHomeProcess != null) minFactor++;
13596            if (mPreviousProcess != null) minFactor++;
13597            if (factor < minFactor) factor = minFactor;
13598            int step = 0;
13599            int fgTrimLevel;
13600            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13601                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13602            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13603                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13604            } else {
13605                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13606            }
13607            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13608            for (i=0; i<N; i++) {
13609                ProcessRecord app = mLruProcesses.get(i);
13610                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13611                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13612                        && !app.killedBackground) {
13613                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13614                        try {
13615                            app.thread.scheduleTrimMemory(curLevel);
13616                        } catch (RemoteException e) {
13617                        }
13618                        if (false) {
13619                            // For now we won't do this; our memory trimming seems
13620                            // to be good enough at this point that destroying
13621                            // activities causes more harm than good.
13622                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13623                                    && app != mHomeProcess && app != mPreviousProcess) {
13624                                // Need to do this on its own message because the stack may not
13625                                // be in a consistent state at this point.
13626                                // For these apps we will also finish their activities
13627                                // to help them free memory.
13628                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13629                            }
13630                        }
13631                    }
13632                    app.trimMemoryLevel = curLevel;
13633                    step++;
13634                    if (step >= factor) {
13635                        step = 0;
13636                        switch (curLevel) {
13637                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13638                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13639                                break;
13640                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13641                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13642                                break;
13643                        }
13644                    }
13645                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13646                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13647                            && app.thread != null) {
13648                        try {
13649                            app.thread.scheduleTrimMemory(
13650                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13651                        } catch (RemoteException e) {
13652                        }
13653                    }
13654                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13655                } else {
13656                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13657                            && app.pendingUiClean) {
13658                        // If this application is now in the background and it
13659                        // had done UI, then give it the special trim level to
13660                        // have it free UI resources.
13661                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13662                        if (app.trimMemoryLevel < level && app.thread != null) {
13663                            try {
13664                                app.thread.scheduleTrimMemory(level);
13665                            } catch (RemoteException e) {
13666                            }
13667                        }
13668                        app.pendingUiClean = false;
13669                    }
13670                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13671                        try {
13672                            app.thread.scheduleTrimMemory(fgTrimLevel);
13673                        } catch (RemoteException e) {
13674                        }
13675                    }
13676                    app.trimMemoryLevel = fgTrimLevel;
13677                }
13678            }
13679        } else {
13680            final int N = mLruProcesses.size();
13681            for (i=0; i<N; i++) {
13682                ProcessRecord app = mLruProcesses.get(i);
13683                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13684                        && app.pendingUiClean) {
13685                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13686                            && app.thread != null) {
13687                        try {
13688                            app.thread.scheduleTrimMemory(
13689                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13690                        } catch (RemoteException e) {
13691                        }
13692                    }
13693                    app.pendingUiClean = false;
13694                }
13695                app.trimMemoryLevel = 0;
13696            }
13697        }
13698
13699        if (mAlwaysFinishActivities) {
13700            // Need to do this on its own message because the stack may not
13701            // be in a consistent state at this point.
13702            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13703        }
13704    }
13705
13706    final void trimApplications() {
13707        synchronized (this) {
13708            int i;
13709
13710            // First remove any unused application processes whose package
13711            // has been removed.
13712            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13713                final ProcessRecord app = mRemovedProcesses.get(i);
13714                if (app.activities.size() == 0
13715                        && app.curReceiver == null && app.services.size() == 0) {
13716                    Slog.i(
13717                        TAG, "Exiting empty application process "
13718                        + app.processName + " ("
13719                        + (app.thread != null ? app.thread.asBinder() : null)
13720                        + ")\n");
13721                    if (app.pid > 0 && app.pid != MY_PID) {
13722                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13723                                app.processName, app.setAdj, "empty");
13724                        Process.killProcessQuiet(app.pid);
13725                    } else {
13726                        try {
13727                            app.thread.scheduleExit();
13728                        } catch (Exception e) {
13729                            // Ignore exceptions.
13730                        }
13731                    }
13732                    cleanUpApplicationRecordLocked(app, false, true, -1);
13733                    mRemovedProcesses.remove(i);
13734
13735                    if (app.persistent) {
13736                        if (app.persistent) {
13737                            addAppLocked(app.info, false);
13738                        }
13739                    }
13740                }
13741            }
13742
13743            // Now update the oom adj for all processes.
13744            updateOomAdjLocked();
13745        }
13746    }
13747
13748    /** This method sends the specified signal to each of the persistent apps */
13749    public void signalPersistentProcesses(int sig) throws RemoteException {
13750        if (sig != Process.SIGNAL_USR1) {
13751            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13752        }
13753
13754        synchronized (this) {
13755            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13756                    != PackageManager.PERMISSION_GRANTED) {
13757                throw new SecurityException("Requires permission "
13758                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13759            }
13760
13761            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13762                ProcessRecord r = mLruProcesses.get(i);
13763                if (r.thread != null && r.persistent) {
13764                    Process.sendSignal(r.pid, sig);
13765                }
13766            }
13767        }
13768    }
13769
13770    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13771        if (proc == null || proc == mProfileProc) {
13772            proc = mProfileProc;
13773            path = mProfileFile;
13774            profileType = mProfileType;
13775            clearProfilerLocked();
13776        }
13777        if (proc == null) {
13778            return;
13779        }
13780        try {
13781            proc.thread.profilerControl(false, path, null, profileType);
13782        } catch (RemoteException e) {
13783            throw new IllegalStateException("Process disappeared");
13784        }
13785    }
13786
13787    private void clearProfilerLocked() {
13788        if (mProfileFd != null) {
13789            try {
13790                mProfileFd.close();
13791            } catch (IOException e) {
13792            }
13793        }
13794        mProfileApp = null;
13795        mProfileProc = null;
13796        mProfileFile = null;
13797        mProfileType = 0;
13798        mAutoStopProfiler = false;
13799    }
13800
13801    public boolean profileControl(String process, int userId, boolean start,
13802            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13803
13804        try {
13805            synchronized (this) {
13806                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13807                // its own permission.
13808                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13809                        != PackageManager.PERMISSION_GRANTED) {
13810                    throw new SecurityException("Requires permission "
13811                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13812                }
13813
13814                if (start && fd == null) {
13815                    throw new IllegalArgumentException("null fd");
13816                }
13817
13818                ProcessRecord proc = null;
13819                if (process != null) {
13820                    proc = findProcessLocked(process, userId, "profileControl");
13821                }
13822
13823                if (start && (proc == null || proc.thread == null)) {
13824                    throw new IllegalArgumentException("Unknown process: " + process);
13825                }
13826
13827                if (start) {
13828                    stopProfilerLocked(null, null, 0);
13829                    setProfileApp(proc.info, proc.processName, path, fd, false);
13830                    mProfileProc = proc;
13831                    mProfileType = profileType;
13832                    try {
13833                        fd = fd.dup();
13834                    } catch (IOException e) {
13835                        fd = null;
13836                    }
13837                    proc.thread.profilerControl(start, path, fd, profileType);
13838                    fd = null;
13839                    mProfileFd = null;
13840                } else {
13841                    stopProfilerLocked(proc, path, profileType);
13842                    if (fd != null) {
13843                        try {
13844                            fd.close();
13845                        } catch (IOException e) {
13846                        }
13847                    }
13848                }
13849
13850                return true;
13851            }
13852        } catch (RemoteException e) {
13853            throw new IllegalStateException("Process disappeared");
13854        } finally {
13855            if (fd != null) {
13856                try {
13857                    fd.close();
13858                } catch (IOException e) {
13859                }
13860            }
13861        }
13862    }
13863
13864    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
13865        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
13866                userId, true, true, callName, null);
13867        ProcessRecord proc = null;
13868        try {
13869            int pid = Integer.parseInt(process);
13870            synchronized (mPidsSelfLocked) {
13871                proc = mPidsSelfLocked.get(pid);
13872            }
13873        } catch (NumberFormatException e) {
13874        }
13875
13876        if (proc == null) {
13877            HashMap<String, SparseArray<ProcessRecord>> all
13878                    = mProcessNames.getMap();
13879            SparseArray<ProcessRecord> procs = all.get(process);
13880            if (procs != null && procs.size() > 0) {
13881                proc = procs.valueAt(0);
13882                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
13883                    for (int i=1; i<procs.size(); i++) {
13884                        ProcessRecord thisProc = procs.valueAt(i);
13885                        if (thisProc.userId == userId) {
13886                            proc = thisProc;
13887                            break;
13888                        }
13889                    }
13890                }
13891            }
13892        }
13893
13894        return proc;
13895    }
13896
13897    public boolean dumpHeap(String process, int userId, boolean managed,
13898            String path, ParcelFileDescriptor fd) throws RemoteException {
13899
13900        try {
13901            synchronized (this) {
13902                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13903                // its own permission (same as profileControl).
13904                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13905                        != PackageManager.PERMISSION_GRANTED) {
13906                    throw new SecurityException("Requires permission "
13907                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13908                }
13909
13910                if (fd == null) {
13911                    throw new IllegalArgumentException("null fd");
13912                }
13913
13914                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
13915                if (proc == null || proc.thread == null) {
13916                    throw new IllegalArgumentException("Unknown process: " + process);
13917                }
13918
13919                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13920                if (!isDebuggable) {
13921                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13922                        throw new SecurityException("Process not debuggable: " + proc);
13923                    }
13924                }
13925
13926                proc.thread.dumpHeap(managed, path, fd);
13927                fd = null;
13928                return true;
13929            }
13930        } catch (RemoteException e) {
13931            throw new IllegalStateException("Process disappeared");
13932        } finally {
13933            if (fd != null) {
13934                try {
13935                    fd.close();
13936                } catch (IOException e) {
13937                }
13938            }
13939        }
13940    }
13941
13942    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13943    public void monitor() {
13944        synchronized (this) { }
13945    }
13946
13947    void onCoreSettingsChange(Bundle settings) {
13948        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13949            ProcessRecord processRecord = mLruProcesses.get(i);
13950            try {
13951                if (processRecord.thread != null) {
13952                    processRecord.thread.setCoreSettings(settings);
13953                }
13954            } catch (RemoteException re) {
13955                /* ignore */
13956            }
13957        }
13958    }
13959
13960    // Multi-user methods
13961
13962    @Override
13963    public boolean switchUser(int userId) {
13964        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13965                != PackageManager.PERMISSION_GRANTED) {
13966            String msg = "Permission Denial: switchUser() from pid="
13967                    + Binder.getCallingPid()
13968                    + ", uid=" + Binder.getCallingUid()
13969                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13970            Slog.w(TAG, msg);
13971            throw new SecurityException(msg);
13972        }
13973
13974        final long ident = Binder.clearCallingIdentity();
13975        try {
13976            synchronized (this) {
13977                final int oldUserId = mCurrentUserId;
13978                if (oldUserId == userId) {
13979                    return true;
13980                }
13981
13982                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
13983                if (userInfo == null) {
13984                    Slog.w(TAG, "No user info for user #" + userId);
13985                    return false;
13986                }
13987
13988                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
13989                        R.anim.screen_user_enter);
13990
13991                // If the user we are switching to is not currently started, then
13992                // we need to start it now.
13993                if (mStartedUsers.get(userId) == null) {
13994                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
13995                    updateStartedUserArrayLocked();
13996                }
13997
13998                mCurrentUserId = userId;
13999                mCurrentUserArray = new int[] { userId };
14000                final Integer userIdInt = Integer.valueOf(userId);
14001                mUserLru.remove(userIdInt);
14002                mUserLru.add(userIdInt);
14003
14004                mWindowManager.setCurrentUser(userId);
14005
14006                final UserStartedState uss = mStartedUsers.get(userId);
14007
14008                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
14009                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14010                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
14011                        oldUserId, userId, uss));
14012                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
14013                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
14014                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14015                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14016                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14017                broadcastIntentLocked(null, null, intent,
14018                        null, null, 0, null, null, null,
14019                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14020
14021                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
14022                    if (userId != 0) {
14023                        intent = new Intent(Intent.ACTION_USER_INITIALIZE);
14024                        broadcastIntentLocked(null, null, intent, null,
14025                                new IIntentReceiver.Stub() {
14026                                    public void performReceive(Intent intent, int resultCode,
14027                                            String data, Bundle extras, boolean ordered,
14028                                            boolean sticky, int sendingUser) {
14029                                        synchronized (ActivityManagerService.this) {
14030                                            getUserManagerLocked().makeInitialized(userInfo.id);
14031                                        }
14032                                    }
14033                                }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
14034                                userId);
14035                    } else {
14036                        getUserManagerLocked().makeInitialized(userInfo.id);
14037                    }
14038                }
14039
14040                boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
14041                if (!haveActivities) {
14042                    startHomeActivityLocked(userId);
14043                }
14044
14045                getUserManagerLocked().userForeground(userId);
14046                sendUserSwitchBroadcastsLocked(oldUserId, userId);
14047            }
14048        } finally {
14049            Binder.restoreCallingIdentity(ident);
14050        }
14051
14052        return true;
14053    }
14054
14055    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
14056        long ident = Binder.clearCallingIdentity();
14057        try {
14058            Intent intent;
14059            if (oldUserId >= 0) {
14060                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
14061                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14062                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
14063                broadcastIntentLocked(null, null, intent,
14064                        null, null, 0, null, null, null,
14065                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
14066            }
14067            if (newUserId >= 0) {
14068                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
14069                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14070                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14071                broadcastIntentLocked(null, null, intent,
14072                        null, null, 0, null, null, null,
14073                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
14074                intent = new Intent(Intent.ACTION_USER_SWITCHED);
14075                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14076                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14077                broadcastIntentLocked(null, null, intent,
14078                        null, null, 0, null, null,
14079                        android.Manifest.permission.MANAGE_USERS,
14080                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14081            }
14082        } finally {
14083            Binder.restoreCallingIdentity(ident);
14084        }
14085    }
14086
14087    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
14088            final int newUserId) {
14089        final int N = mUserSwitchObservers.beginBroadcast();
14090        if (N > 0) {
14091            final IRemoteCallback callback = new IRemoteCallback.Stub() {
14092                int mCount = 0;
14093                @Override
14094                public void sendResult(Bundle data) throws RemoteException {
14095                    synchronized (ActivityManagerService.this) {
14096                        if (mCurUserSwitchCallback == this) {
14097                            mCount++;
14098                            if (mCount == N) {
14099                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14100                            }
14101                        }
14102                    }
14103                }
14104            };
14105            synchronized (this) {
14106                mCurUserSwitchCallback = callback;
14107            }
14108            for (int i=0; i<N; i++) {
14109                try {
14110                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
14111                            newUserId, callback);
14112                } catch (RemoteException e) {
14113                }
14114            }
14115        } else {
14116            synchronized (this) {
14117                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14118            }
14119        }
14120        mUserSwitchObservers.finishBroadcast();
14121    }
14122
14123    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14124        synchronized (this) {
14125            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
14126            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14127        }
14128    }
14129
14130    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
14131        mCurUserSwitchCallback = null;
14132        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14133        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
14134                oldUserId, newUserId, uss));
14135    }
14136
14137    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14138        final int N = mUserSwitchObservers.beginBroadcast();
14139        for (int i=0; i<N; i++) {
14140            try {
14141                mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
14142            } catch (RemoteException e) {
14143            }
14144        }
14145        mUserSwitchObservers.finishBroadcast();
14146        synchronized (this) {
14147            mWindowManager.stopFreezingScreen();
14148        }
14149    }
14150
14151    void finishUserSwitch(UserStartedState uss) {
14152        synchronized (this) {
14153            if (uss.mState == UserStartedState.STATE_BOOTING
14154                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
14155                uss.mState = UserStartedState.STATE_RUNNING;
14156                final int userId = uss.mHandle.getIdentifier();
14157                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
14158                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14159                broadcastIntentLocked(null, null, intent,
14160                        null, null, 0, null, null,
14161                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
14162                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14163            }
14164            int num = mUserLru.size();
14165            int i = 0;
14166            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
14167                Integer oldUserId = mUserLru.get(i);
14168                UserStartedState oldUss = mStartedUsers.get(oldUserId);
14169                if (oldUss == null) {
14170                    // Shouldn't happen, but be sane if it does.
14171                    mUserLru.remove(i);
14172                    num--;
14173                    continue;
14174                }
14175                if (oldUss.mState == UserStartedState.STATE_STOPPING) {
14176                    // This user is already stopping, doesn't count.
14177                    num--;
14178                    i++;
14179                    continue;
14180                }
14181                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
14182                    // Owner and current can't be stopped, but count as running.
14183                    i++;
14184                    continue;
14185                }
14186                // This is a user to be stopped.
14187                stopUserLocked(oldUserId, null);
14188                num--;
14189                i++;
14190            }
14191        }
14192    }
14193
14194    @Override
14195    public int stopUser(final int userId, final IStopUserCallback callback) {
14196        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14197                != PackageManager.PERMISSION_GRANTED) {
14198            String msg = "Permission Denial: switchUser() from pid="
14199                    + Binder.getCallingPid()
14200                    + ", uid=" + Binder.getCallingUid()
14201                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14202            Slog.w(TAG, msg);
14203            throw new SecurityException(msg);
14204        }
14205        if (userId <= 0) {
14206            throw new IllegalArgumentException("Can't stop primary user " + userId);
14207        }
14208        synchronized (this) {
14209            return stopUserLocked(userId, callback);
14210        }
14211    }
14212
14213    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
14214        if (mCurrentUserId == userId) {
14215            return ActivityManager.USER_OP_IS_CURRENT;
14216        }
14217
14218        final UserStartedState uss = mStartedUsers.get(userId);
14219        if (uss == null) {
14220            // User is not started, nothing to do...  but we do need to
14221            // callback if requested.
14222            if (callback != null) {
14223                mHandler.post(new Runnable() {
14224                    @Override
14225                    public void run() {
14226                        try {
14227                            callback.userStopped(userId);
14228                        } catch (RemoteException e) {
14229                        }
14230                    }
14231                });
14232            }
14233            return ActivityManager.USER_OP_SUCCESS;
14234        }
14235
14236        if (callback != null) {
14237            uss.mStopCallbacks.add(callback);
14238        }
14239
14240        if (uss.mState != UserStartedState.STATE_STOPPING) {
14241            uss.mState = UserStartedState.STATE_STOPPING;
14242
14243            long ident = Binder.clearCallingIdentity();
14244            try {
14245                // Inform of user switch
14246                Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14247                final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() {
14248                    @Override
14249                    public void performReceive(Intent intent, int resultCode, String data,
14250                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14251                        finishUserStop(uss);
14252                    }
14253                };
14254                broadcastIntentLocked(null, null, intent,
14255                        null, resultReceiver, 0, null, null, null,
14256                        true, false, MY_PID, Process.SYSTEM_UID, userId);
14257            } finally {
14258                Binder.restoreCallingIdentity(ident);
14259            }
14260        }
14261
14262        return ActivityManager.USER_OP_SUCCESS;
14263    }
14264
14265    void finishUserStop(UserStartedState uss) {
14266        final int userId = uss.mHandle.getIdentifier();
14267        boolean stopped;
14268        ArrayList<IStopUserCallback> callbacks;
14269        synchronized (this) {
14270            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
14271            if (uss.mState != UserStartedState.STATE_STOPPING
14272                    || mStartedUsers.get(userId) != uss) {
14273                stopped = false;
14274            } else {
14275                stopped = true;
14276                // User can no longer run.
14277                mStartedUsers.remove(userId);
14278                mUserLru.remove(Integer.valueOf(userId));
14279                updateStartedUserArrayLocked();
14280
14281                // Clean up all state and processes associated with the user.
14282                // Kill all the processes for the user.
14283                forceStopUserLocked(userId);
14284            }
14285        }
14286
14287        for (int i=0; i<callbacks.size(); i++) {
14288            try {
14289                if (stopped) callbacks.get(i).userStopped(userId);
14290                else callbacks.get(i).userStopAborted(userId);
14291            } catch (RemoteException e) {
14292            }
14293        }
14294    }
14295
14296    @Override
14297    public UserInfo getCurrentUser() {
14298        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14299                != PackageManager.PERMISSION_GRANTED) && (
14300                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14301                != PackageManager.PERMISSION_GRANTED)) {
14302            String msg = "Permission Denial: getCurrentUser() from pid="
14303                    + Binder.getCallingPid()
14304                    + ", uid=" + Binder.getCallingUid()
14305                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14306            Slog.w(TAG, msg);
14307            throw new SecurityException(msg);
14308        }
14309        synchronized (this) {
14310            return getUserManagerLocked().getUserInfo(mCurrentUserId);
14311        }
14312    }
14313
14314    int getCurrentUserIdLocked() {
14315        return mCurrentUserId;
14316    }
14317
14318    @Override
14319    public boolean isUserRunning(int userId) {
14320        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14321                != PackageManager.PERMISSION_GRANTED) {
14322            String msg = "Permission Denial: isUserRunning() from pid="
14323                    + Binder.getCallingPid()
14324                    + ", uid=" + Binder.getCallingUid()
14325                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14326            Slog.w(TAG, msg);
14327            throw new SecurityException(msg);
14328        }
14329        synchronized (this) {
14330            return isUserRunningLocked(userId);
14331        }
14332    }
14333
14334    boolean isUserRunningLocked(int userId) {
14335        UserStartedState state = mStartedUsers.get(userId);
14336        return state != null && state.mState != UserStartedState.STATE_STOPPING;
14337    }
14338
14339    @Override
14340    public int[] getRunningUserIds() {
14341        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14342                != PackageManager.PERMISSION_GRANTED) {
14343            String msg = "Permission Denial: isUserRunning() from pid="
14344                    + Binder.getCallingPid()
14345                    + ", uid=" + Binder.getCallingUid()
14346                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14347            Slog.w(TAG, msg);
14348            throw new SecurityException(msg);
14349        }
14350        synchronized (this) {
14351            return mStartedUserArray;
14352        }
14353    }
14354
14355    private void updateStartedUserArrayLocked() {
14356        mStartedUserArray = new int[mStartedUsers.size()];
14357        for (int i=0; i<mStartedUsers.size();  i++) {
14358            mStartedUserArray[i] = mStartedUsers.keyAt(i);
14359        }
14360    }
14361
14362    @Override
14363    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
14364        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14365                != PackageManager.PERMISSION_GRANTED) {
14366            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
14367                    + Binder.getCallingPid()
14368                    + ", uid=" + Binder.getCallingUid()
14369                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14370            Slog.w(TAG, msg);
14371            throw new SecurityException(msg);
14372        }
14373
14374        mUserSwitchObservers.register(observer);
14375    }
14376
14377    @Override
14378    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
14379        mUserSwitchObservers.unregister(observer);
14380    }
14381
14382    private boolean userExists(int userId) {
14383        if (userId == 0) {
14384            return true;
14385        }
14386        UserManagerService ums = getUserManagerLocked();
14387        return ums != null ? (ums.getUserInfo(userId) != null) : false;
14388    }
14389
14390    int[] getUsersLocked() {
14391        UserManagerService ums = getUserManagerLocked();
14392        return ums != null ? ums.getUserIds() : new int[] { 0 };
14393    }
14394
14395    UserManagerService getUserManagerLocked() {
14396        if (mUserManager == null) {
14397            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
14398            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
14399        }
14400        return mUserManager;
14401    }
14402
14403    private void checkValidCaller(int uid, int userId) {
14404        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
14405
14406        throw new SecurityException("Caller uid=" + uid
14407                + " is not privileged to communicate with user=" + userId);
14408    }
14409
14410    private int applyUserId(int uid, int userId) {
14411        return UserHandle.getUid(userId, uid);
14412    }
14413
14414    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
14415        if (info == null) return null;
14416        ApplicationInfo newInfo = new ApplicationInfo(info);
14417        newInfo.uid = applyUserId(info.uid, userId);
14418        newInfo.dataDir = USER_DATA_DIR + userId + "/"
14419                + info.packageName;
14420        return newInfo;
14421    }
14422
14423    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
14424        if (aInfo == null
14425                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
14426            return aInfo;
14427        }
14428
14429        ActivityInfo info = new ActivityInfo(aInfo);
14430        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
14431        return info;
14432    }
14433}
14434