ActivityManagerService.java revision 6d51571835737c7502a2e111ee9dc2527ebad984
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            userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId,
4599                    false, true, "getIntentSender", null);
4600            try {
4601                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4602                    int uid = AppGlobals.getPackageManager()
4603                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4604                    if (!UserHandle.isSameApp(callingUid, uid)) {
4605                        String msg = "Permission Denial: getIntentSender() from pid="
4606                            + Binder.getCallingPid()
4607                            + ", uid=" + Binder.getCallingUid()
4608                            + ", (need uid=" + uid + ")"
4609                            + " is not allowed to send as package " + packageName;
4610                        Slog.w(TAG, msg);
4611                        throw new SecurityException(msg);
4612                    }
4613                }
4614
4615                return getIntentSenderLocked(type, packageName, callingUid, userId,
4616                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4617
4618            } catch (RemoteException e) {
4619                throw new SecurityException(e);
4620            }
4621        }
4622    }
4623
4624    IIntentSender getIntentSenderLocked(int type, String packageName,
4625            int callingUid, int userId, IBinder token, String resultWho,
4626            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4627            Bundle options) {
4628        if (DEBUG_MU)
4629            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4630        ActivityRecord activity = null;
4631        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4632            activity = mMainStack.isInStackLocked(token);
4633            if (activity == null) {
4634                return null;
4635            }
4636            if (activity.finishing) {
4637                return null;
4638            }
4639        }
4640
4641        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4642        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4643        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4644        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4645                |PendingIntent.FLAG_UPDATE_CURRENT);
4646
4647        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4648                type, packageName, activity, resultWho,
4649                requestCode, intents, resolvedTypes, flags, options, userId);
4650        WeakReference<PendingIntentRecord> ref;
4651        ref = mIntentSenderRecords.get(key);
4652        PendingIntentRecord rec = ref != null ? ref.get() : null;
4653        if (rec != null) {
4654            if (!cancelCurrent) {
4655                if (updateCurrent) {
4656                    if (rec.key.requestIntent != null) {
4657                        rec.key.requestIntent.replaceExtras(intents != null ?
4658                                intents[intents.length - 1] : null);
4659                    }
4660                    if (intents != null) {
4661                        intents[intents.length-1] = rec.key.requestIntent;
4662                        rec.key.allIntents = intents;
4663                        rec.key.allResolvedTypes = resolvedTypes;
4664                    } else {
4665                        rec.key.allIntents = null;
4666                        rec.key.allResolvedTypes = null;
4667                    }
4668                }
4669                return rec;
4670            }
4671            rec.canceled = true;
4672            mIntentSenderRecords.remove(key);
4673        }
4674        if (noCreate) {
4675            return rec;
4676        }
4677        rec = new PendingIntentRecord(this, key, callingUid);
4678        mIntentSenderRecords.put(key, rec.ref);
4679        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4680            if (activity.pendingResults == null) {
4681                activity.pendingResults
4682                        = new HashSet<WeakReference<PendingIntentRecord>>();
4683            }
4684            activity.pendingResults.add(rec.ref);
4685        }
4686        return rec;
4687    }
4688
4689    public void cancelIntentSender(IIntentSender sender) {
4690        if (!(sender instanceof PendingIntentRecord)) {
4691            return;
4692        }
4693        synchronized(this) {
4694            PendingIntentRecord rec = (PendingIntentRecord)sender;
4695            try {
4696                int uid = AppGlobals.getPackageManager()
4697                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4698                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4699                    String msg = "Permission Denial: cancelIntentSender() from pid="
4700                        + Binder.getCallingPid()
4701                        + ", uid=" + Binder.getCallingUid()
4702                        + " is not allowed to cancel packges "
4703                        + rec.key.packageName;
4704                    Slog.w(TAG, msg);
4705                    throw new SecurityException(msg);
4706                }
4707            } catch (RemoteException e) {
4708                throw new SecurityException(e);
4709            }
4710            cancelIntentSenderLocked(rec, true);
4711        }
4712    }
4713
4714    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4715        rec.canceled = true;
4716        mIntentSenderRecords.remove(rec.key);
4717        if (cleanActivity && rec.key.activity != null) {
4718            rec.key.activity.pendingResults.remove(rec.ref);
4719        }
4720    }
4721
4722    public String getPackageForIntentSender(IIntentSender pendingResult) {
4723        if (!(pendingResult instanceof PendingIntentRecord)) {
4724            return null;
4725        }
4726        try {
4727            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4728            return res.key.packageName;
4729        } catch (ClassCastException e) {
4730        }
4731        return null;
4732    }
4733
4734    public int getUidForIntentSender(IIntentSender sender) {
4735        if (sender instanceof PendingIntentRecord) {
4736            try {
4737                PendingIntentRecord res = (PendingIntentRecord)sender;
4738                return res.uid;
4739            } catch (ClassCastException e) {
4740            }
4741        }
4742        return -1;
4743    }
4744
4745    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4746        if (!(pendingResult instanceof PendingIntentRecord)) {
4747            return false;
4748        }
4749        try {
4750            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4751            if (res.key.allIntents == null) {
4752                return false;
4753            }
4754            for (int i=0; i<res.key.allIntents.length; i++) {
4755                Intent intent = res.key.allIntents[i];
4756                if (intent.getPackage() != null && intent.getComponent() != null) {
4757                    return false;
4758                }
4759            }
4760            return true;
4761        } catch (ClassCastException e) {
4762        }
4763        return false;
4764    }
4765
4766    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4767        if (!(pendingResult instanceof PendingIntentRecord)) {
4768            return false;
4769        }
4770        try {
4771            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4772            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4773                return true;
4774            }
4775            return false;
4776        } catch (ClassCastException e) {
4777        }
4778        return false;
4779    }
4780
4781    public void setProcessLimit(int max) {
4782        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4783                "setProcessLimit()");
4784        synchronized (this) {
4785            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4786            mProcessLimitOverride = max;
4787        }
4788        trimApplications();
4789    }
4790
4791    public int getProcessLimit() {
4792        synchronized (this) {
4793            return mProcessLimitOverride;
4794        }
4795    }
4796
4797    void foregroundTokenDied(ForegroundToken token) {
4798        synchronized (ActivityManagerService.this) {
4799            synchronized (mPidsSelfLocked) {
4800                ForegroundToken cur
4801                    = mForegroundProcesses.get(token.pid);
4802                if (cur != token) {
4803                    return;
4804                }
4805                mForegroundProcesses.remove(token.pid);
4806                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4807                if (pr == null) {
4808                    return;
4809                }
4810                pr.forcingToForeground = null;
4811                pr.foregroundServices = false;
4812            }
4813            updateOomAdjLocked();
4814        }
4815    }
4816
4817    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4818        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4819                "setProcessForeground()");
4820        synchronized(this) {
4821            boolean changed = false;
4822
4823            synchronized (mPidsSelfLocked) {
4824                ProcessRecord pr = mPidsSelfLocked.get(pid);
4825                if (pr == null && isForeground) {
4826                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4827                    return;
4828                }
4829                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4830                if (oldToken != null) {
4831                    oldToken.token.unlinkToDeath(oldToken, 0);
4832                    mForegroundProcesses.remove(pid);
4833                    if (pr != null) {
4834                        pr.forcingToForeground = null;
4835                    }
4836                    changed = true;
4837                }
4838                if (isForeground && token != null) {
4839                    ForegroundToken newToken = new ForegroundToken() {
4840                        public void binderDied() {
4841                            foregroundTokenDied(this);
4842                        }
4843                    };
4844                    newToken.pid = pid;
4845                    newToken.token = token;
4846                    try {
4847                        token.linkToDeath(newToken, 0);
4848                        mForegroundProcesses.put(pid, newToken);
4849                        pr.forcingToForeground = token;
4850                        changed = true;
4851                    } catch (RemoteException e) {
4852                        // If the process died while doing this, we will later
4853                        // do the cleanup with the process death link.
4854                    }
4855                }
4856            }
4857
4858            if (changed) {
4859                updateOomAdjLocked();
4860            }
4861        }
4862    }
4863
4864    // =========================================================
4865    // PERMISSIONS
4866    // =========================================================
4867
4868    static class PermissionController extends IPermissionController.Stub {
4869        ActivityManagerService mActivityManagerService;
4870        PermissionController(ActivityManagerService activityManagerService) {
4871            mActivityManagerService = activityManagerService;
4872        }
4873
4874        public boolean checkPermission(String permission, int pid, int uid) {
4875            return mActivityManagerService.checkPermission(permission, pid,
4876                    uid) == PackageManager.PERMISSION_GRANTED;
4877        }
4878    }
4879
4880    /**
4881     * This can be called with or without the global lock held.
4882     */
4883    int checkComponentPermission(String permission, int pid, int uid,
4884            int owningUid, boolean exported) {
4885        // We might be performing an operation on behalf of an indirect binder
4886        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4887        // client identity accordingly before proceeding.
4888        Identity tlsIdentity = sCallerIdentity.get();
4889        if (tlsIdentity != null) {
4890            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4891                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4892            uid = tlsIdentity.uid;
4893            pid = tlsIdentity.pid;
4894        }
4895
4896        if (pid == MY_PID) {
4897            return PackageManager.PERMISSION_GRANTED;
4898        }
4899
4900        return ActivityManager.checkComponentPermission(permission, uid,
4901                owningUid, exported);
4902    }
4903
4904    /**
4905     * As the only public entry point for permissions checking, this method
4906     * can enforce the semantic that requesting a check on a null global
4907     * permission is automatically denied.  (Internally a null permission
4908     * string is used when calling {@link #checkComponentPermission} in cases
4909     * when only uid-based security is needed.)
4910     *
4911     * This can be called with or without the global lock held.
4912     */
4913    public int checkPermission(String permission, int pid, int uid) {
4914        if (permission == null) {
4915            return PackageManager.PERMISSION_DENIED;
4916        }
4917        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4918    }
4919
4920    /**
4921     * Binder IPC calls go through the public entry point.
4922     * This can be called with or without the global lock held.
4923     */
4924    int checkCallingPermission(String permission) {
4925        return checkPermission(permission,
4926                Binder.getCallingPid(),
4927                UserHandle.getAppId(Binder.getCallingUid()));
4928    }
4929
4930    /**
4931     * This can be called with or without the global lock held.
4932     */
4933    void enforceCallingPermission(String permission, String func) {
4934        if (checkCallingPermission(permission)
4935                == PackageManager.PERMISSION_GRANTED) {
4936            return;
4937        }
4938
4939        String msg = "Permission Denial: " + func + " from pid="
4940                + Binder.getCallingPid()
4941                + ", uid=" + Binder.getCallingUid()
4942                + " requires " + permission;
4943        Slog.w(TAG, msg);
4944        throw new SecurityException(msg);
4945    }
4946
4947    /**
4948     * Determine if UID is holding permissions required to access {@link Uri} in
4949     * the given {@link ProviderInfo}. Final permission checking is always done
4950     * in {@link ContentProvider}.
4951     */
4952    private final boolean checkHoldingPermissionsLocked(
4953            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4954        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4955                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4956
4957        if (pi.applicationInfo.uid == uid) {
4958            return true;
4959        } else if (!pi.exported) {
4960            return false;
4961        }
4962
4963        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4964        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4965        try {
4966            // check if target holds top-level <provider> permissions
4967            if (!readMet && pi.readPermission != null
4968                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4969                readMet = true;
4970            }
4971            if (!writeMet && pi.writePermission != null
4972                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4973                writeMet = true;
4974            }
4975
4976            // track if unprotected read/write is allowed; any denied
4977            // <path-permission> below removes this ability
4978            boolean allowDefaultRead = pi.readPermission == null;
4979            boolean allowDefaultWrite = pi.writePermission == null;
4980
4981            // check if target holds any <path-permission> that match uri
4982            final PathPermission[] pps = pi.pathPermissions;
4983            if (pps != null) {
4984                final String path = uri.getPath();
4985                int i = pps.length;
4986                while (i > 0 && (!readMet || !writeMet)) {
4987                    i--;
4988                    PathPermission pp = pps[i];
4989                    if (pp.match(path)) {
4990                        if (!readMet) {
4991                            final String pprperm = pp.getReadPermission();
4992                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4993                                    + pprperm + " for " + pp.getPath()
4994                                    + ": match=" + pp.match(path)
4995                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4996                            if (pprperm != null) {
4997                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4998                                    readMet = true;
4999                                } else {
5000                                    allowDefaultRead = false;
5001                                }
5002                            }
5003                        }
5004                        if (!writeMet) {
5005                            final String ppwperm = pp.getWritePermission();
5006                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5007                                    + ppwperm + " for " + pp.getPath()
5008                                    + ": match=" + pp.match(path)
5009                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5010                            if (ppwperm != null) {
5011                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5012                                    writeMet = true;
5013                                } else {
5014                                    allowDefaultWrite = false;
5015                                }
5016                            }
5017                        }
5018                    }
5019                }
5020            }
5021
5022            // grant unprotected <provider> read/write, if not blocked by
5023            // <path-permission> above
5024            if (allowDefaultRead) readMet = true;
5025            if (allowDefaultWrite) writeMet = true;
5026
5027        } catch (RemoteException e) {
5028            return false;
5029        }
5030
5031        return readMet && writeMet;
5032    }
5033
5034    private final boolean checkUriPermissionLocked(Uri uri, int uid,
5035            int modeFlags) {
5036        // Root gets to do everything.
5037        if (uid == 0) {
5038            return true;
5039        }
5040        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5041        if (perms == null) return false;
5042        UriPermission perm = perms.get(uri);
5043        if (perm == null) return false;
5044        return (modeFlags&perm.modeFlags) == modeFlags;
5045    }
5046
5047    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5048        enforceNotIsolatedCaller("checkUriPermission");
5049
5050        // Another redirected-binder-call permissions check as in
5051        // {@link checkComponentPermission}.
5052        Identity tlsIdentity = sCallerIdentity.get();
5053        if (tlsIdentity != null) {
5054            uid = tlsIdentity.uid;
5055            pid = tlsIdentity.pid;
5056        }
5057
5058        // Our own process gets to do everything.
5059        if (pid == MY_PID) {
5060            return PackageManager.PERMISSION_GRANTED;
5061        }
5062        synchronized(this) {
5063            return checkUriPermissionLocked(uri, uid, modeFlags)
5064                    ? PackageManager.PERMISSION_GRANTED
5065                    : PackageManager.PERMISSION_DENIED;
5066        }
5067    }
5068
5069    /**
5070     * Check if the targetPkg can be granted permission to access uri by
5071     * the callingUid using the given modeFlags.  Throws a security exception
5072     * if callingUid is not allowed to do this.  Returns the uid of the target
5073     * if the URI permission grant should be performed; returns -1 if it is not
5074     * needed (for example targetPkg already has permission to access the URI).
5075     * If you already know the uid of the target, you can supply it in
5076     * lastTargetUid else set that to -1.
5077     */
5078    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5079            Uri uri, int modeFlags, int lastTargetUid) {
5080        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5081                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5082        if (modeFlags == 0) {
5083            return -1;
5084        }
5085
5086        if (targetPkg != null) {
5087            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5088                    "Checking grant " + targetPkg + " permission to " + uri);
5089        }
5090
5091        final IPackageManager pm = AppGlobals.getPackageManager();
5092
5093        // If this is not a content: uri, we can't do anything with it.
5094        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5095            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5096                    "Can't grant URI permission for non-content URI: " + uri);
5097            return -1;
5098        }
5099
5100        String name = uri.getAuthority();
5101        ProviderInfo pi = null;
5102        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5103                UserHandle.getUserId(callingUid));
5104        if (cpr != null) {
5105            pi = cpr.info;
5106        } else {
5107            try {
5108                pi = pm.resolveContentProvider(name,
5109                        PackageManager.GET_URI_PERMISSION_PATTERNS,
5110                        UserHandle.getUserId(callingUid));
5111            } catch (RemoteException ex) {
5112            }
5113        }
5114        if (pi == null) {
5115            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5116            return -1;
5117        }
5118
5119        int targetUid = lastTargetUid;
5120        if (targetUid < 0 && targetPkg != null) {
5121            try {
5122                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5123                if (targetUid < 0) {
5124                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5125                            "Can't grant URI permission no uid for: " + targetPkg);
5126                    return -1;
5127                }
5128            } catch (RemoteException ex) {
5129                return -1;
5130            }
5131        }
5132
5133        if (targetUid >= 0) {
5134            // First...  does the target actually need this permission?
5135            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5136                // No need to grant the target this permission.
5137                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5138                        "Target " + targetPkg + " already has full permission to " + uri);
5139                return -1;
5140            }
5141        } else {
5142            // First...  there is no target package, so can anyone access it?
5143            boolean allowed = pi.exported;
5144            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5145                if (pi.readPermission != null) {
5146                    allowed = false;
5147                }
5148            }
5149            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5150                if (pi.writePermission != null) {
5151                    allowed = false;
5152                }
5153            }
5154            if (allowed) {
5155                return -1;
5156            }
5157        }
5158
5159        // Second...  is the provider allowing granting of URI permissions?
5160        if (!pi.grantUriPermissions) {
5161            throw new SecurityException("Provider " + pi.packageName
5162                    + "/" + pi.name
5163                    + " does not allow granting of Uri permissions (uri "
5164                    + uri + ")");
5165        }
5166        if (pi.uriPermissionPatterns != null) {
5167            final int N = pi.uriPermissionPatterns.length;
5168            boolean allowed = false;
5169            for (int i=0; i<N; i++) {
5170                if (pi.uriPermissionPatterns[i] != null
5171                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5172                    allowed = true;
5173                    break;
5174                }
5175            }
5176            if (!allowed) {
5177                throw new SecurityException("Provider " + pi.packageName
5178                        + "/" + pi.name
5179                        + " does not allow granting of permission to path of Uri "
5180                        + uri);
5181            }
5182        }
5183
5184        // Third...  does the caller itself have permission to access
5185        // this uri?
5186        if (callingUid != Process.myUid()) {
5187            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5188                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5189                    throw new SecurityException("Uid " + callingUid
5190                            + " does not have permission to uri " + uri);
5191                }
5192            }
5193        }
5194
5195        return targetUid;
5196    }
5197
5198    public int checkGrantUriPermission(int callingUid, String targetPkg,
5199            Uri uri, int modeFlags) {
5200        enforceNotIsolatedCaller("checkGrantUriPermission");
5201        synchronized(this) {
5202            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5203        }
5204    }
5205
5206    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5207            Uri uri, int modeFlags, UriPermissionOwner owner) {
5208        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5209                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5210        if (modeFlags == 0) {
5211            return;
5212        }
5213
5214        // So here we are: the caller has the assumed permission
5215        // to the uri, and the target doesn't.  Let's now give this to
5216        // the target.
5217
5218        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5219                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5220
5221        HashMap<Uri, UriPermission> targetUris
5222                = mGrantedUriPermissions.get(targetUid);
5223        if (targetUris == null) {
5224            targetUris = new HashMap<Uri, UriPermission>();
5225            mGrantedUriPermissions.put(targetUid, targetUris);
5226        }
5227
5228        UriPermission perm = targetUris.get(uri);
5229        if (perm == null) {
5230            perm = new UriPermission(targetUid, uri);
5231            targetUris.put(uri, perm);
5232        }
5233
5234        perm.modeFlags |= modeFlags;
5235        if (owner == null) {
5236            perm.globalModeFlags |= modeFlags;
5237        } else {
5238            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5239                 perm.readOwners.add(owner);
5240                 owner.addReadPermission(perm);
5241            }
5242            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5243                 perm.writeOwners.add(owner);
5244                 owner.addWritePermission(perm);
5245            }
5246        }
5247    }
5248
5249    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5250            int modeFlags, UriPermissionOwner owner) {
5251        if (targetPkg == null) {
5252            throw new NullPointerException("targetPkg");
5253        }
5254
5255        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5256        if (targetUid < 0) {
5257            return;
5258        }
5259
5260        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5261    }
5262
5263    static class NeededUriGrants extends ArrayList<Uri> {
5264        final String targetPkg;
5265        final int targetUid;
5266        final int flags;
5267
5268        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5269            targetPkg = _targetPkg;
5270            targetUid = _targetUid;
5271            flags = _flags;
5272        }
5273    }
5274
5275    /**
5276     * Like checkGrantUriPermissionLocked, but takes an Intent.
5277     */
5278    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5279            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5280        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5281                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5282                + " clip=" + (intent != null ? intent.getClipData() : null)
5283                + " from " + intent + "; flags=0x"
5284                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5285
5286        if (targetPkg == null) {
5287            throw new NullPointerException("targetPkg");
5288        }
5289
5290        if (intent == null) {
5291            return null;
5292        }
5293        Uri data = intent.getData();
5294        ClipData clip = intent.getClipData();
5295        if (data == null && clip == null) {
5296            return null;
5297        }
5298        if (data != null) {
5299            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5300                mode, needed != null ? needed.targetUid : -1);
5301            if (target > 0) {
5302                if (needed == null) {
5303                    needed = new NeededUriGrants(targetPkg, target, mode);
5304                }
5305                needed.add(data);
5306            }
5307        }
5308        if (clip != null) {
5309            for (int i=0; i<clip.getItemCount(); i++) {
5310                Uri uri = clip.getItemAt(i).getUri();
5311                if (uri != null) {
5312                    int target = -1;
5313                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5314                            mode, needed != null ? needed.targetUid : -1);
5315                    if (target > 0) {
5316                        if (needed == null) {
5317                            needed = new NeededUriGrants(targetPkg, target, mode);
5318                        }
5319                        needed.add(uri);
5320                    }
5321                } else {
5322                    Intent clipIntent = clip.getItemAt(i).getIntent();
5323                    if (clipIntent != null) {
5324                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5325                                callingUid, targetPkg, clipIntent, mode, needed);
5326                        if (newNeeded != null) {
5327                            needed = newNeeded;
5328                        }
5329                    }
5330                }
5331            }
5332        }
5333
5334        return needed;
5335    }
5336
5337    /**
5338     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5339     */
5340    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5341            UriPermissionOwner owner) {
5342        if (needed != null) {
5343            for (int i=0; i<needed.size(); i++) {
5344                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5345                        needed.get(i), needed.flags, owner);
5346            }
5347        }
5348    }
5349
5350    void grantUriPermissionFromIntentLocked(int callingUid,
5351            String targetPkg, Intent intent, UriPermissionOwner owner) {
5352        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5353                intent, intent != null ? intent.getFlags() : 0, null);
5354        if (needed == null) {
5355            return;
5356        }
5357
5358        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5359    }
5360
5361    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5362            Uri uri, int modeFlags) {
5363        enforceNotIsolatedCaller("grantUriPermission");
5364        synchronized(this) {
5365            final ProcessRecord r = getRecordForAppLocked(caller);
5366            if (r == null) {
5367                throw new SecurityException("Unable to find app for caller "
5368                        + caller
5369                        + " when granting permission to uri " + uri);
5370            }
5371            if (targetPkg == null) {
5372                throw new IllegalArgumentException("null target");
5373            }
5374            if (uri == null) {
5375                throw new IllegalArgumentException("null uri");
5376            }
5377
5378            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5379                    null);
5380        }
5381    }
5382
5383    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5384        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5385                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5386            HashMap<Uri, UriPermission> perms
5387                    = mGrantedUriPermissions.get(perm.uid);
5388            if (perms != null) {
5389                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5390                        "Removing " + perm.uid + " permission to " + perm.uri);
5391                perms.remove(perm.uri);
5392                if (perms.size() == 0) {
5393                    mGrantedUriPermissions.remove(perm.uid);
5394                }
5395            }
5396        }
5397    }
5398
5399    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5400            int modeFlags) {
5401        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5402                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5403        if (modeFlags == 0) {
5404            return;
5405        }
5406
5407        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5408                "Revoking all granted permissions to " + uri);
5409
5410        final IPackageManager pm = AppGlobals.getPackageManager();
5411
5412        final String authority = uri.getAuthority();
5413        ProviderInfo pi = null;
5414        int userId = UserHandle.getUserId(callingUid);
5415        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5416        if (cpr != null) {
5417            pi = cpr.info;
5418        } else {
5419            try {
5420                pi = pm.resolveContentProvider(authority,
5421                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5422            } catch (RemoteException ex) {
5423            }
5424        }
5425        if (pi == null) {
5426            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5427            return;
5428        }
5429
5430        // Does the caller have this permission on the URI?
5431        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5432            // Right now, if you are not the original owner of the permission,
5433            // you are not allowed to revoke it.
5434            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5435                throw new SecurityException("Uid " + callingUid
5436                        + " does not have permission to uri " + uri);
5437            //}
5438        }
5439
5440        // Go through all of the permissions and remove any that match.
5441        final List<String> SEGMENTS = uri.getPathSegments();
5442        if (SEGMENTS != null) {
5443            final int NS = SEGMENTS.size();
5444            int N = mGrantedUriPermissions.size();
5445            for (int i=0; i<N; i++) {
5446                HashMap<Uri, UriPermission> perms
5447                        = mGrantedUriPermissions.valueAt(i);
5448                Iterator<UriPermission> it = perms.values().iterator();
5449            toploop:
5450                while (it.hasNext()) {
5451                    UriPermission perm = it.next();
5452                    Uri targetUri = perm.uri;
5453                    if (!authority.equals(targetUri.getAuthority())) {
5454                        continue;
5455                    }
5456                    List<String> targetSegments = targetUri.getPathSegments();
5457                    if (targetSegments == null) {
5458                        continue;
5459                    }
5460                    if (targetSegments.size() < NS) {
5461                        continue;
5462                    }
5463                    for (int j=0; j<NS; j++) {
5464                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5465                            continue toploop;
5466                        }
5467                    }
5468                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5469                            "Revoking " + perm.uid + " permission to " + perm.uri);
5470                    perm.clearModes(modeFlags);
5471                    if (perm.modeFlags == 0) {
5472                        it.remove();
5473                    }
5474                }
5475                if (perms.size() == 0) {
5476                    mGrantedUriPermissions.remove(
5477                            mGrantedUriPermissions.keyAt(i));
5478                    N--;
5479                    i--;
5480                }
5481            }
5482        }
5483    }
5484
5485    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5486            int modeFlags) {
5487        enforceNotIsolatedCaller("revokeUriPermission");
5488        synchronized(this) {
5489            final ProcessRecord r = getRecordForAppLocked(caller);
5490            if (r == null) {
5491                throw new SecurityException("Unable to find app for caller "
5492                        + caller
5493                        + " when revoking permission to uri " + uri);
5494            }
5495            if (uri == null) {
5496                Slog.w(TAG, "revokeUriPermission: null uri");
5497                return;
5498            }
5499
5500            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5501                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5502            if (modeFlags == 0) {
5503                return;
5504            }
5505
5506            final IPackageManager pm = AppGlobals.getPackageManager();
5507
5508            final String authority = uri.getAuthority();
5509            ProviderInfo pi = null;
5510            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5511            if (cpr != null) {
5512                pi = cpr.info;
5513            } else {
5514                try {
5515                    pi = pm.resolveContentProvider(authority,
5516                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5517                } catch (RemoteException ex) {
5518                }
5519            }
5520            if (pi == null) {
5521                Slog.w(TAG, "No content provider found for permission revoke: "
5522                        + uri.toSafeString());
5523                return;
5524            }
5525
5526            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5527        }
5528    }
5529
5530    @Override
5531    public IBinder newUriPermissionOwner(String name) {
5532        enforceNotIsolatedCaller("newUriPermissionOwner");
5533        synchronized(this) {
5534            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5535            return owner.getExternalTokenLocked();
5536        }
5537    }
5538
5539    @Override
5540    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5541            Uri uri, int modeFlags) {
5542        synchronized(this) {
5543            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5544            if (owner == null) {
5545                throw new IllegalArgumentException("Unknown owner: " + token);
5546            }
5547            if (fromUid != Binder.getCallingUid()) {
5548                if (Binder.getCallingUid() != Process.myUid()) {
5549                    // Only system code can grant URI permissions on behalf
5550                    // of other users.
5551                    throw new SecurityException("nice try");
5552                }
5553            }
5554            if (targetPkg == null) {
5555                throw new IllegalArgumentException("null target");
5556            }
5557            if (uri == null) {
5558                throw new IllegalArgumentException("null uri");
5559            }
5560
5561            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5562        }
5563    }
5564
5565    @Override
5566    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5567        synchronized(this) {
5568            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5569            if (owner == null) {
5570                throw new IllegalArgumentException("Unknown owner: " + token);
5571            }
5572
5573            if (uri == null) {
5574                owner.removeUriPermissionsLocked(mode);
5575            } else {
5576                owner.removeUriPermissionLocked(uri, mode);
5577            }
5578        }
5579    }
5580
5581    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5582        synchronized (this) {
5583            ProcessRecord app =
5584                who != null ? getRecordForAppLocked(who) : null;
5585            if (app == null) return;
5586
5587            Message msg = Message.obtain();
5588            msg.what = WAIT_FOR_DEBUGGER_MSG;
5589            msg.obj = app;
5590            msg.arg1 = waiting ? 1 : 0;
5591            mHandler.sendMessage(msg);
5592        }
5593    }
5594
5595    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5596        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5597        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5598        outInfo.availMem = Process.getFreeMemory();
5599        outInfo.totalMem = Process.getTotalMemory();
5600        outInfo.threshold = homeAppMem;
5601        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5602        outInfo.hiddenAppThreshold = hiddenAppMem;
5603        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5604                ProcessList.SERVICE_ADJ);
5605        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5606                ProcessList.VISIBLE_APP_ADJ);
5607        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5608                ProcessList.FOREGROUND_APP_ADJ);
5609    }
5610
5611    // =========================================================
5612    // TASK MANAGEMENT
5613    // =========================================================
5614
5615    public List getTasks(int maxNum, int flags,
5616                         IThumbnailReceiver receiver) {
5617        ArrayList list = new ArrayList();
5618
5619        PendingThumbnailsRecord pending = null;
5620        IApplicationThread topThumbnail = null;
5621        ActivityRecord topRecord = null;
5622
5623        synchronized(this) {
5624            if (localLOGV) Slog.v(
5625                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5626                + ", receiver=" + receiver);
5627
5628            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5629                    != PackageManager.PERMISSION_GRANTED) {
5630                if (receiver != null) {
5631                    // If the caller wants to wait for pending thumbnails,
5632                    // it ain't gonna get them.
5633                    try {
5634                        receiver.finished();
5635                    } catch (RemoteException ex) {
5636                    }
5637                }
5638                String msg = "Permission Denial: getTasks() from pid="
5639                        + Binder.getCallingPid()
5640                        + ", uid=" + Binder.getCallingUid()
5641                        + " requires " + android.Manifest.permission.GET_TASKS;
5642                Slog.w(TAG, msg);
5643                throw new SecurityException(msg);
5644            }
5645
5646            int pos = mMainStack.mHistory.size()-1;
5647            ActivityRecord next =
5648                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5649            ActivityRecord top = null;
5650            TaskRecord curTask = null;
5651            int numActivities = 0;
5652            int numRunning = 0;
5653            while (pos >= 0 && maxNum > 0) {
5654                final ActivityRecord r = next;
5655                pos--;
5656                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5657
5658                // Initialize state for next task if needed.
5659                if (top == null ||
5660                        (top.state == ActivityState.INITIALIZING
5661                            && top.task == r.task)) {
5662                    top = r;
5663                    curTask = r.task;
5664                    numActivities = numRunning = 0;
5665                }
5666
5667                // Add 'r' into the current task.
5668                numActivities++;
5669                if (r.app != null && r.app.thread != null) {
5670                    numRunning++;
5671                }
5672
5673                if (localLOGV) Slog.v(
5674                    TAG, r.intent.getComponent().flattenToShortString()
5675                    + ": task=" + r.task);
5676
5677                // If the next one is a different task, generate a new
5678                // TaskInfo entry for what we have.
5679                if (next == null || next.task != curTask) {
5680                    ActivityManager.RunningTaskInfo ci
5681                            = new ActivityManager.RunningTaskInfo();
5682                    ci.id = curTask.taskId;
5683                    ci.baseActivity = r.intent.getComponent();
5684                    ci.topActivity = top.intent.getComponent();
5685                    if (top.thumbHolder != null) {
5686                        ci.description = top.thumbHolder.lastDescription;
5687                    }
5688                    ci.numActivities = numActivities;
5689                    ci.numRunning = numRunning;
5690                    //System.out.println(
5691                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5692                    if (ci.thumbnail == null && receiver != null) {
5693                        if (localLOGV) Slog.v(
5694                            TAG, "State=" + top.state + "Idle=" + top.idle
5695                            + " app=" + top.app
5696                            + " thr=" + (top.app != null ? top.app.thread : null));
5697                        if (top.state == ActivityState.RESUMED
5698                                || top.state == ActivityState.PAUSING) {
5699                            if (top.idle && top.app != null
5700                                && top.app.thread != null) {
5701                                topRecord = top;
5702                                topThumbnail = top.app.thread;
5703                            } else {
5704                                top.thumbnailNeeded = true;
5705                            }
5706                        }
5707                        if (pending == null) {
5708                            pending = new PendingThumbnailsRecord(receiver);
5709                        }
5710                        pending.pendingRecords.add(top);
5711                    }
5712                    list.add(ci);
5713                    maxNum--;
5714                    top = null;
5715                }
5716            }
5717
5718            if (pending != null) {
5719                mPendingThumbnails.add(pending);
5720            }
5721        }
5722
5723        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5724
5725        if (topThumbnail != null) {
5726            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5727            try {
5728                topThumbnail.requestThumbnail(topRecord.appToken);
5729            } catch (Exception e) {
5730                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5731                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5732            }
5733        }
5734
5735        if (pending == null && receiver != null) {
5736            // In this case all thumbnails were available and the client
5737            // is being asked to be told when the remaining ones come in...
5738            // which is unusually, since the top-most currently running
5739            // activity should never have a canned thumbnail!  Oh well.
5740            try {
5741                receiver.finished();
5742            } catch (RemoteException ex) {
5743            }
5744        }
5745
5746        return list;
5747    }
5748
5749    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5750            int flags, int userId) {
5751        final int callingUid = Binder.getCallingUid();
5752        if (userId != UserHandle.getCallingUserId()) {
5753            // Check if the caller is holding permissions for cross-user requests.
5754            if (checkComponentPermission(
5755                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5756                    Binder.getCallingPid(), callingUid, -1, true)
5757                    != PackageManager.PERMISSION_GRANTED) {
5758                String msg = "Permission Denial: "
5759                        + "Request to get recent tasks for user " + userId
5760                        + " but is calling from user " + UserHandle.getUserId(callingUid)
5761                        + "; this requires "
5762                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5763                Slog.w(TAG, msg);
5764                throw new SecurityException(msg);
5765            } else {
5766                if (userId == UserHandle.USER_CURRENT) {
5767                    userId = mCurrentUserId;
5768                }
5769            }
5770        }
5771
5772        synchronized (this) {
5773            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5774                    "getRecentTasks()");
5775            final boolean detailed = checkCallingPermission(
5776                    android.Manifest.permission.GET_DETAILED_TASKS)
5777                    == PackageManager.PERMISSION_GRANTED;
5778
5779            IPackageManager pm = AppGlobals.getPackageManager();
5780
5781            final int N = mRecentTasks.size();
5782            ArrayList<ActivityManager.RecentTaskInfo> res
5783                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5784                            maxNum < N ? maxNum : N);
5785            for (int i=0; i<N && maxNum > 0; i++) {
5786                TaskRecord tr = mRecentTasks.get(i);
5787                // Only add calling user's recent tasks
5788                if (tr.userId != userId) continue;
5789                // Return the entry if desired by the caller.  We always return
5790                // the first entry, because callers always expect this to be the
5791                // foreground app.  We may filter others if the caller has
5792                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5793                // we should exclude the entry.
5794
5795                if (i == 0
5796                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5797                        || (tr.intent == null)
5798                        || ((tr.intent.getFlags()
5799                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5800                    ActivityManager.RecentTaskInfo rti
5801                            = new ActivityManager.RecentTaskInfo();
5802                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5803                    rti.persistentId = tr.taskId;
5804                    rti.baseIntent = new Intent(
5805                            tr.intent != null ? tr.intent : tr.affinityIntent);
5806                    if (!detailed) {
5807                        rti.baseIntent.replaceExtras((Bundle)null);
5808                    }
5809                    rti.origActivity = tr.origActivity;
5810                    rti.description = tr.lastDescription;
5811
5812                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5813                        // Check whether this activity is currently available.
5814                        try {
5815                            if (rti.origActivity != null) {
5816                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5817                                        == null) {
5818                                    continue;
5819                                }
5820                            } else if (rti.baseIntent != null) {
5821                                if (pm.queryIntentActivities(rti.baseIntent,
5822                                        null, 0, userId) == null) {
5823                                    continue;
5824                                }
5825                            }
5826                        } catch (RemoteException e) {
5827                            // Will never happen.
5828                        }
5829                    }
5830
5831                    res.add(rti);
5832                    maxNum--;
5833                }
5834            }
5835            return res;
5836        }
5837    }
5838
5839    private TaskRecord taskForIdLocked(int id) {
5840        final int N = mRecentTasks.size();
5841        for (int i=0; i<N; i++) {
5842            TaskRecord tr = mRecentTasks.get(i);
5843            if (tr.taskId == id) {
5844                return tr;
5845            }
5846        }
5847        return null;
5848    }
5849
5850    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5851        synchronized (this) {
5852            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5853                    "getTaskThumbnails()");
5854            TaskRecord tr = taskForIdLocked(id);
5855            if (tr != null) {
5856                return mMainStack.getTaskThumbnailsLocked(tr);
5857            }
5858        }
5859        return null;
5860    }
5861
5862    public Bitmap getTaskTopThumbnail(int id) {
5863        synchronized (this) {
5864            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5865                    "getTaskTopThumbnail()");
5866            TaskRecord tr = taskForIdLocked(id);
5867            if (tr != null) {
5868                return mMainStack.getTaskTopThumbnailLocked(tr);
5869            }
5870        }
5871        return null;
5872    }
5873
5874    public boolean removeSubTask(int taskId, int subTaskIndex) {
5875        synchronized (this) {
5876            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5877                    "removeSubTask()");
5878            long ident = Binder.clearCallingIdentity();
5879            try {
5880                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5881                        true) != null;
5882            } finally {
5883                Binder.restoreCallingIdentity(ident);
5884            }
5885        }
5886    }
5887
5888    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5889        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5890        Intent baseIntent = new Intent(
5891                tr.intent != null ? tr.intent : tr.affinityIntent);
5892        ComponentName component = baseIntent.getComponent();
5893        if (component == null) {
5894            Slog.w(TAG, "Now component for base intent of task: " + tr);
5895            return;
5896        }
5897
5898        // Find any running services associated with this app.
5899        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5900
5901        if (killProcesses) {
5902            // Find any running processes associated with this app.
5903            final String pkg = component.getPackageName();
5904            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5905            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5906            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5907                for (int i=0; i<uids.size(); i++) {
5908                    ProcessRecord proc = uids.valueAt(i);
5909                    if (proc.userId != tr.userId) {
5910                        continue;
5911                    }
5912                    if (!proc.pkgList.contains(pkg)) {
5913                        continue;
5914                    }
5915                    procs.add(proc);
5916                }
5917            }
5918
5919            // Kill the running processes.
5920            for (int i=0; i<procs.size(); i++) {
5921                ProcessRecord pr = procs.get(i);
5922                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5923                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5924                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5925                            pr.processName, pr.setAdj, "remove task");
5926                    pr.killedBackground = true;
5927                    Process.killProcessQuiet(pr.pid);
5928                } else {
5929                    pr.waitingToKill = "remove task";
5930                }
5931            }
5932        }
5933    }
5934
5935    public boolean removeTask(int taskId, int flags) {
5936        synchronized (this) {
5937            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5938                    "removeTask()");
5939            long ident = Binder.clearCallingIdentity();
5940            try {
5941                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5942                        false);
5943                if (r != null) {
5944                    mRecentTasks.remove(r.task);
5945                    cleanUpRemovedTaskLocked(r.task, flags);
5946                    return true;
5947                } else {
5948                    TaskRecord tr = null;
5949                    int i=0;
5950                    while (i < mRecentTasks.size()) {
5951                        TaskRecord t = mRecentTasks.get(i);
5952                        if (t.taskId == taskId) {
5953                            tr = t;
5954                            break;
5955                        }
5956                        i++;
5957                    }
5958                    if (tr != null) {
5959                        if (tr.numActivities <= 0) {
5960                            // Caller is just removing a recent task that is
5961                            // not actively running.  That is easy!
5962                            mRecentTasks.remove(i);
5963                            cleanUpRemovedTaskLocked(tr, flags);
5964                            return true;
5965                        } else {
5966                            Slog.w(TAG, "removeTask: task " + taskId
5967                                    + " does not have activities to remove, "
5968                                    + " but numActivities=" + tr.numActivities
5969                                    + ": " + tr);
5970                        }
5971                    }
5972                }
5973            } finally {
5974                Binder.restoreCallingIdentity(ident);
5975            }
5976        }
5977        return false;
5978    }
5979
5980    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5981        int j;
5982        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5983        TaskRecord jt = startTask;
5984
5985        // First look backwards
5986        for (j=startIndex-1; j>=0; j--) {
5987            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5988            if (r.task != jt) {
5989                jt = r.task;
5990                if (affinity.equals(jt.affinity)) {
5991                    return j;
5992                }
5993            }
5994        }
5995
5996        // Now look forwards
5997        final int N = mMainStack.mHistory.size();
5998        jt = startTask;
5999        for (j=startIndex+1; j<N; j++) {
6000            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
6001            if (r.task != jt) {
6002                if (affinity.equals(jt.affinity)) {
6003                    return j;
6004                }
6005                jt = r.task;
6006            }
6007        }
6008
6009        // Might it be at the top?
6010        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
6011            return N-1;
6012        }
6013
6014        return -1;
6015    }
6016
6017    /**
6018     * TODO: Add mController hook
6019     */
6020    public void moveTaskToFront(int task, int flags, Bundle options) {
6021        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6022                "moveTaskToFront()");
6023
6024        synchronized(this) {
6025            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6026                    Binder.getCallingUid(), "Task to front")) {
6027                ActivityOptions.abort(options);
6028                return;
6029            }
6030            final long origId = Binder.clearCallingIdentity();
6031            try {
6032                TaskRecord tr = taskForIdLocked(task);
6033                if (tr != null) {
6034                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6035                        mMainStack.mUserLeaving = true;
6036                    }
6037                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6038                        // Caller wants the home activity moved with it.  To accomplish this,
6039                        // we'll just move the home task to the top first.
6040                        mMainStack.moveHomeToFrontLocked();
6041                    }
6042                    mMainStack.moveTaskToFrontLocked(tr, null, options);
6043                    return;
6044                }
6045                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6046                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
6047                    if (hr.task.taskId == task) {
6048                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6049                            mMainStack.mUserLeaving = true;
6050                        }
6051                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6052                            // Caller wants the home activity moved with it.  To accomplish this,
6053                            // we'll just move the home task to the top first.
6054                            mMainStack.moveHomeToFrontLocked();
6055                        }
6056                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
6057                        return;
6058                    }
6059                }
6060            } finally {
6061                Binder.restoreCallingIdentity(origId);
6062            }
6063            ActivityOptions.abort(options);
6064        }
6065    }
6066
6067    public void moveTaskToBack(int task) {
6068        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6069                "moveTaskToBack()");
6070
6071        synchronized(this) {
6072            if (mMainStack.mResumedActivity != null
6073                    && mMainStack.mResumedActivity.task.taskId == task) {
6074                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6075                        Binder.getCallingUid(), "Task to back")) {
6076                    return;
6077                }
6078            }
6079            final long origId = Binder.clearCallingIdentity();
6080            mMainStack.moveTaskToBackLocked(task, null);
6081            Binder.restoreCallingIdentity(origId);
6082        }
6083    }
6084
6085    /**
6086     * Moves an activity, and all of the other activities within the same task, to the bottom
6087     * of the history stack.  The activity's order within the task is unchanged.
6088     *
6089     * @param token A reference to the activity we wish to move
6090     * @param nonRoot If false then this only works if the activity is the root
6091     *                of a task; if true it will work for any activity in a task.
6092     * @return Returns true if the move completed, false if not.
6093     */
6094    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6095        enforceNotIsolatedCaller("moveActivityTaskToBack");
6096        synchronized(this) {
6097            final long origId = Binder.clearCallingIdentity();
6098            int taskId = getTaskForActivityLocked(token, !nonRoot);
6099            if (taskId >= 0) {
6100                return mMainStack.moveTaskToBackLocked(taskId, null);
6101            }
6102            Binder.restoreCallingIdentity(origId);
6103        }
6104        return false;
6105    }
6106
6107    public void moveTaskBackwards(int task) {
6108        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6109                "moveTaskBackwards()");
6110
6111        synchronized(this) {
6112            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6113                    Binder.getCallingUid(), "Task backwards")) {
6114                return;
6115            }
6116            final long origId = Binder.clearCallingIdentity();
6117            moveTaskBackwardsLocked(task);
6118            Binder.restoreCallingIdentity(origId);
6119        }
6120    }
6121
6122    private final void moveTaskBackwardsLocked(int task) {
6123        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6124    }
6125
6126    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6127        synchronized(this) {
6128            return getTaskForActivityLocked(token, onlyRoot);
6129        }
6130    }
6131
6132    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6133        final int N = mMainStack.mHistory.size();
6134        TaskRecord lastTask = null;
6135        for (int i=0; i<N; i++) {
6136            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6137            if (r.appToken == token) {
6138                if (!onlyRoot || lastTask != r.task) {
6139                    return r.task.taskId;
6140                }
6141                return -1;
6142            }
6143            lastTask = r.task;
6144        }
6145
6146        return -1;
6147    }
6148
6149    // =========================================================
6150    // THUMBNAILS
6151    // =========================================================
6152
6153    public void reportThumbnail(IBinder token,
6154            Bitmap thumbnail, CharSequence description) {
6155        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6156        final long origId = Binder.clearCallingIdentity();
6157        sendPendingThumbnail(null, token, thumbnail, description, true);
6158        Binder.restoreCallingIdentity(origId);
6159    }
6160
6161    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6162            Bitmap thumbnail, CharSequence description, boolean always) {
6163        TaskRecord task = null;
6164        ArrayList receivers = null;
6165
6166        //System.out.println("Send pending thumbnail: " + r);
6167
6168        synchronized(this) {
6169            if (r == null) {
6170                r = mMainStack.isInStackLocked(token);
6171                if (r == null) {
6172                    return;
6173                }
6174            }
6175            if (thumbnail == null && r.thumbHolder != null) {
6176                thumbnail = r.thumbHolder.lastThumbnail;
6177                description = r.thumbHolder.lastDescription;
6178            }
6179            if (thumbnail == null && !always) {
6180                // If there is no thumbnail, and this entry is not actually
6181                // going away, then abort for now and pick up the next
6182                // thumbnail we get.
6183                return;
6184            }
6185            task = r.task;
6186
6187            int N = mPendingThumbnails.size();
6188            int i=0;
6189            while (i<N) {
6190                PendingThumbnailsRecord pr =
6191                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6192                //System.out.println("Looking in " + pr.pendingRecords);
6193                if (pr.pendingRecords.remove(r)) {
6194                    if (receivers == null) {
6195                        receivers = new ArrayList();
6196                    }
6197                    receivers.add(pr);
6198                    if (pr.pendingRecords.size() == 0) {
6199                        pr.finished = true;
6200                        mPendingThumbnails.remove(i);
6201                        N--;
6202                        continue;
6203                    }
6204                }
6205                i++;
6206            }
6207        }
6208
6209        if (receivers != null) {
6210            final int N = receivers.size();
6211            for (int i=0; i<N; i++) {
6212                try {
6213                    PendingThumbnailsRecord pr =
6214                        (PendingThumbnailsRecord)receivers.get(i);
6215                    pr.receiver.newThumbnail(
6216                        task != null ? task.taskId : -1, thumbnail, description);
6217                    if (pr.finished) {
6218                        pr.receiver.finished();
6219                    }
6220                } catch (Exception e) {
6221                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6222                }
6223            }
6224        }
6225    }
6226
6227    // =========================================================
6228    // CONTENT PROVIDERS
6229    // =========================================================
6230
6231    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6232        List<ProviderInfo> providers = null;
6233        try {
6234            providers = AppGlobals.getPackageManager().
6235                queryContentProviders(app.processName, app.uid,
6236                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6237        } catch (RemoteException ex) {
6238        }
6239        if (DEBUG_MU)
6240            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6241        int userId = app.userId;
6242        if (providers != null) {
6243            int N = providers.size();
6244            for (int i=0; i<N; i++) {
6245                ProviderInfo cpi =
6246                    (ProviderInfo)providers.get(i);
6247                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6248                        cpi.name, cpi.flags);
6249                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6250                    // This is a singleton provider, but a user besides the
6251                    // default user is asking to initialize a process it runs
6252                    // in...  well, no, it doesn't actually run in this process,
6253                    // it runs in the process of the default user.  Get rid of it.
6254                    providers.remove(i);
6255                    N--;
6256                    continue;
6257                }
6258
6259                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6260                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6261                if (cpr == null) {
6262                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6263                    mProviderMap.putProviderByClass(comp, cpr);
6264                }
6265                if (DEBUG_MU)
6266                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6267                app.pubProviders.put(cpi.name, cpr);
6268                app.addPackage(cpi.applicationInfo.packageName);
6269                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6270            }
6271        }
6272        return providers;
6273    }
6274
6275    /**
6276     * Check if {@link ProcessRecord} has a possible chance at accessing the
6277     * given {@link ProviderInfo}. Final permission checking is always done
6278     * in {@link ContentProvider}.
6279     */
6280    private final String checkContentProviderPermissionLocked(
6281            ProviderInfo cpi, ProcessRecord r) {
6282        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6283        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6284        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6285                cpi.applicationInfo.uid, cpi.exported)
6286                == PackageManager.PERMISSION_GRANTED) {
6287            return null;
6288        }
6289        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6290                cpi.applicationInfo.uid, cpi.exported)
6291                == PackageManager.PERMISSION_GRANTED) {
6292            return null;
6293        }
6294
6295        PathPermission[] pps = cpi.pathPermissions;
6296        if (pps != null) {
6297            int i = pps.length;
6298            while (i > 0) {
6299                i--;
6300                PathPermission pp = pps[i];
6301                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6302                        cpi.applicationInfo.uid, cpi.exported)
6303                        == PackageManager.PERMISSION_GRANTED) {
6304                    return null;
6305                }
6306                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6307                        cpi.applicationInfo.uid, cpi.exported)
6308                        == PackageManager.PERMISSION_GRANTED) {
6309                    return null;
6310                }
6311            }
6312        }
6313
6314        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6315        if (perms != null) {
6316            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6317                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6318                    return null;
6319                }
6320            }
6321        }
6322
6323        String msg;
6324        if (!cpi.exported) {
6325            msg = "Permission Denial: opening provider " + cpi.name
6326                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6327                    + ", uid=" + callingUid + ") that is not exported from uid "
6328                    + cpi.applicationInfo.uid;
6329        } else {
6330            msg = "Permission Denial: opening provider " + cpi.name
6331                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6332                    + ", uid=" + callingUid + ") requires "
6333                    + cpi.readPermission + " or " + cpi.writePermission;
6334        }
6335        Slog.w(TAG, msg);
6336        return msg;
6337    }
6338
6339    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6340            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6341        if (r != null) {
6342            for (int i=0; i<r.conProviders.size(); i++) {
6343                ContentProviderConnection conn = r.conProviders.get(i);
6344                if (conn.provider == cpr) {
6345                    if (DEBUG_PROVIDER) Slog.v(TAG,
6346                            "Adding provider requested by "
6347                            + r.processName + " from process "
6348                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6349                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6350                    if (stable) {
6351                        conn.stableCount++;
6352                        conn.numStableIncs++;
6353                    } else {
6354                        conn.unstableCount++;
6355                        conn.numUnstableIncs++;
6356                    }
6357                    return conn;
6358                }
6359            }
6360            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6361            if (stable) {
6362                conn.stableCount = 1;
6363                conn.numStableIncs = 1;
6364            } else {
6365                conn.unstableCount = 1;
6366                conn.numUnstableIncs = 1;
6367            }
6368            cpr.connections.add(conn);
6369            r.conProviders.add(conn);
6370            return conn;
6371        }
6372        cpr.addExternalProcessHandleLocked(externalProcessToken);
6373        return null;
6374    }
6375
6376    boolean decProviderCountLocked(ContentProviderConnection conn,
6377            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6378        if (conn != null) {
6379            cpr = conn.provider;
6380            if (DEBUG_PROVIDER) Slog.v(TAG,
6381                    "Removing provider requested by "
6382                    + conn.client.processName + " from process "
6383                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6384                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6385            if (stable) {
6386                conn.stableCount--;
6387            } else {
6388                conn.unstableCount--;
6389            }
6390            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6391                cpr.connections.remove(conn);
6392                conn.client.conProviders.remove(conn);
6393                return true;
6394            }
6395            return false;
6396        }
6397        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6398        return false;
6399    }
6400
6401    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6402            String name, IBinder token, boolean stable, int userId) {
6403        ContentProviderRecord cpr;
6404        ContentProviderConnection conn = null;
6405        ProviderInfo cpi = null;
6406
6407        synchronized(this) {
6408            ProcessRecord r = null;
6409            if (caller != null) {
6410                r = getRecordForAppLocked(caller);
6411                if (r == null) {
6412                    throw new SecurityException(
6413                            "Unable to find app for caller " + caller
6414                          + " (pid=" + Binder.getCallingPid()
6415                          + ") when getting content provider " + name);
6416                }
6417            }
6418
6419            // First check if this content provider has been published...
6420            cpr = mProviderMap.getProviderByName(name, userId);
6421            boolean providerRunning = cpr != null;
6422            if (providerRunning) {
6423                cpi = cpr.info;
6424                String msg;
6425                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6426                    throw new SecurityException(msg);
6427                }
6428
6429                if (r != null && cpr.canRunHere(r)) {
6430                    // This provider has been published or is in the process
6431                    // of being published...  but it is also allowed to run
6432                    // in the caller's process, so don't make a connection
6433                    // and just let the caller instantiate its own instance.
6434                    ContentProviderHolder holder = cpr.newHolder(null);
6435                    // don't give caller the provider object, it needs
6436                    // to make its own.
6437                    holder.provider = null;
6438                    return holder;
6439                }
6440
6441                final long origId = Binder.clearCallingIdentity();
6442
6443                // In this case the provider instance already exists, so we can
6444                // return it right away.
6445                conn = incProviderCountLocked(r, cpr, token, stable);
6446                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6447                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6448                        // If this is a perceptible app accessing the provider,
6449                        // make sure to count it as being accessed and thus
6450                        // back up on the LRU list.  This is good because
6451                        // content providers are often expensive to start.
6452                        updateLruProcessLocked(cpr.proc, false, true);
6453                    }
6454                }
6455
6456                if (cpr.proc != null) {
6457                    if (false) {
6458                        if (cpr.name.flattenToShortString().equals(
6459                                "com.android.providers.calendar/.CalendarProvider2")) {
6460                            Slog.v(TAG, "****************** KILLING "
6461                                + cpr.name.flattenToShortString());
6462                            Process.killProcess(cpr.proc.pid);
6463                        }
6464                    }
6465                    boolean success = updateOomAdjLocked(cpr.proc);
6466                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6467                    // NOTE: there is still a race here where a signal could be
6468                    // pending on the process even though we managed to update its
6469                    // adj level.  Not sure what to do about this, but at least
6470                    // the race is now smaller.
6471                    if (!success) {
6472                        // Uh oh...  it looks like the provider's process
6473                        // has been killed on us.  We need to wait for a new
6474                        // process to be started, and make sure its death
6475                        // doesn't kill our process.
6476                        Slog.i(TAG,
6477                                "Existing provider " + cpr.name.flattenToShortString()
6478                                + " is crashing; detaching " + r);
6479                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6480                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6481                        if (!lastRef) {
6482                            // This wasn't the last ref our process had on
6483                            // the provider...  we have now been killed, bail.
6484                            return null;
6485                        }
6486                        providerRunning = false;
6487                        conn = null;
6488                    }
6489                }
6490
6491                Binder.restoreCallingIdentity(origId);
6492            }
6493
6494            boolean singleton;
6495            if (!providerRunning) {
6496                try {
6497                    cpi = AppGlobals.getPackageManager().
6498                        resolveContentProvider(name,
6499                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6500                } catch (RemoteException ex) {
6501                }
6502                if (cpi == null) {
6503                    return null;
6504                }
6505                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6506                        cpi.name, cpi.flags);
6507                if (singleton) {
6508                    userId = 0;
6509                }
6510                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6511
6512                String msg;
6513                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6514                    throw new SecurityException(msg);
6515                }
6516
6517                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6518                        && !cpi.processName.equals("system")) {
6519                    // If this content provider does not run in the system
6520                    // process, and the system is not yet ready to run other
6521                    // processes, then fail fast instead of hanging.
6522                    throw new IllegalArgumentException(
6523                            "Attempt to launch content provider before system ready");
6524                }
6525
6526                // Make sure that the user who owns this provider is started.  If not,
6527                // we don't want to allow it to run.
6528                if (mStartedUsers.get(userId) == null) {
6529                    Slog.w(TAG, "Unable to launch app "
6530                            + cpi.applicationInfo.packageName + "/"
6531                            + cpi.applicationInfo.uid + " for provider "
6532                            + name + ": user " + userId + " is stopped");
6533                    return null;
6534                }
6535
6536                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6537                cpr = mProviderMap.getProviderByClass(comp, userId);
6538                final boolean firstClass = cpr == null;
6539                if (firstClass) {
6540                    try {
6541                        ApplicationInfo ai =
6542                            AppGlobals.getPackageManager().
6543                                getApplicationInfo(
6544                                        cpi.applicationInfo.packageName,
6545                                        STOCK_PM_FLAGS, userId);
6546                        if (ai == null) {
6547                            Slog.w(TAG, "No package info for content provider "
6548                                    + cpi.name);
6549                            return null;
6550                        }
6551                        ai = getAppInfoForUser(ai, userId);
6552                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6553                    } catch (RemoteException ex) {
6554                        // pm is in same process, this will never happen.
6555                    }
6556                }
6557
6558                if (r != null && cpr.canRunHere(r)) {
6559                    // If this is a multiprocess provider, then just return its
6560                    // info and allow the caller to instantiate it.  Only do
6561                    // this if the provider is the same user as the caller's
6562                    // process, or can run as root (so can be in any process).
6563                    return cpr.newHolder(null);
6564                }
6565
6566                if (DEBUG_PROVIDER) {
6567                    RuntimeException e = new RuntimeException("here");
6568                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6569                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6570                }
6571
6572                // This is single process, and our app is now connecting to it.
6573                // See if we are already in the process of launching this
6574                // provider.
6575                final int N = mLaunchingProviders.size();
6576                int i;
6577                for (i=0; i<N; i++) {
6578                    if (mLaunchingProviders.get(i) == cpr) {
6579                        break;
6580                    }
6581                }
6582
6583                // If the provider is not already being launched, then get it
6584                // started.
6585                if (i >= N) {
6586                    final long origId = Binder.clearCallingIdentity();
6587
6588                    try {
6589                        // Content provider is now in use, its package can't be stopped.
6590                        try {
6591                            AppGlobals.getPackageManager().setPackageStoppedState(
6592                                    cpr.appInfo.packageName, false, userId);
6593                        } catch (RemoteException e) {
6594                        } catch (IllegalArgumentException e) {
6595                            Slog.w(TAG, "Failed trying to unstop package "
6596                                    + cpr.appInfo.packageName + ": " + e);
6597                        }
6598
6599                        ProcessRecord proc = startProcessLocked(cpi.processName,
6600                                cpr.appInfo, false, 0, "content provider",
6601                                new ComponentName(cpi.applicationInfo.packageName,
6602                                        cpi.name), false, false);
6603                        if (proc == null) {
6604                            Slog.w(TAG, "Unable to launch app "
6605                                    + cpi.applicationInfo.packageName + "/"
6606                                    + cpi.applicationInfo.uid + " for provider "
6607                                    + name + ": process is bad");
6608                            return null;
6609                        }
6610                        cpr.launchingApp = proc;
6611                        mLaunchingProviders.add(cpr);
6612                    } finally {
6613                        Binder.restoreCallingIdentity(origId);
6614                    }
6615                }
6616
6617                // Make sure the provider is published (the same provider class
6618                // may be published under multiple names).
6619                if (firstClass) {
6620                    mProviderMap.putProviderByClass(comp, cpr);
6621                }
6622
6623                mProviderMap.putProviderByName(name, cpr);
6624                conn = incProviderCountLocked(r, cpr, token, stable);
6625                if (conn != null) {
6626                    conn.waiting = true;
6627                }
6628            }
6629        }
6630
6631        // Wait for the provider to be published...
6632        synchronized (cpr) {
6633            while (cpr.provider == null) {
6634                if (cpr.launchingApp == null) {
6635                    Slog.w(TAG, "Unable to launch app "
6636                            + cpi.applicationInfo.packageName + "/"
6637                            + cpi.applicationInfo.uid + " for provider "
6638                            + name + ": launching app became null");
6639                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6640                            cpi.applicationInfo.packageName,
6641                            cpi.applicationInfo.uid, name);
6642                    return null;
6643                }
6644                try {
6645                    if (DEBUG_MU) {
6646                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6647                                + cpr.launchingApp);
6648                    }
6649                    if (conn != null) {
6650                        conn.waiting = true;
6651                    }
6652                    cpr.wait();
6653                } catch (InterruptedException ex) {
6654                } finally {
6655                    if (conn != null) {
6656                        conn.waiting = false;
6657                    }
6658                }
6659            }
6660        }
6661        return cpr != null ? cpr.newHolder(conn) : null;
6662    }
6663
6664    public final ContentProviderHolder getContentProvider(
6665            IApplicationThread caller, String name, int userId, boolean stable) {
6666        enforceNotIsolatedCaller("getContentProvider");
6667        if (caller == null) {
6668            String msg = "null IApplicationThread when getting content provider "
6669                    + name;
6670            Slog.w(TAG, msg);
6671            throw new SecurityException(msg);
6672        }
6673
6674        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6675                false, true, "getContentProvider", null);
6676        return getContentProviderImpl(caller, name, null, stable, userId);
6677    }
6678
6679    public ContentProviderHolder getContentProviderExternal(
6680            String name, int userId, IBinder token) {
6681        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6682            "Do not have permission in call getContentProviderExternal()");
6683        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6684                false, true, "getContentProvider", null);
6685        return getContentProviderExternalUnchecked(name, token, userId);
6686    }
6687
6688    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6689            IBinder token, int userId) {
6690        return getContentProviderImpl(null, name, token, true, userId);
6691    }
6692
6693    /**
6694     * Drop a content provider from a ProcessRecord's bookkeeping
6695     * @param cpr
6696     */
6697    public void removeContentProvider(IBinder connection, boolean stable) {
6698        enforceNotIsolatedCaller("removeContentProvider");
6699        synchronized (this) {
6700            ContentProviderConnection conn;
6701            try {
6702                conn = (ContentProviderConnection)connection;
6703            } catch (ClassCastException e) {
6704                String msg ="removeContentProvider: " + connection
6705                        + " not a ContentProviderConnection";
6706                Slog.w(TAG, msg);
6707                throw new IllegalArgumentException(msg);
6708            }
6709            if (conn == null) {
6710                throw new NullPointerException("connection is null");
6711            }
6712            if (decProviderCountLocked(conn, null, null, stable)) {
6713                updateOomAdjLocked();
6714            }
6715        }
6716    }
6717
6718    public void removeContentProviderExternal(String name, IBinder token) {
6719        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6720            "Do not have permission in call removeContentProviderExternal()");
6721        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6722    }
6723
6724    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6725        synchronized (this) {
6726            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6727            if(cpr == null) {
6728                //remove from mProvidersByClass
6729                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6730                return;
6731            }
6732
6733            //update content provider record entry info
6734            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6735            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6736            if (localCpr.hasExternalProcessHandles()) {
6737                if (localCpr.removeExternalProcessHandleLocked(token)) {
6738                    updateOomAdjLocked();
6739                } else {
6740                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6741                            + " with no external reference for token: "
6742                            + token + ".");
6743                }
6744            } else {
6745                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6746                        + " with no external references.");
6747            }
6748        }
6749    }
6750
6751    public final void publishContentProviders(IApplicationThread caller,
6752            List<ContentProviderHolder> providers) {
6753        if (providers == null) {
6754            return;
6755        }
6756
6757        enforceNotIsolatedCaller("publishContentProviders");
6758        synchronized (this) {
6759            final ProcessRecord r = getRecordForAppLocked(caller);
6760            if (DEBUG_MU)
6761                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6762            if (r == null) {
6763                throw new SecurityException(
6764                        "Unable to find app for caller " + caller
6765                      + " (pid=" + Binder.getCallingPid()
6766                      + ") when publishing content providers");
6767            }
6768
6769            final long origId = Binder.clearCallingIdentity();
6770
6771            final int N = providers.size();
6772            for (int i=0; i<N; i++) {
6773                ContentProviderHolder src = providers.get(i);
6774                if (src == null || src.info == null || src.provider == null) {
6775                    continue;
6776                }
6777                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6778                if (DEBUG_MU)
6779                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6780                if (dst != null) {
6781                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6782                    mProviderMap.putProviderByClass(comp, dst);
6783                    String names[] = dst.info.authority.split(";");
6784                    for (int j = 0; j < names.length; j++) {
6785                        mProviderMap.putProviderByName(names[j], dst);
6786                    }
6787
6788                    int NL = mLaunchingProviders.size();
6789                    int j;
6790                    for (j=0; j<NL; j++) {
6791                        if (mLaunchingProviders.get(j) == dst) {
6792                            mLaunchingProviders.remove(j);
6793                            j--;
6794                            NL--;
6795                        }
6796                    }
6797                    synchronized (dst) {
6798                        dst.provider = src.provider;
6799                        dst.proc = r;
6800                        dst.notifyAll();
6801                    }
6802                    updateOomAdjLocked(r);
6803                }
6804            }
6805
6806            Binder.restoreCallingIdentity(origId);
6807        }
6808    }
6809
6810    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6811        ContentProviderConnection conn;
6812        try {
6813            conn = (ContentProviderConnection)connection;
6814        } catch (ClassCastException e) {
6815            String msg ="refContentProvider: " + connection
6816                    + " not a ContentProviderConnection";
6817            Slog.w(TAG, msg);
6818            throw new IllegalArgumentException(msg);
6819        }
6820        if (conn == null) {
6821            throw new NullPointerException("connection is null");
6822        }
6823
6824        synchronized (this) {
6825            if (stable > 0) {
6826                conn.numStableIncs += stable;
6827            }
6828            stable = conn.stableCount + stable;
6829            if (stable < 0) {
6830                throw new IllegalStateException("stableCount < 0: " + stable);
6831            }
6832
6833            if (unstable > 0) {
6834                conn.numUnstableIncs += unstable;
6835            }
6836            unstable = conn.unstableCount + unstable;
6837            if (unstable < 0) {
6838                throw new IllegalStateException("unstableCount < 0: " + unstable);
6839            }
6840
6841            if ((stable+unstable) <= 0) {
6842                throw new IllegalStateException("ref counts can't go to zero here: stable="
6843                        + stable + " unstable=" + unstable);
6844            }
6845            conn.stableCount = stable;
6846            conn.unstableCount = unstable;
6847            return !conn.dead;
6848        }
6849    }
6850
6851    public void unstableProviderDied(IBinder connection) {
6852        ContentProviderConnection conn;
6853        try {
6854            conn = (ContentProviderConnection)connection;
6855        } catch (ClassCastException e) {
6856            String msg ="refContentProvider: " + connection
6857                    + " not a ContentProviderConnection";
6858            Slog.w(TAG, msg);
6859            throw new IllegalArgumentException(msg);
6860        }
6861        if (conn == null) {
6862            throw new NullPointerException("connection is null");
6863        }
6864
6865        // Safely retrieve the content provider associated with the connection.
6866        IContentProvider provider;
6867        synchronized (this) {
6868            provider = conn.provider.provider;
6869        }
6870
6871        if (provider == null) {
6872            // Um, yeah, we're way ahead of you.
6873            return;
6874        }
6875
6876        // Make sure the caller is being honest with us.
6877        if (provider.asBinder().pingBinder()) {
6878            // Er, no, still looks good to us.
6879            synchronized (this) {
6880                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6881                        + " says " + conn + " died, but we don't agree");
6882                return;
6883            }
6884        }
6885
6886        // Well look at that!  It's dead!
6887        synchronized (this) {
6888            if (conn.provider.provider != provider) {
6889                // But something changed...  good enough.
6890                return;
6891            }
6892
6893            ProcessRecord proc = conn.provider.proc;
6894            if (proc == null || proc.thread == null) {
6895                // Seems like the process is already cleaned up.
6896                return;
6897            }
6898
6899            // As far as we're concerned, this is just like receiving a
6900            // death notification...  just a bit prematurely.
6901            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6902                    + ") early provider death");
6903            final long ident = Binder.clearCallingIdentity();
6904            try {
6905                appDiedLocked(proc, proc.pid, proc.thread);
6906            } finally {
6907                Binder.restoreCallingIdentity(ident);
6908            }
6909        }
6910    }
6911
6912    public static final void installSystemProviders() {
6913        List<ProviderInfo> providers;
6914        synchronized (mSelf) {
6915            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6916            providers = mSelf.generateApplicationProvidersLocked(app);
6917            if (providers != null) {
6918                for (int i=providers.size()-1; i>=0; i--) {
6919                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6920                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6921                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6922                                + ": not system .apk");
6923                        providers.remove(i);
6924                    }
6925                }
6926            }
6927        }
6928        if (providers != null) {
6929            mSystemThread.installSystemProviders(providers);
6930        }
6931
6932        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6933
6934        mSelf.mUsageStatsService.monitorPackages();
6935    }
6936
6937    /**
6938     * Allows app to retrieve the MIME type of a URI without having permission
6939     * to access its content provider.
6940     *
6941     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6942     *
6943     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6944     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6945     */
6946    public String getProviderMimeType(Uri uri, int userId) {
6947        enforceNotIsolatedCaller("getProviderMimeType");
6948        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
6949                userId, false, true, "getProviderMimeType", null);
6950        final String name = uri.getAuthority();
6951        final long ident = Binder.clearCallingIdentity();
6952        ContentProviderHolder holder = null;
6953
6954        try {
6955            holder = getContentProviderExternalUnchecked(name, null, userId);
6956            if (holder != null) {
6957                return holder.provider.getType(uri);
6958            }
6959        } catch (RemoteException e) {
6960            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6961            return null;
6962        } finally {
6963            if (holder != null) {
6964                removeContentProviderExternalUnchecked(name, null, userId);
6965            }
6966            Binder.restoreCallingIdentity(ident);
6967        }
6968
6969        return null;
6970    }
6971
6972    // =========================================================
6973    // GLOBAL MANAGEMENT
6974    // =========================================================
6975
6976    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6977            ApplicationInfo info, String customProcess, boolean isolated) {
6978        String proc = customProcess != null ? customProcess : info.processName;
6979        BatteryStatsImpl.Uid.Proc ps = null;
6980        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6981        int uid = info.uid;
6982        if (isolated) {
6983            int userId = UserHandle.getUserId(uid);
6984            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6985            uid = 0;
6986            while (true) {
6987                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6988                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6989                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6990                }
6991                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6992                mNextIsolatedProcessUid++;
6993                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6994                    // No process for this uid, use it.
6995                    break;
6996                }
6997                stepsLeft--;
6998                if (stepsLeft <= 0) {
6999                    return null;
7000                }
7001            }
7002        }
7003        synchronized (stats) {
7004            ps = stats.getProcessStatsLocked(info.uid, proc);
7005        }
7006        return new ProcessRecord(ps, thread, info, proc, uid);
7007    }
7008
7009    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
7010        ProcessRecord app;
7011        if (!isolated) {
7012            app = getProcessRecordLocked(info.processName, info.uid);
7013        } else {
7014            app = null;
7015        }
7016
7017        if (app == null) {
7018            app = newProcessRecordLocked(null, info, null, isolated);
7019            mProcessNames.put(info.processName, app.uid, app);
7020            if (isolated) {
7021                mIsolatedProcesses.put(app.uid, app);
7022            }
7023            updateLruProcessLocked(app, true, true);
7024        }
7025
7026        // This package really, really can not be stopped.
7027        try {
7028            AppGlobals.getPackageManager().setPackageStoppedState(
7029                    info.packageName, false, UserHandle.getUserId(app.uid));
7030        } catch (RemoteException e) {
7031        } catch (IllegalArgumentException e) {
7032            Slog.w(TAG, "Failed trying to unstop package "
7033                    + info.packageName + ": " + e);
7034        }
7035
7036        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7037                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7038            app.persistent = true;
7039            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
7040        }
7041        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7042            mPersistentStartingProcesses.add(app);
7043            startProcessLocked(app, "added application", app.processName);
7044        }
7045
7046        return app;
7047    }
7048
7049    public void unhandledBack() {
7050        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7051                "unhandledBack()");
7052
7053        synchronized(this) {
7054            int count = mMainStack.mHistory.size();
7055            if (DEBUG_SWITCH) Slog.d(
7056                TAG, "Performing unhandledBack(): stack size = " + count);
7057            if (count > 1) {
7058                final long origId = Binder.clearCallingIdentity();
7059                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
7060                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
7061                Binder.restoreCallingIdentity(origId);
7062            }
7063        }
7064    }
7065
7066    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7067        enforceNotIsolatedCaller("openContentUri");
7068        final int userId = UserHandle.getCallingUserId();
7069        String name = uri.getAuthority();
7070        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
7071        ParcelFileDescriptor pfd = null;
7072        if (cph != null) {
7073            // We record the binder invoker's uid in thread-local storage before
7074            // going to the content provider to open the file.  Later, in the code
7075            // that handles all permissions checks, we look for this uid and use
7076            // that rather than the Activity Manager's own uid.  The effect is that
7077            // we do the check against the caller's permissions even though it looks
7078            // to the content provider like the Activity Manager itself is making
7079            // the request.
7080            sCallerIdentity.set(new Identity(
7081                    Binder.getCallingPid(), Binder.getCallingUid()));
7082            try {
7083                pfd = cph.provider.openFile(uri, "r");
7084            } catch (FileNotFoundException e) {
7085                // do nothing; pfd will be returned null
7086            } finally {
7087                // Ensure that whatever happens, we clean up the identity state
7088                sCallerIdentity.remove();
7089            }
7090
7091            // We've got the fd now, so we're done with the provider.
7092            removeContentProviderExternalUnchecked(name, null, userId);
7093        } else {
7094            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7095        }
7096        return pfd;
7097    }
7098
7099    // Actually is sleeping or shutting down or whatever else in the future
7100    // is an inactive state.
7101    public boolean isSleeping() {
7102        return mSleeping || mShuttingDown;
7103    }
7104
7105    public void goingToSleep() {
7106        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7107                != PackageManager.PERMISSION_GRANTED) {
7108            throw new SecurityException("Requires permission "
7109                    + android.Manifest.permission.DEVICE_POWER);
7110        }
7111
7112        synchronized(this) {
7113            mWentToSleep = true;
7114            updateEventDispatchingLocked();
7115
7116            if (!mSleeping) {
7117                mSleeping = true;
7118                mMainStack.stopIfSleepingLocked();
7119
7120                // Initialize the wake times of all processes.
7121                checkExcessivePowerUsageLocked(false);
7122                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7123                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7124                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7125            }
7126        }
7127    }
7128
7129    public boolean shutdown(int timeout) {
7130        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7131                != PackageManager.PERMISSION_GRANTED) {
7132            throw new SecurityException("Requires permission "
7133                    + android.Manifest.permission.SHUTDOWN);
7134        }
7135
7136        boolean timedout = false;
7137
7138        synchronized(this) {
7139            mShuttingDown = true;
7140            updateEventDispatchingLocked();
7141
7142            if (mMainStack.mResumedActivity != null) {
7143                mMainStack.stopIfSleepingLocked();
7144                final long endTime = System.currentTimeMillis() + timeout;
7145                while (mMainStack.mResumedActivity != null
7146                        || mMainStack.mPausingActivity != null) {
7147                    long delay = endTime - System.currentTimeMillis();
7148                    if (delay <= 0) {
7149                        Slog.w(TAG, "Activity manager shutdown timed out");
7150                        timedout = true;
7151                        break;
7152                    }
7153                    try {
7154                        this.wait();
7155                    } catch (InterruptedException e) {
7156                    }
7157                }
7158            }
7159        }
7160
7161        mUsageStatsService.shutdown();
7162        mBatteryStatsService.shutdown();
7163
7164        return timedout;
7165    }
7166
7167    public final void activitySlept(IBinder token) {
7168        if (localLOGV) Slog.v(
7169            TAG, "Activity slept: token=" + token);
7170
7171        ActivityRecord r = null;
7172
7173        final long origId = Binder.clearCallingIdentity();
7174
7175        synchronized (this) {
7176            r = mMainStack.isInStackLocked(token);
7177            if (r != null) {
7178                mMainStack.activitySleptLocked(r);
7179            }
7180        }
7181
7182        Binder.restoreCallingIdentity(origId);
7183    }
7184
7185    private void comeOutOfSleepIfNeededLocked() {
7186        if (!mWentToSleep && !mLockScreenShown) {
7187            if (mSleeping) {
7188                mSleeping = false;
7189                mMainStack.awakeFromSleepingLocked();
7190                mMainStack.resumeTopActivityLocked(null);
7191            }
7192        }
7193    }
7194
7195    public void wakingUp() {
7196        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7197                != PackageManager.PERMISSION_GRANTED) {
7198            throw new SecurityException("Requires permission "
7199                    + android.Manifest.permission.DEVICE_POWER);
7200        }
7201
7202        synchronized(this) {
7203            mWentToSleep = false;
7204            updateEventDispatchingLocked();
7205            comeOutOfSleepIfNeededLocked();
7206        }
7207    }
7208
7209    private void updateEventDispatchingLocked() {
7210        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7211    }
7212
7213    public void setLockScreenShown(boolean shown) {
7214        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7215                != PackageManager.PERMISSION_GRANTED) {
7216            throw new SecurityException("Requires permission "
7217                    + android.Manifest.permission.DEVICE_POWER);
7218        }
7219
7220        synchronized(this) {
7221            mLockScreenShown = shown;
7222            comeOutOfSleepIfNeededLocked();
7223        }
7224    }
7225
7226    public void stopAppSwitches() {
7227        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7228                != PackageManager.PERMISSION_GRANTED) {
7229            throw new SecurityException("Requires permission "
7230                    + android.Manifest.permission.STOP_APP_SWITCHES);
7231        }
7232
7233        synchronized(this) {
7234            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7235                    + APP_SWITCH_DELAY_TIME;
7236            mDidAppSwitch = false;
7237            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7238            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7239            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7240        }
7241    }
7242
7243    public void resumeAppSwitches() {
7244        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7245                != PackageManager.PERMISSION_GRANTED) {
7246            throw new SecurityException("Requires permission "
7247                    + android.Manifest.permission.STOP_APP_SWITCHES);
7248        }
7249
7250        synchronized(this) {
7251            // Note that we don't execute any pending app switches... we will
7252            // let those wait until either the timeout, or the next start
7253            // activity request.
7254            mAppSwitchesAllowedTime = 0;
7255        }
7256    }
7257
7258    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7259            String name) {
7260        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7261            return true;
7262        }
7263
7264        final int perm = checkComponentPermission(
7265                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7266                callingUid, -1, true);
7267        if (perm == PackageManager.PERMISSION_GRANTED) {
7268            return true;
7269        }
7270
7271        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7272        return false;
7273    }
7274
7275    public void setDebugApp(String packageName, boolean waitForDebugger,
7276            boolean persistent) {
7277        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7278                "setDebugApp()");
7279
7280        // Note that this is not really thread safe if there are multiple
7281        // callers into it at the same time, but that's not a situation we
7282        // care about.
7283        if (persistent) {
7284            final ContentResolver resolver = mContext.getContentResolver();
7285            Settings.System.putString(
7286                resolver, Settings.System.DEBUG_APP,
7287                packageName);
7288            Settings.System.putInt(
7289                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7290                waitForDebugger ? 1 : 0);
7291        }
7292
7293        synchronized (this) {
7294            if (!persistent) {
7295                mOrigDebugApp = mDebugApp;
7296                mOrigWaitForDebugger = mWaitForDebugger;
7297            }
7298            mDebugApp = packageName;
7299            mWaitForDebugger = waitForDebugger;
7300            mDebugTransient = !persistent;
7301            if (packageName != null) {
7302                final long origId = Binder.clearCallingIdentity();
7303                forceStopPackageLocked(packageName, -1, false, false, true, true,
7304                        UserHandle.USER_ALL);
7305                Binder.restoreCallingIdentity(origId);
7306            }
7307        }
7308    }
7309
7310    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7311        synchronized (this) {
7312            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7313            if (!isDebuggable) {
7314                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7315                    throw new SecurityException("Process not debuggable: " + app.packageName);
7316                }
7317            }
7318
7319            mOpenGlTraceApp = processName;
7320        }
7321    }
7322
7323    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7324            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7325        synchronized (this) {
7326            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7327            if (!isDebuggable) {
7328                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7329                    throw new SecurityException("Process not debuggable: " + app.packageName);
7330                }
7331            }
7332            mProfileApp = processName;
7333            mProfileFile = profileFile;
7334            if (mProfileFd != null) {
7335                try {
7336                    mProfileFd.close();
7337                } catch (IOException e) {
7338                }
7339                mProfileFd = null;
7340            }
7341            mProfileFd = profileFd;
7342            mProfileType = 0;
7343            mAutoStopProfiler = autoStopProfiler;
7344        }
7345    }
7346
7347    public void setAlwaysFinish(boolean enabled) {
7348        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7349                "setAlwaysFinish()");
7350
7351        Settings.System.putInt(
7352                mContext.getContentResolver(),
7353                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7354
7355        synchronized (this) {
7356            mAlwaysFinishActivities = enabled;
7357        }
7358    }
7359
7360    public void setActivityController(IActivityController controller) {
7361        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7362                "setActivityController()");
7363        synchronized (this) {
7364            mController = controller;
7365        }
7366    }
7367
7368    public boolean isUserAMonkey() {
7369        // For now the fact that there is a controller implies
7370        // we have a monkey.
7371        synchronized (this) {
7372            return mController != null;
7373        }
7374    }
7375
7376    public void registerProcessObserver(IProcessObserver observer) {
7377        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7378                "registerProcessObserver()");
7379        synchronized (this) {
7380            mProcessObservers.register(observer);
7381        }
7382    }
7383
7384    public void unregisterProcessObserver(IProcessObserver observer) {
7385        synchronized (this) {
7386            mProcessObservers.unregister(observer);
7387        }
7388    }
7389
7390    public void setImmersive(IBinder token, boolean immersive) {
7391        synchronized(this) {
7392            ActivityRecord r = mMainStack.isInStackLocked(token);
7393            if (r == null) {
7394                throw new IllegalArgumentException();
7395            }
7396            r.immersive = immersive;
7397        }
7398    }
7399
7400    public boolean isImmersive(IBinder token) {
7401        synchronized (this) {
7402            ActivityRecord r = mMainStack.isInStackLocked(token);
7403            if (r == null) {
7404                throw new IllegalArgumentException();
7405            }
7406            return r.immersive;
7407        }
7408    }
7409
7410    public boolean isTopActivityImmersive() {
7411        enforceNotIsolatedCaller("startActivity");
7412        synchronized (this) {
7413            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7414            return (r != null) ? r.immersive : false;
7415        }
7416    }
7417
7418    public final void enterSafeMode() {
7419        synchronized(this) {
7420            // It only makes sense to do this before the system is ready
7421            // and started launching other packages.
7422            if (!mSystemReady) {
7423                try {
7424                    AppGlobals.getPackageManager().enterSafeMode();
7425                } catch (RemoteException e) {
7426                }
7427            }
7428        }
7429    }
7430
7431    public final void showSafeModeOverlay() {
7432        View v = LayoutInflater.from(mContext).inflate(
7433                com.android.internal.R.layout.safe_mode, null);
7434        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7435        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7436        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7437        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7438        lp.gravity = Gravity.BOTTOM | Gravity.START;
7439        lp.format = v.getBackground().getOpacity();
7440        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7441                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7442        ((WindowManager)mContext.getSystemService(
7443                Context.WINDOW_SERVICE)).addView(v, lp);
7444    }
7445
7446    public void noteWakeupAlarm(IIntentSender sender) {
7447        if (!(sender instanceof PendingIntentRecord)) {
7448            return;
7449        }
7450        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7451        synchronized (stats) {
7452            if (mBatteryStatsService.isOnBattery()) {
7453                mBatteryStatsService.enforceCallingPermission();
7454                PendingIntentRecord rec = (PendingIntentRecord)sender;
7455                int MY_UID = Binder.getCallingUid();
7456                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7457                BatteryStatsImpl.Uid.Pkg pkg =
7458                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7459                pkg.incWakeupsLocked();
7460            }
7461        }
7462    }
7463
7464    public boolean killPids(int[] pids, String pReason, boolean secure) {
7465        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7466            throw new SecurityException("killPids only available to the system");
7467        }
7468        String reason = (pReason == null) ? "Unknown" : pReason;
7469        // XXX Note: don't acquire main activity lock here, because the window
7470        // manager calls in with its locks held.
7471
7472        boolean killed = false;
7473        synchronized (mPidsSelfLocked) {
7474            int[] types = new int[pids.length];
7475            int worstType = 0;
7476            for (int i=0; i<pids.length; i++) {
7477                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7478                if (proc != null) {
7479                    int type = proc.setAdj;
7480                    types[i] = type;
7481                    if (type > worstType) {
7482                        worstType = type;
7483                    }
7484                }
7485            }
7486
7487            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7488            // then constrain it so we will kill all hidden procs.
7489            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7490                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7491                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7492            }
7493
7494            // If this is not a secure call, don't let it kill processes that
7495            // are important.
7496            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7497                worstType = ProcessList.SERVICE_ADJ;
7498            }
7499
7500            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7501            for (int i=0; i<pids.length; i++) {
7502                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7503                if (proc == null) {
7504                    continue;
7505                }
7506                int adj = proc.setAdj;
7507                if (adj >= worstType && !proc.killedBackground) {
7508                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7509                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7510                            proc.processName, adj, reason);
7511                    killed = true;
7512                    proc.killedBackground = true;
7513                    Process.killProcessQuiet(pids[i]);
7514                }
7515            }
7516        }
7517        return killed;
7518    }
7519
7520    @Override
7521    public boolean killProcessesBelowForeground(String reason) {
7522        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7523            throw new SecurityException("killProcessesBelowForeground() only available to system");
7524        }
7525
7526        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7527    }
7528
7529    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7530        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7531            throw new SecurityException("killProcessesBelowAdj() only available to system");
7532        }
7533
7534        boolean killed = false;
7535        synchronized (mPidsSelfLocked) {
7536            final int size = mPidsSelfLocked.size();
7537            for (int i = 0; i < size; i++) {
7538                final int pid = mPidsSelfLocked.keyAt(i);
7539                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7540                if (proc == null) continue;
7541
7542                final int adj = proc.setAdj;
7543                if (adj > belowAdj && !proc.killedBackground) {
7544                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7545                    EventLog.writeEvent(
7546                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7547                    killed = true;
7548                    proc.killedBackground = true;
7549                    Process.killProcessQuiet(pid);
7550                }
7551            }
7552        }
7553        return killed;
7554    }
7555
7556    public final void startRunning(String pkg, String cls, String action,
7557            String data) {
7558        synchronized(this) {
7559            if (mStartRunning) {
7560                return;
7561            }
7562            mStartRunning = true;
7563            mTopComponent = pkg != null && cls != null
7564                    ? new ComponentName(pkg, cls) : null;
7565            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7566            mTopData = data;
7567            if (!mSystemReady) {
7568                return;
7569            }
7570        }
7571
7572        systemReady(null);
7573    }
7574
7575    private void retrieveSettings() {
7576        final ContentResolver resolver = mContext.getContentResolver();
7577        String debugApp = Settings.System.getString(
7578            resolver, Settings.System.DEBUG_APP);
7579        boolean waitForDebugger = Settings.System.getInt(
7580            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7581        boolean alwaysFinishActivities = Settings.System.getInt(
7582            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7583
7584        Configuration configuration = new Configuration();
7585        Settings.System.getConfiguration(resolver, configuration);
7586
7587        synchronized (this) {
7588            mDebugApp = mOrigDebugApp = debugApp;
7589            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7590            mAlwaysFinishActivities = alwaysFinishActivities;
7591            // This happens before any activities are started, so we can
7592            // change mConfiguration in-place.
7593            updateConfigurationLocked(configuration, null, false, true);
7594            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7595        }
7596    }
7597
7598    public boolean testIsSystemReady() {
7599        // no need to synchronize(this) just to read & return the value
7600        return mSystemReady;
7601    }
7602
7603    private static File getCalledPreBootReceiversFile() {
7604        File dataDir = Environment.getDataDirectory();
7605        File systemDir = new File(dataDir, "system");
7606        File fname = new File(systemDir, "called_pre_boots.dat");
7607        return fname;
7608    }
7609
7610    static final int LAST_DONE_VERSION = 10000;
7611
7612    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7613        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7614        File file = getCalledPreBootReceiversFile();
7615        FileInputStream fis = null;
7616        try {
7617            fis = new FileInputStream(file);
7618            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7619            int fvers = dis.readInt();
7620            if (fvers == LAST_DONE_VERSION) {
7621                String vers = dis.readUTF();
7622                String codename = dis.readUTF();
7623                String build = dis.readUTF();
7624                if (android.os.Build.VERSION.RELEASE.equals(vers)
7625                        && android.os.Build.VERSION.CODENAME.equals(codename)
7626                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7627                    int num = dis.readInt();
7628                    while (num > 0) {
7629                        num--;
7630                        String pkg = dis.readUTF();
7631                        String cls = dis.readUTF();
7632                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7633                    }
7634                }
7635            }
7636        } catch (FileNotFoundException e) {
7637        } catch (IOException e) {
7638            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7639        } finally {
7640            if (fis != null) {
7641                try {
7642                    fis.close();
7643                } catch (IOException e) {
7644                }
7645            }
7646        }
7647        return lastDoneReceivers;
7648    }
7649
7650    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7651        File file = getCalledPreBootReceiversFile();
7652        FileOutputStream fos = null;
7653        DataOutputStream dos = null;
7654        try {
7655            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7656            fos = new FileOutputStream(file);
7657            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7658            dos.writeInt(LAST_DONE_VERSION);
7659            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7660            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7661            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7662            dos.writeInt(list.size());
7663            for (int i=0; i<list.size(); i++) {
7664                dos.writeUTF(list.get(i).getPackageName());
7665                dos.writeUTF(list.get(i).getClassName());
7666            }
7667        } catch (IOException e) {
7668            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7669            file.delete();
7670        } finally {
7671            FileUtils.sync(fos);
7672            if (dos != null) {
7673                try {
7674                    dos.close();
7675                } catch (IOException e) {
7676                    // TODO Auto-generated catch block
7677                    e.printStackTrace();
7678                }
7679            }
7680        }
7681    }
7682
7683    public void systemReady(final Runnable goingCallback) {
7684        synchronized(this) {
7685            if (mSystemReady) {
7686                if (goingCallback != null) goingCallback.run();
7687                return;
7688            }
7689
7690            // Check to see if there are any update receivers to run.
7691            if (!mDidUpdate) {
7692                if (mWaitingUpdate) {
7693                    return;
7694                }
7695                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7696                List<ResolveInfo> ris = null;
7697                try {
7698                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7699                            intent, null, 0, 0);
7700                } catch (RemoteException e) {
7701                }
7702                if (ris != null) {
7703                    for (int i=ris.size()-1; i>=0; i--) {
7704                        if ((ris.get(i).activityInfo.applicationInfo.flags
7705                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7706                            ris.remove(i);
7707                        }
7708                    }
7709                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7710
7711                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7712
7713                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7714                    for (int i=0; i<ris.size(); i++) {
7715                        ActivityInfo ai = ris.get(i).activityInfo;
7716                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7717                        if (lastDoneReceivers.contains(comp)) {
7718                            ris.remove(i);
7719                            i--;
7720                        }
7721                    }
7722
7723                    final int[] users = getUsersLocked();
7724                    for (int i=0; i<ris.size(); i++) {
7725                        ActivityInfo ai = ris.get(i).activityInfo;
7726                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7727                        doneReceivers.add(comp);
7728                        intent.setComponent(comp);
7729                        for (int j=0; j<users.length; j++) {
7730                            IIntentReceiver finisher = null;
7731                            if (i == ris.size()-1 && j == users.length-1) {
7732                                finisher = new IIntentReceiver.Stub() {
7733                                    public void performReceive(Intent intent, int resultCode,
7734                                            String data, Bundle extras, boolean ordered,
7735                                            boolean sticky, int sendingUser) {
7736                                        // The raw IIntentReceiver interface is called
7737                                        // with the AM lock held, so redispatch to
7738                                        // execute our code without the lock.
7739                                        mHandler.post(new Runnable() {
7740                                            public void run() {
7741                                                synchronized (ActivityManagerService.this) {
7742                                                    mDidUpdate = true;
7743                                                }
7744                                                writeLastDonePreBootReceivers(doneReceivers);
7745                                                showBootMessage(mContext.getText(
7746                                                        R.string.android_upgrading_complete),
7747                                                        false);
7748                                                systemReady(goingCallback);
7749                                            }
7750                                        });
7751                                    }
7752                                };
7753                            }
7754                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
7755                                    + " for user " + users[j]);
7756                            broadcastIntentLocked(null, null, intent, null, finisher,
7757                                    0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7758                                    users[j]);
7759                            if (finisher != null) {
7760                                mWaitingUpdate = true;
7761                            }
7762                        }
7763                    }
7764                }
7765                if (mWaitingUpdate) {
7766                    return;
7767                }
7768                mDidUpdate = true;
7769            }
7770
7771            mSystemReady = true;
7772            if (!mStartRunning) {
7773                return;
7774            }
7775        }
7776
7777        ArrayList<ProcessRecord> procsToKill = null;
7778        synchronized(mPidsSelfLocked) {
7779            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7780                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7781                if (!isAllowedWhileBooting(proc.info)){
7782                    if (procsToKill == null) {
7783                        procsToKill = new ArrayList<ProcessRecord>();
7784                    }
7785                    procsToKill.add(proc);
7786                }
7787            }
7788        }
7789
7790        synchronized(this) {
7791            if (procsToKill != null) {
7792                for (int i=procsToKill.size()-1; i>=0; i--) {
7793                    ProcessRecord proc = procsToKill.get(i);
7794                    Slog.i(TAG, "Removing system update proc: " + proc);
7795                    removeProcessLocked(proc, true, false, "system update done");
7796                }
7797            }
7798
7799            // Now that we have cleaned up any update processes, we
7800            // are ready to start launching real processes and know that
7801            // we won't trample on them any more.
7802            mProcessesReady = true;
7803        }
7804
7805        Slog.i(TAG, "System now ready");
7806        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7807            SystemClock.uptimeMillis());
7808
7809        synchronized(this) {
7810            // Make sure we have no pre-ready processes sitting around.
7811
7812            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7813                ResolveInfo ri = mContext.getPackageManager()
7814                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7815                                STOCK_PM_FLAGS);
7816                CharSequence errorMsg = null;
7817                if (ri != null) {
7818                    ActivityInfo ai = ri.activityInfo;
7819                    ApplicationInfo app = ai.applicationInfo;
7820                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7821                        mTopAction = Intent.ACTION_FACTORY_TEST;
7822                        mTopData = null;
7823                        mTopComponent = new ComponentName(app.packageName,
7824                                ai.name);
7825                    } else {
7826                        errorMsg = mContext.getResources().getText(
7827                                com.android.internal.R.string.factorytest_not_system);
7828                    }
7829                } else {
7830                    errorMsg = mContext.getResources().getText(
7831                            com.android.internal.R.string.factorytest_no_action);
7832                }
7833                if (errorMsg != null) {
7834                    mTopAction = null;
7835                    mTopData = null;
7836                    mTopComponent = null;
7837                    Message msg = Message.obtain();
7838                    msg.what = SHOW_FACTORY_ERROR_MSG;
7839                    msg.getData().putCharSequence("msg", errorMsg);
7840                    mHandler.sendMessage(msg);
7841                }
7842            }
7843        }
7844
7845        retrieveSettings();
7846
7847        if (goingCallback != null) goingCallback.run();
7848
7849        synchronized (this) {
7850            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7851                try {
7852                    List apps = AppGlobals.getPackageManager().
7853                        getPersistentApplications(STOCK_PM_FLAGS);
7854                    if (apps != null) {
7855                        int N = apps.size();
7856                        int i;
7857                        for (i=0; i<N; i++) {
7858                            ApplicationInfo info
7859                                = (ApplicationInfo)apps.get(i);
7860                            if (info != null &&
7861                                    !info.packageName.equals("android")) {
7862                                addAppLocked(info, false);
7863                            }
7864                        }
7865                    }
7866                } catch (RemoteException ex) {
7867                    // pm is in same process, this will never happen.
7868                }
7869            }
7870
7871            // Start up initial activity.
7872            mBooting = true;
7873
7874            try {
7875                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7876                    Message msg = Message.obtain();
7877                    msg.what = SHOW_UID_ERROR_MSG;
7878                    mHandler.sendMessage(msg);
7879                }
7880            } catch (RemoteException e) {
7881            }
7882
7883            long ident = Binder.clearCallingIdentity();
7884            try {
7885                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
7886                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
7887                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7888                broadcastIntentLocked(null, null, intent,
7889                        null, null, 0, null, null, null,
7890                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
7891            } finally {
7892                Binder.restoreCallingIdentity(ident);
7893            }
7894            mMainStack.resumeTopActivityLocked(null);
7895            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
7896        }
7897    }
7898
7899    private boolean makeAppCrashingLocked(ProcessRecord app,
7900            String shortMsg, String longMsg, String stackTrace) {
7901        app.crashing = true;
7902        app.crashingReport = generateProcessError(app,
7903                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7904        startAppProblemLocked(app);
7905        app.stopFreezingAllLocked();
7906        return handleAppCrashLocked(app);
7907    }
7908
7909    private void makeAppNotRespondingLocked(ProcessRecord app,
7910            String activity, String shortMsg, String longMsg) {
7911        app.notResponding = true;
7912        app.notRespondingReport = generateProcessError(app,
7913                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7914                activity, shortMsg, longMsg, null);
7915        startAppProblemLocked(app);
7916        app.stopFreezingAllLocked();
7917    }
7918
7919    /**
7920     * Generate a process error record, suitable for attachment to a ProcessRecord.
7921     *
7922     * @param app The ProcessRecord in which the error occurred.
7923     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7924     *                      ActivityManager.AppErrorStateInfo
7925     * @param activity The activity associated with the crash, if known.
7926     * @param shortMsg Short message describing the crash.
7927     * @param longMsg Long message describing the crash.
7928     * @param stackTrace Full crash stack trace, may be null.
7929     *
7930     * @return Returns a fully-formed AppErrorStateInfo record.
7931     */
7932    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7933            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7934        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7935
7936        report.condition = condition;
7937        report.processName = app.processName;
7938        report.pid = app.pid;
7939        report.uid = app.info.uid;
7940        report.tag = activity;
7941        report.shortMsg = shortMsg;
7942        report.longMsg = longMsg;
7943        report.stackTrace = stackTrace;
7944
7945        return report;
7946    }
7947
7948    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7949        synchronized (this) {
7950            app.crashing = false;
7951            app.crashingReport = null;
7952            app.notResponding = false;
7953            app.notRespondingReport = null;
7954            if (app.anrDialog == fromDialog) {
7955                app.anrDialog = null;
7956            }
7957            if (app.waitDialog == fromDialog) {
7958                app.waitDialog = null;
7959            }
7960            if (app.pid > 0 && app.pid != MY_PID) {
7961                handleAppCrashLocked(app);
7962                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7963                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7964                        app.processName, app.setAdj, "user's request after error");
7965                Process.killProcessQuiet(app.pid);
7966            }
7967        }
7968    }
7969
7970    private boolean handleAppCrashLocked(ProcessRecord app) {
7971        if (mHeadless) {
7972            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7973            return false;
7974        }
7975        long now = SystemClock.uptimeMillis();
7976
7977        Long crashTime;
7978        if (!app.isolated) {
7979            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7980        } else {
7981            crashTime = null;
7982        }
7983        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7984            // This process loses!
7985            Slog.w(TAG, "Process " + app.info.processName
7986                    + " has crashed too many times: killing!");
7987            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7988                    app.info.processName, app.uid);
7989            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7990                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7991                if (r.app == app) {
7992                    Slog.w(TAG, "  Force finishing activity "
7993                        + r.intent.getComponent().flattenToShortString());
7994                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
7995                            null, "crashed", false);
7996                }
7997            }
7998            if (!app.persistent) {
7999                // We don't want to start this process again until the user
8000                // explicitly does so...  but for persistent process, we really
8001                // need to keep it running.  If a persistent process is actually
8002                // repeatedly crashing, then badness for everyone.
8003                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
8004                        app.info.processName);
8005                if (!app.isolated) {
8006                    // XXX We don't have a way to mark isolated processes
8007                    // as bad, since they don't have a peristent identity.
8008                    mBadProcesses.put(app.info.processName, app.uid, now);
8009                    mProcessCrashTimes.remove(app.info.processName, app.uid);
8010                }
8011                app.bad = true;
8012                app.removed = true;
8013                // Don't let services in this process be restarted and potentially
8014                // annoy the user repeatedly.  Unless it is persistent, since those
8015                // processes run critical code.
8016                removeProcessLocked(app, false, false, "crash");
8017                mMainStack.resumeTopActivityLocked(null);
8018                return false;
8019            }
8020            mMainStack.resumeTopActivityLocked(null);
8021        } else {
8022            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
8023            if (r != null && r.app == app) {
8024                // If the top running activity is from this crashing
8025                // process, then terminate it to avoid getting in a loop.
8026                Slog.w(TAG, "  Force finishing activity "
8027                        + r.intent.getComponent().flattenToShortString());
8028                int index = mMainStack.indexOfActivityLocked(r);
8029                r.stack.finishActivityLocked(r, index,
8030                        Activity.RESULT_CANCELED, null, "crashed", false);
8031                // Also terminate any activities below it that aren't yet
8032                // stopped, to avoid a situation where one will get
8033                // re-start our crashing activity once it gets resumed again.
8034                index--;
8035                if (index >= 0) {
8036                    r = (ActivityRecord)mMainStack.mHistory.get(index);
8037                    if (r.state == ActivityState.RESUMED
8038                            || r.state == ActivityState.PAUSING
8039                            || r.state == ActivityState.PAUSED) {
8040                        if (!r.isHomeActivity || mHomeProcess != r.app) {
8041                            Slog.w(TAG, "  Force finishing activity "
8042                                    + r.intent.getComponent().flattenToShortString());
8043                            r.stack.finishActivityLocked(r, index,
8044                                    Activity.RESULT_CANCELED, null, "crashed", false);
8045                        }
8046                    }
8047                }
8048            }
8049        }
8050
8051        // Bump up the crash count of any services currently running in the proc.
8052        if (app.services.size() != 0) {
8053            // Any services running in the application need to be placed
8054            // back in the pending list.
8055            Iterator<ServiceRecord> it = app.services.iterator();
8056            while (it.hasNext()) {
8057                ServiceRecord sr = it.next();
8058                sr.crashCount++;
8059            }
8060        }
8061
8062        // If the crashing process is what we consider to be the "home process" and it has been
8063        // replaced by a third-party app, clear the package preferred activities from packages
8064        // with a home activity running in the process to prevent a repeatedly crashing app
8065        // from blocking the user to manually clear the list.
8066        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8067                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8068            Iterator it = mHomeProcess.activities.iterator();
8069            while (it.hasNext()) {
8070                ActivityRecord r = (ActivityRecord)it.next();
8071                if (r.isHomeActivity) {
8072                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8073                    try {
8074                        ActivityThread.getPackageManager()
8075                                .clearPackagePreferredActivities(r.packageName);
8076                    } catch (RemoteException c) {
8077                        // pm is in same process, this will never happen.
8078                    }
8079                }
8080            }
8081        }
8082
8083        if (!app.isolated) {
8084            // XXX Can't keep track of crash times for isolated processes,
8085            // because they don't have a perisistent identity.
8086            mProcessCrashTimes.put(app.info.processName, app.uid, now);
8087        }
8088
8089        return true;
8090    }
8091
8092    void startAppProblemLocked(ProcessRecord app) {
8093        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8094                mContext, app.info.packageName, app.info.flags);
8095        skipCurrentReceiverLocked(app);
8096    }
8097
8098    void skipCurrentReceiverLocked(ProcessRecord app) {
8099        for (BroadcastQueue queue : mBroadcastQueues) {
8100            queue.skipCurrentReceiverLocked(app);
8101        }
8102    }
8103
8104    /**
8105     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8106     * The application process will exit immediately after this call returns.
8107     * @param app object of the crashing app, null for the system server
8108     * @param crashInfo describing the exception
8109     */
8110    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8111        ProcessRecord r = findAppProcess(app, "Crash");
8112        final String processName = app == null ? "system_server"
8113                : (r == null ? "unknown" : r.processName);
8114
8115        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8116                processName,
8117                r == null ? -1 : r.info.flags,
8118                crashInfo.exceptionClassName,
8119                crashInfo.exceptionMessage,
8120                crashInfo.throwFileName,
8121                crashInfo.throwLineNumber);
8122
8123        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
8124
8125        crashApplication(r, crashInfo);
8126    }
8127
8128    public void handleApplicationStrictModeViolation(
8129            IBinder app,
8130            int violationMask,
8131            StrictMode.ViolationInfo info) {
8132        ProcessRecord r = findAppProcess(app, "StrictMode");
8133        if (r == null) {
8134            return;
8135        }
8136
8137        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8138            Integer stackFingerprint = info.hashCode();
8139            boolean logIt = true;
8140            synchronized (mAlreadyLoggedViolatedStacks) {
8141                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8142                    logIt = false;
8143                    // TODO: sub-sample into EventLog for these, with
8144                    // the info.durationMillis?  Then we'd get
8145                    // the relative pain numbers, without logging all
8146                    // the stack traces repeatedly.  We'd want to do
8147                    // likewise in the client code, which also does
8148                    // dup suppression, before the Binder call.
8149                } else {
8150                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8151                        mAlreadyLoggedViolatedStacks.clear();
8152                    }
8153                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8154                }
8155            }
8156            if (logIt) {
8157                logStrictModeViolationToDropBox(r, info);
8158            }
8159        }
8160
8161        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8162            AppErrorResult result = new AppErrorResult();
8163            synchronized (this) {
8164                final long origId = Binder.clearCallingIdentity();
8165
8166                Message msg = Message.obtain();
8167                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8168                HashMap<String, Object> data = new HashMap<String, Object>();
8169                data.put("result", result);
8170                data.put("app", r);
8171                data.put("violationMask", violationMask);
8172                data.put("info", info);
8173                msg.obj = data;
8174                mHandler.sendMessage(msg);
8175
8176                Binder.restoreCallingIdentity(origId);
8177            }
8178            int res = result.get();
8179            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8180        }
8181    }
8182
8183    // Depending on the policy in effect, there could be a bunch of
8184    // these in quick succession so we try to batch these together to
8185    // minimize disk writes, number of dropbox entries, and maximize
8186    // compression, by having more fewer, larger records.
8187    private void logStrictModeViolationToDropBox(
8188            ProcessRecord process,
8189            StrictMode.ViolationInfo info) {
8190        if (info == null) {
8191            return;
8192        }
8193        final boolean isSystemApp = process == null ||
8194                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8195                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8196        final String processName = process == null ? "unknown" : process.processName;
8197        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8198        final DropBoxManager dbox = (DropBoxManager)
8199                mContext.getSystemService(Context.DROPBOX_SERVICE);
8200
8201        // Exit early if the dropbox isn't configured to accept this report type.
8202        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8203
8204        boolean bufferWasEmpty;
8205        boolean needsFlush;
8206        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8207        synchronized (sb) {
8208            bufferWasEmpty = sb.length() == 0;
8209            appendDropBoxProcessHeaders(process, processName, sb);
8210            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8211            sb.append("System-App: ").append(isSystemApp).append("\n");
8212            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8213            if (info.violationNumThisLoop != 0) {
8214                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8215            }
8216            if (info.numAnimationsRunning != 0) {
8217                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8218            }
8219            if (info.broadcastIntentAction != null) {
8220                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8221            }
8222            if (info.durationMillis != -1) {
8223                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8224            }
8225            if (info.numInstances != -1) {
8226                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8227            }
8228            if (info.tags != null) {
8229                for (String tag : info.tags) {
8230                    sb.append("Span-Tag: ").append(tag).append("\n");
8231                }
8232            }
8233            sb.append("\n");
8234            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8235                sb.append(info.crashInfo.stackTrace);
8236            }
8237            sb.append("\n");
8238
8239            // Only buffer up to ~64k.  Various logging bits truncate
8240            // things at 128k.
8241            needsFlush = (sb.length() > 64 * 1024);
8242        }
8243
8244        // Flush immediately if the buffer's grown too large, or this
8245        // is a non-system app.  Non-system apps are isolated with a
8246        // different tag & policy and not batched.
8247        //
8248        // Batching is useful during internal testing with
8249        // StrictMode settings turned up high.  Without batching,
8250        // thousands of separate files could be created on boot.
8251        if (!isSystemApp || needsFlush) {
8252            new Thread("Error dump: " + dropboxTag) {
8253                @Override
8254                public void run() {
8255                    String report;
8256                    synchronized (sb) {
8257                        report = sb.toString();
8258                        sb.delete(0, sb.length());
8259                        sb.trimToSize();
8260                    }
8261                    if (report.length() != 0) {
8262                        dbox.addText(dropboxTag, report);
8263                    }
8264                }
8265            }.start();
8266            return;
8267        }
8268
8269        // System app batching:
8270        if (!bufferWasEmpty) {
8271            // An existing dropbox-writing thread is outstanding, so
8272            // we don't need to start it up.  The existing thread will
8273            // catch the buffer appends we just did.
8274            return;
8275        }
8276
8277        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8278        // (After this point, we shouldn't access AMS internal data structures.)
8279        new Thread("Error dump: " + dropboxTag) {
8280            @Override
8281            public void run() {
8282                // 5 second sleep to let stacks arrive and be batched together
8283                try {
8284                    Thread.sleep(5000);  // 5 seconds
8285                } catch (InterruptedException e) {}
8286
8287                String errorReport;
8288                synchronized (mStrictModeBuffer) {
8289                    errorReport = mStrictModeBuffer.toString();
8290                    if (errorReport.length() == 0) {
8291                        return;
8292                    }
8293                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8294                    mStrictModeBuffer.trimToSize();
8295                }
8296                dbox.addText(dropboxTag, errorReport);
8297            }
8298        }.start();
8299    }
8300
8301    /**
8302     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8303     * @param app object of the crashing app, null for the system server
8304     * @param tag reported by the caller
8305     * @param crashInfo describing the context of the error
8306     * @return true if the process should exit immediately (WTF is fatal)
8307     */
8308    public boolean handleApplicationWtf(IBinder app, String tag,
8309            ApplicationErrorReport.CrashInfo crashInfo) {
8310        ProcessRecord r = findAppProcess(app, "WTF");
8311        final String processName = app == null ? "system_server"
8312                : (r == null ? "unknown" : r.processName);
8313
8314        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8315                processName,
8316                r == null ? -1 : r.info.flags,
8317                tag, crashInfo.exceptionMessage);
8318
8319        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8320
8321        if (r != null && r.pid != Process.myPid() &&
8322                Settings.Secure.getInt(mContext.getContentResolver(),
8323                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8324            crashApplication(r, crashInfo);
8325            return true;
8326        } else {
8327            return false;
8328        }
8329    }
8330
8331    /**
8332     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8333     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8334     */
8335    private ProcessRecord findAppProcess(IBinder app, String reason) {
8336        if (app == null) {
8337            return null;
8338        }
8339
8340        synchronized (this) {
8341            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8342                final int NA = apps.size();
8343                for (int ia=0; ia<NA; ia++) {
8344                    ProcessRecord p = apps.valueAt(ia);
8345                    if (p.thread != null && p.thread.asBinder() == app) {
8346                        return p;
8347                    }
8348                }
8349            }
8350
8351            Slog.w(TAG, "Can't find mystery application for " + reason
8352                    + " from pid=" + Binder.getCallingPid()
8353                    + " uid=" + Binder.getCallingUid() + ": " + app);
8354            return null;
8355        }
8356    }
8357
8358    /**
8359     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8360     * to append various headers to the dropbox log text.
8361     */
8362    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8363            StringBuilder sb) {
8364        // Watchdog thread ends up invoking this function (with
8365        // a null ProcessRecord) to add the stack file to dropbox.
8366        // Do not acquire a lock on this (am) in such cases, as it
8367        // could cause a potential deadlock, if and when watchdog
8368        // is invoked due to unavailability of lock on am and it
8369        // would prevent watchdog from killing system_server.
8370        if (process == null) {
8371            sb.append("Process: ").append(processName).append("\n");
8372            return;
8373        }
8374        // Note: ProcessRecord 'process' is guarded by the service
8375        // instance.  (notably process.pkgList, which could otherwise change
8376        // concurrently during execution of this method)
8377        synchronized (this) {
8378            sb.append("Process: ").append(processName).append("\n");
8379            int flags = process.info.flags;
8380            IPackageManager pm = AppGlobals.getPackageManager();
8381            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8382            for (String pkg : process.pkgList) {
8383                sb.append("Package: ").append(pkg);
8384                try {
8385                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8386                    if (pi != null) {
8387                        sb.append(" v").append(pi.versionCode);
8388                        if (pi.versionName != null) {
8389                            sb.append(" (").append(pi.versionName).append(")");
8390                        }
8391                    }
8392                } catch (RemoteException e) {
8393                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8394                }
8395                sb.append("\n");
8396            }
8397        }
8398    }
8399
8400    private static String processClass(ProcessRecord process) {
8401        if (process == null || process.pid == MY_PID) {
8402            return "system_server";
8403        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8404            return "system_app";
8405        } else {
8406            return "data_app";
8407        }
8408    }
8409
8410    /**
8411     * Write a description of an error (crash, WTF, ANR) to the drop box.
8412     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8413     * @param process which caused the error, null means the system server
8414     * @param activity which triggered the error, null if unknown
8415     * @param parent activity related to the error, null if unknown
8416     * @param subject line related to the error, null if absent
8417     * @param report in long form describing the error, null if absent
8418     * @param logFile to include in the report, null if none
8419     * @param crashInfo giving an application stack trace, null if absent
8420     */
8421    public void addErrorToDropBox(String eventType,
8422            ProcessRecord process, String processName, ActivityRecord activity,
8423            ActivityRecord parent, String subject,
8424            final String report, final File logFile,
8425            final ApplicationErrorReport.CrashInfo crashInfo) {
8426        // NOTE -- this must never acquire the ActivityManagerService lock,
8427        // otherwise the watchdog may be prevented from resetting the system.
8428
8429        final String dropboxTag = processClass(process) + "_" + eventType;
8430        final DropBoxManager dbox = (DropBoxManager)
8431                mContext.getSystemService(Context.DROPBOX_SERVICE);
8432
8433        // Exit early if the dropbox isn't configured to accept this report type.
8434        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8435
8436        final StringBuilder sb = new StringBuilder(1024);
8437        appendDropBoxProcessHeaders(process, processName, sb);
8438        if (activity != null) {
8439            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8440        }
8441        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8442            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8443        }
8444        if (parent != null && parent != activity) {
8445            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8446        }
8447        if (subject != null) {
8448            sb.append("Subject: ").append(subject).append("\n");
8449        }
8450        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8451        if (Debug.isDebuggerConnected()) {
8452            sb.append("Debugger: Connected\n");
8453        }
8454        sb.append("\n");
8455
8456        // Do the rest in a worker thread to avoid blocking the caller on I/O
8457        // (After this point, we shouldn't access AMS internal data structures.)
8458        Thread worker = new Thread("Error dump: " + dropboxTag) {
8459            @Override
8460            public void run() {
8461                if (report != null) {
8462                    sb.append(report);
8463                }
8464                if (logFile != null) {
8465                    try {
8466                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8467                    } catch (IOException e) {
8468                        Slog.e(TAG, "Error reading " + logFile, e);
8469                    }
8470                }
8471                if (crashInfo != null && crashInfo.stackTrace != null) {
8472                    sb.append(crashInfo.stackTrace);
8473                }
8474
8475                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8476                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8477                if (lines > 0) {
8478                    sb.append("\n");
8479
8480                    // Merge several logcat streams, and take the last N lines
8481                    InputStreamReader input = null;
8482                    try {
8483                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8484                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8485                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8486
8487                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8488                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8489                        input = new InputStreamReader(logcat.getInputStream());
8490
8491                        int num;
8492                        char[] buf = new char[8192];
8493                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8494                    } catch (IOException e) {
8495                        Slog.e(TAG, "Error running logcat", e);
8496                    } finally {
8497                        if (input != null) try { input.close(); } catch (IOException e) {}
8498                    }
8499                }
8500
8501                dbox.addText(dropboxTag, sb.toString());
8502            }
8503        };
8504
8505        if (process == null) {
8506            // If process is null, we are being called from some internal code
8507            // and may be about to die -- run this synchronously.
8508            worker.run();
8509        } else {
8510            worker.start();
8511        }
8512    }
8513
8514    /**
8515     * Bring up the "unexpected error" dialog box for a crashing app.
8516     * Deal with edge cases (intercepts from instrumented applications,
8517     * ActivityController, error intent receivers, that sort of thing).
8518     * @param r the application crashing
8519     * @param crashInfo describing the failure
8520     */
8521    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8522        long timeMillis = System.currentTimeMillis();
8523        String shortMsg = crashInfo.exceptionClassName;
8524        String longMsg = crashInfo.exceptionMessage;
8525        String stackTrace = crashInfo.stackTrace;
8526        if (shortMsg != null && longMsg != null) {
8527            longMsg = shortMsg + ": " + longMsg;
8528        } else if (shortMsg != null) {
8529            longMsg = shortMsg;
8530        }
8531
8532        AppErrorResult result = new AppErrorResult();
8533        synchronized (this) {
8534            if (mController != null) {
8535                try {
8536                    String name = r != null ? r.processName : null;
8537                    int pid = r != null ? r.pid : Binder.getCallingPid();
8538                    if (!mController.appCrashed(name, pid,
8539                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8540                        Slog.w(TAG, "Force-killing crashed app " + name
8541                                + " at watcher's request");
8542                        Process.killProcess(pid);
8543                        return;
8544                    }
8545                } catch (RemoteException e) {
8546                    mController = null;
8547                }
8548            }
8549
8550            final long origId = Binder.clearCallingIdentity();
8551
8552            // If this process is running instrumentation, finish it.
8553            if (r != null && r.instrumentationClass != null) {
8554                Slog.w(TAG, "Error in app " + r.processName
8555                      + " running instrumentation " + r.instrumentationClass + ":");
8556                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8557                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8558                Bundle info = new Bundle();
8559                info.putString("shortMsg", shortMsg);
8560                info.putString("longMsg", longMsg);
8561                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8562                Binder.restoreCallingIdentity(origId);
8563                return;
8564            }
8565
8566            // If we can't identify the process or it's already exceeded its crash quota,
8567            // quit right away without showing a crash dialog.
8568            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8569                Binder.restoreCallingIdentity(origId);
8570                return;
8571            }
8572
8573            Message msg = Message.obtain();
8574            msg.what = SHOW_ERROR_MSG;
8575            HashMap data = new HashMap();
8576            data.put("result", result);
8577            data.put("app", r);
8578            msg.obj = data;
8579            mHandler.sendMessage(msg);
8580
8581            Binder.restoreCallingIdentity(origId);
8582        }
8583
8584        int res = result.get();
8585
8586        Intent appErrorIntent = null;
8587        synchronized (this) {
8588            if (r != null && !r.isolated) {
8589                // XXX Can't keep track of crash time for isolated processes,
8590                // since they don't have a persistent identity.
8591                mProcessCrashTimes.put(r.info.processName, r.uid,
8592                        SystemClock.uptimeMillis());
8593            }
8594            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8595                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8596            }
8597        }
8598
8599        if (appErrorIntent != null) {
8600            try {
8601                mContext.startActivity(appErrorIntent);
8602            } catch (ActivityNotFoundException e) {
8603                Slog.w(TAG, "bug report receiver dissappeared", e);
8604            }
8605        }
8606    }
8607
8608    Intent createAppErrorIntentLocked(ProcessRecord r,
8609            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8610        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8611        if (report == null) {
8612            return null;
8613        }
8614        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8615        result.setComponent(r.errorReportReceiver);
8616        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8617        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8618        return result;
8619    }
8620
8621    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8622            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8623        if (r.errorReportReceiver == null) {
8624            return null;
8625        }
8626
8627        if (!r.crashing && !r.notResponding) {
8628            return null;
8629        }
8630
8631        ApplicationErrorReport report = new ApplicationErrorReport();
8632        report.packageName = r.info.packageName;
8633        report.installerPackageName = r.errorReportReceiver.getPackageName();
8634        report.processName = r.processName;
8635        report.time = timeMillis;
8636        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8637
8638        if (r.crashing) {
8639            report.type = ApplicationErrorReport.TYPE_CRASH;
8640            report.crashInfo = crashInfo;
8641        } else if (r.notResponding) {
8642            report.type = ApplicationErrorReport.TYPE_ANR;
8643            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8644
8645            report.anrInfo.activity = r.notRespondingReport.tag;
8646            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8647            report.anrInfo.info = r.notRespondingReport.longMsg;
8648        }
8649
8650        return report;
8651    }
8652
8653    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8654        enforceNotIsolatedCaller("getProcessesInErrorState");
8655        // assume our apps are happy - lazy create the list
8656        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8657
8658        final boolean allUsers = ActivityManager.checkUidPermission(
8659                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8660                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8661        int userId = UserHandle.getUserId(Binder.getCallingUid());
8662
8663        synchronized (this) {
8664
8665            // iterate across all processes
8666            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8667                ProcessRecord app = mLruProcesses.get(i);
8668                if (!allUsers && app.userId != userId) {
8669                    continue;
8670                }
8671                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8672                    // This one's in trouble, so we'll generate a report for it
8673                    // crashes are higher priority (in case there's a crash *and* an anr)
8674                    ActivityManager.ProcessErrorStateInfo report = null;
8675                    if (app.crashing) {
8676                        report = app.crashingReport;
8677                    } else if (app.notResponding) {
8678                        report = app.notRespondingReport;
8679                    }
8680
8681                    if (report != null) {
8682                        if (errList == null) {
8683                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8684                        }
8685                        errList.add(report);
8686                    } else {
8687                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8688                                " crashing = " + app.crashing +
8689                                " notResponding = " + app.notResponding);
8690                    }
8691                }
8692            }
8693        }
8694
8695        return errList;
8696    }
8697
8698    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8699        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8700            if (currApp != null) {
8701                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8702            }
8703            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8704        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8705            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8706        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8707            if (currApp != null) {
8708                currApp.lru = 0;
8709            }
8710            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8711        } else if (adj >= ProcessList.SERVICE_ADJ) {
8712            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8713        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8714            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8715        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8716            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8717        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8718            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8719        } else {
8720            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8721        }
8722    }
8723
8724    private void fillInProcMemInfo(ProcessRecord app,
8725            ActivityManager.RunningAppProcessInfo outInfo) {
8726        outInfo.pid = app.pid;
8727        outInfo.uid = app.info.uid;
8728        if (mHeavyWeightProcess == app) {
8729            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8730        }
8731        if (app.persistent) {
8732            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8733        }
8734        if (app.hasActivities) {
8735            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8736        }
8737        outInfo.lastTrimLevel = app.trimMemoryLevel;
8738        int adj = app.curAdj;
8739        outInfo.importance = oomAdjToImportance(adj, outInfo);
8740        outInfo.importanceReasonCode = app.adjTypeCode;
8741    }
8742
8743    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8744        enforceNotIsolatedCaller("getRunningAppProcesses");
8745        // Lazy instantiation of list
8746        List<ActivityManager.RunningAppProcessInfo> runList = null;
8747        final boolean allUsers = ActivityManager.checkUidPermission(
8748                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8749                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8750        int userId = UserHandle.getUserId(Binder.getCallingUid());
8751        synchronized (this) {
8752            // Iterate across all processes
8753            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8754                ProcessRecord app = mLruProcesses.get(i);
8755                if (!allUsers && app.userId != userId) {
8756                    continue;
8757                }
8758                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8759                    // Generate process state info for running application
8760                    ActivityManager.RunningAppProcessInfo currApp =
8761                        new ActivityManager.RunningAppProcessInfo(app.processName,
8762                                app.pid, app.getPackageList());
8763                    fillInProcMemInfo(app, currApp);
8764                    if (app.adjSource instanceof ProcessRecord) {
8765                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8766                        currApp.importanceReasonImportance = oomAdjToImportance(
8767                                app.adjSourceOom, null);
8768                    } else if (app.adjSource instanceof ActivityRecord) {
8769                        ActivityRecord r = (ActivityRecord)app.adjSource;
8770                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8771                    }
8772                    if (app.adjTarget instanceof ComponentName) {
8773                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8774                    }
8775                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8776                    //        + " lru=" + currApp.lru);
8777                    if (runList == null) {
8778                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8779                    }
8780                    runList.add(currApp);
8781                }
8782            }
8783        }
8784        return runList;
8785    }
8786
8787    public List<ApplicationInfo> getRunningExternalApplications() {
8788        enforceNotIsolatedCaller("getRunningExternalApplications");
8789        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8790        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8791        if (runningApps != null && runningApps.size() > 0) {
8792            Set<String> extList = new HashSet<String>();
8793            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8794                if (app.pkgList != null) {
8795                    for (String pkg : app.pkgList) {
8796                        extList.add(pkg);
8797                    }
8798                }
8799            }
8800            IPackageManager pm = AppGlobals.getPackageManager();
8801            for (String pkg : extList) {
8802                try {
8803                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8804                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8805                        retList.add(info);
8806                    }
8807                } catch (RemoteException e) {
8808                }
8809            }
8810        }
8811        return retList;
8812    }
8813
8814    @Override
8815    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8816        enforceNotIsolatedCaller("getMyMemoryState");
8817        synchronized (this) {
8818            ProcessRecord proc;
8819            synchronized (mPidsSelfLocked) {
8820                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8821            }
8822            fillInProcMemInfo(proc, outInfo);
8823        }
8824    }
8825
8826    @Override
8827    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8828        if (checkCallingPermission(android.Manifest.permission.DUMP)
8829                != PackageManager.PERMISSION_GRANTED) {
8830            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8831                    + Binder.getCallingPid()
8832                    + ", uid=" + Binder.getCallingUid()
8833                    + " without permission "
8834                    + android.Manifest.permission.DUMP);
8835            return;
8836        }
8837
8838        boolean dumpAll = false;
8839        boolean dumpClient = false;
8840        String dumpPackage = null;
8841
8842        int opti = 0;
8843        while (opti < args.length) {
8844            String opt = args[opti];
8845            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8846                break;
8847            }
8848            opti++;
8849            if ("-a".equals(opt)) {
8850                dumpAll = true;
8851            } else if ("-c".equals(opt)) {
8852                dumpClient = true;
8853            } else if ("-h".equals(opt)) {
8854                pw.println("Activity manager dump options:");
8855                pw.println("  [-a] [-c] [-h] [cmd] ...");
8856                pw.println("  cmd may be one of:");
8857                pw.println("    a[ctivities]: activity stack state");
8858                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8859                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8860                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8861                pw.println("    o[om]: out of memory management");
8862                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8863                pw.println("    provider [COMP_SPEC]: provider client-side state");
8864                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8865                pw.println("    service [COMP_SPEC]: service client-side state");
8866                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8867                pw.println("    all: dump all activities");
8868                pw.println("    top: dump the top activity");
8869                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8870                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8871                pw.println("    a partial substring in a component name, a");
8872                pw.println("    hex object identifier.");
8873                pw.println("  -a: include all available server state.");
8874                pw.println("  -c: include client state.");
8875                return;
8876            } else {
8877                pw.println("Unknown argument: " + opt + "; use -h for help");
8878            }
8879        }
8880
8881        long origId = Binder.clearCallingIdentity();
8882        boolean more = false;
8883        // Is the caller requesting to dump a particular piece of data?
8884        if (opti < args.length) {
8885            String cmd = args[opti];
8886            opti++;
8887            if ("activities".equals(cmd) || "a".equals(cmd)) {
8888                synchronized (this) {
8889                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8890                }
8891            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8892                String[] newArgs;
8893                String name;
8894                if (opti >= args.length) {
8895                    name = null;
8896                    newArgs = EMPTY_STRING_ARRAY;
8897                } else {
8898                    name = args[opti];
8899                    opti++;
8900                    newArgs = new String[args.length - opti];
8901                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8902                            args.length - opti);
8903                }
8904                synchronized (this) {
8905                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8906                }
8907            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8908                String[] newArgs;
8909                String name;
8910                if (opti >= args.length) {
8911                    name = null;
8912                    newArgs = EMPTY_STRING_ARRAY;
8913                } else {
8914                    name = args[opti];
8915                    opti++;
8916                    newArgs = new String[args.length - opti];
8917                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8918                            args.length - opti);
8919                }
8920                synchronized (this) {
8921                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8922                }
8923            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8924                String[] newArgs;
8925                String name;
8926                if (opti >= args.length) {
8927                    name = null;
8928                    newArgs = EMPTY_STRING_ARRAY;
8929                } else {
8930                    name = args[opti];
8931                    opti++;
8932                    newArgs = new String[args.length - opti];
8933                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8934                            args.length - opti);
8935                }
8936                synchronized (this) {
8937                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8938                }
8939            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8940                synchronized (this) {
8941                    dumpOomLocked(fd, pw, args, opti, true);
8942                }
8943            } else if ("provider".equals(cmd)) {
8944                String[] newArgs;
8945                String name;
8946                if (opti >= args.length) {
8947                    name = null;
8948                    newArgs = EMPTY_STRING_ARRAY;
8949                } else {
8950                    name = args[opti];
8951                    opti++;
8952                    newArgs = new String[args.length - opti];
8953                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8954                }
8955                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8956                    pw.println("No providers match: " + name);
8957                    pw.println("Use -h for help.");
8958                }
8959            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8960                synchronized (this) {
8961                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8962                }
8963            } else if ("service".equals(cmd)) {
8964                String[] newArgs;
8965                String name;
8966                if (opti >= args.length) {
8967                    name = null;
8968                    newArgs = EMPTY_STRING_ARRAY;
8969                } else {
8970                    name = args[opti];
8971                    opti++;
8972                    newArgs = new String[args.length - opti];
8973                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8974                            args.length - opti);
8975                }
8976                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8977                    pw.println("No services match: " + name);
8978                    pw.println("Use -h for help.");
8979                }
8980            } else if ("package".equals(cmd)) {
8981                String[] newArgs;
8982                if (opti >= args.length) {
8983                    pw.println("package: no package name specified");
8984                    pw.println("Use -h for help.");
8985                } else {
8986                    dumpPackage = args[opti];
8987                    opti++;
8988                    newArgs = new String[args.length - opti];
8989                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8990                            args.length - opti);
8991                    args = newArgs;
8992                    opti = 0;
8993                    more = true;
8994                }
8995            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8996                synchronized (this) {
8997                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8998                }
8999            } else {
9000                // Dumping a single activity?
9001                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
9002                    pw.println("Bad activity command, or no activities match: " + cmd);
9003                    pw.println("Use -h for help.");
9004                }
9005            }
9006            if (!more) {
9007                Binder.restoreCallingIdentity(origId);
9008                return;
9009            }
9010        }
9011
9012        // No piece of data specified, dump everything.
9013        synchronized (this) {
9014            boolean needSep;
9015            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9016            if (needSep) {
9017                pw.println(" ");
9018            }
9019            if (dumpAll) {
9020                pw.println("-------------------------------------------------------------------------------");
9021            }
9022            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9023            if (needSep) {
9024                pw.println(" ");
9025            }
9026            if (dumpAll) {
9027                pw.println("-------------------------------------------------------------------------------");
9028            }
9029            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9030            if (needSep) {
9031                pw.println(" ");
9032            }
9033            if (dumpAll) {
9034                pw.println("-------------------------------------------------------------------------------");
9035            }
9036            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9037            if (needSep) {
9038                pw.println(" ");
9039            }
9040            if (dumpAll) {
9041                pw.println("-------------------------------------------------------------------------------");
9042            }
9043            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9044            if (needSep) {
9045                pw.println(" ");
9046            }
9047            if (dumpAll) {
9048                pw.println("-------------------------------------------------------------------------------");
9049            }
9050            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9051        }
9052        Binder.restoreCallingIdentity(origId);
9053    }
9054
9055    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9056            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9057        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9058        pw.println("  Main stack:");
9059        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
9060                dumpPackage);
9061        pw.println(" ");
9062        pw.println("  Running activities (most recent first):");
9063        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
9064                dumpPackage);
9065        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
9066            pw.println(" ");
9067            pw.println("  Activities waiting for another to become visible:");
9068            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
9069                    !dumpAll, false, dumpPackage);
9070        }
9071        if (mMainStack.mStoppingActivities.size() > 0) {
9072            pw.println(" ");
9073            pw.println("  Activities waiting to stop:");
9074            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
9075                    !dumpAll, false, dumpPackage);
9076        }
9077        if (mMainStack.mGoingToSleepActivities.size() > 0) {
9078            pw.println(" ");
9079            pw.println("  Activities waiting to sleep:");
9080            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
9081                    !dumpAll, false, dumpPackage);
9082        }
9083        if (mMainStack.mFinishingActivities.size() > 0) {
9084            pw.println(" ");
9085            pw.println("  Activities waiting to finish:");
9086            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
9087                    !dumpAll, false, dumpPackage);
9088        }
9089
9090        pw.println(" ");
9091        if (mMainStack.mPausingActivity != null) {
9092            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
9093        }
9094        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
9095        pw.println("  mFocusedActivity: " + mFocusedActivity);
9096        if (dumpAll) {
9097            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9098            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
9099            pw.println("  mDismissKeyguardOnNextActivity: "
9100                    + mMainStack.mDismissKeyguardOnNextActivity);
9101        }
9102
9103        if (mRecentTasks.size() > 0) {
9104            pw.println();
9105            pw.println("  Recent tasks:");
9106
9107            final int N = mRecentTasks.size();
9108            for (int i=0; i<N; i++) {
9109                TaskRecord tr = mRecentTasks.get(i);
9110                if (dumpPackage != null) {
9111                    if (tr.realActivity == null ||
9112                            !dumpPackage.equals(tr.realActivity)) {
9113                        continue;
9114                    }
9115                }
9116                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9117                        pw.println(tr);
9118                if (dumpAll) {
9119                    mRecentTasks.get(i).dump(pw, "    ");
9120                }
9121            }
9122        }
9123
9124        if (dumpAll) {
9125            pw.println(" ");
9126            pw.println("  mCurTask: " + mCurTask);
9127        }
9128
9129        return true;
9130    }
9131
9132    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9133            int opti, boolean dumpAll, String dumpPackage) {
9134        boolean needSep = false;
9135        int numPers = 0;
9136
9137        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9138
9139        if (dumpAll) {
9140            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9141                final int NA = procs.size();
9142                for (int ia=0; ia<NA; ia++) {
9143                    ProcessRecord r = procs.valueAt(ia);
9144                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9145                        continue;
9146                    }
9147                    if (!needSep) {
9148                        pw.println("  All known processes:");
9149                        needSep = true;
9150                    }
9151                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9152                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9153                        pw.print(" "); pw.println(r);
9154                    r.dump(pw, "    ");
9155                    if (r.persistent) {
9156                        numPers++;
9157                    }
9158                }
9159            }
9160        }
9161
9162        if (mIsolatedProcesses.size() > 0) {
9163            if (needSep) pw.println(" ");
9164            needSep = true;
9165            pw.println("  Isolated process list (sorted by uid):");
9166            for (int i=0; i<mIsolatedProcesses.size(); i++) {
9167                ProcessRecord r = mIsolatedProcesses.valueAt(i);
9168                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9169                    continue;
9170                }
9171                pw.println(String.format("%sIsolated #%2d: %s",
9172                        "    ", i, r.toString()));
9173            }
9174        }
9175
9176        if (mLruProcesses.size() > 0) {
9177            if (needSep) pw.println(" ");
9178            needSep = true;
9179            pw.println("  Process LRU list (sorted by oom_adj):");
9180            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9181                    "Proc", "PERS", false, dumpPackage);
9182            needSep = true;
9183        }
9184
9185        if (dumpAll) {
9186            synchronized (mPidsSelfLocked) {
9187                boolean printed = false;
9188                for (int i=0; i<mPidsSelfLocked.size(); i++) {
9189                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
9190                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9191                        continue;
9192                    }
9193                    if (!printed) {
9194                        if (needSep) pw.println(" ");
9195                        needSep = true;
9196                        pw.println("  PID mappings:");
9197                        printed = true;
9198                    }
9199                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9200                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9201                }
9202            }
9203        }
9204
9205        if (mForegroundProcesses.size() > 0) {
9206            synchronized (mPidsSelfLocked) {
9207                boolean printed = false;
9208                for (int i=0; i<mForegroundProcesses.size(); i++) {
9209                    ProcessRecord r = mPidsSelfLocked.get(
9210                            mForegroundProcesses.valueAt(i).pid);
9211                    if (dumpPackage != null && (r == null
9212                            || !dumpPackage.equals(r.info.packageName))) {
9213                        continue;
9214                    }
9215                    if (!printed) {
9216                        if (needSep) pw.println(" ");
9217                        needSep = true;
9218                        pw.println("  Foreground Processes:");
9219                        printed = true;
9220                    }
9221                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9222                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9223                }
9224            }
9225        }
9226
9227        if (mPersistentStartingProcesses.size() > 0) {
9228            if (needSep) pw.println(" ");
9229            needSep = true;
9230            pw.println("  Persisent processes that are starting:");
9231            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9232                    "Starting Norm", "Restarting PERS", dumpPackage);
9233        }
9234
9235        if (mRemovedProcesses.size() > 0) {
9236            if (needSep) pw.println(" ");
9237            needSep = true;
9238            pw.println("  Processes that are being removed:");
9239            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9240                    "Removed Norm", "Removed PERS", dumpPackage);
9241        }
9242
9243        if (mProcessesOnHold.size() > 0) {
9244            if (needSep) pw.println(" ");
9245            needSep = true;
9246            pw.println("  Processes that are on old until the system is ready:");
9247            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9248                    "OnHold Norm", "OnHold PERS", dumpPackage);
9249        }
9250
9251        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9252
9253        if (mProcessCrashTimes.getMap().size() > 0) {
9254            boolean printed = false;
9255            long now = SystemClock.uptimeMillis();
9256            for (Map.Entry<String, SparseArray<Long>> procs
9257                    : mProcessCrashTimes.getMap().entrySet()) {
9258                String pname = procs.getKey();
9259                SparseArray<Long> uids = procs.getValue();
9260                final int N = uids.size();
9261                for (int i=0; i<N; i++) {
9262                    int puid = uids.keyAt(i);
9263                    ProcessRecord r = mProcessNames.get(pname, puid);
9264                    if (dumpPackage != null && (r == null
9265                            || !dumpPackage.equals(r.info.packageName))) {
9266                        continue;
9267                    }
9268                    if (!printed) {
9269                        if (needSep) pw.println(" ");
9270                        needSep = true;
9271                        pw.println("  Time since processes crashed:");
9272                        printed = true;
9273                    }
9274                    pw.print("    Process "); pw.print(pname);
9275                            pw.print(" uid "); pw.print(puid);
9276                            pw.print(": last crashed ");
9277                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9278                            pw.println(" ago");
9279                }
9280            }
9281        }
9282
9283        if (mBadProcesses.getMap().size() > 0) {
9284            boolean printed = false;
9285            for (Map.Entry<String, SparseArray<Long>> procs
9286                    : mBadProcesses.getMap().entrySet()) {
9287                String pname = procs.getKey();
9288                SparseArray<Long> uids = procs.getValue();
9289                final int N = uids.size();
9290                for (int i=0; i<N; i++) {
9291                    int puid = uids.keyAt(i);
9292                    ProcessRecord r = mProcessNames.get(pname, puid);
9293                    if (dumpPackage != null && (r == null
9294                            || !dumpPackage.equals(r.info.packageName))) {
9295                        continue;
9296                    }
9297                    if (!printed) {
9298                        if (needSep) pw.println(" ");
9299                        needSep = true;
9300                        pw.println("  Bad processes:");
9301                    }
9302                    pw.print("    Bad process "); pw.print(pname);
9303                            pw.print(" uid "); pw.print(puid);
9304                            pw.print(": crashed at time ");
9305                            pw.println(uids.valueAt(i));
9306                }
9307            }
9308        }
9309
9310        pw.println();
9311        pw.println("  mStartedUsers:");
9312        for (int i=0; i<mStartedUsers.size(); i++) {
9313            UserStartedState uss = mStartedUsers.valueAt(i);
9314            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9315                    pw.print(": "); uss.dump("", pw);
9316        }
9317        pw.print("  mUserLru: [");
9318        for (int i=0; i<mUserLru.size(); i++) {
9319            if (i > 0) pw.print(", ");
9320            pw.print(mUserLru.get(i));
9321        }
9322        pw.println("]");
9323        if (dumpAll) {
9324            pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
9325        }
9326        pw.println("  mHomeProcess: " + mHomeProcess);
9327        pw.println("  mPreviousProcess: " + mPreviousProcess);
9328        if (dumpAll) {
9329            StringBuilder sb = new StringBuilder(128);
9330            sb.append("  mPreviousProcessVisibleTime: ");
9331            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9332            pw.println(sb);
9333        }
9334        if (mHeavyWeightProcess != null) {
9335            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9336        }
9337        pw.println("  mConfiguration: " + mConfiguration);
9338        if (dumpAll) {
9339            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9340            if (mCompatModePackages.getPackages().size() > 0) {
9341                boolean printed = false;
9342                for (Map.Entry<String, Integer> entry
9343                        : mCompatModePackages.getPackages().entrySet()) {
9344                    String pkg = entry.getKey();
9345                    int mode = entry.getValue();
9346                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9347                        continue;
9348                    }
9349                    if (!printed) {
9350                        pw.println("  mScreenCompatPackages:");
9351                        printed = true;
9352                    }
9353                    pw.print("    "); pw.print(pkg); pw.print(": ");
9354                            pw.print(mode); pw.println();
9355                }
9356            }
9357        }
9358        if (mSleeping || mWentToSleep || mLockScreenShown) {
9359            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9360                    + " mLockScreenShown " + mLockScreenShown);
9361        }
9362        if (mShuttingDown) {
9363            pw.println("  mShuttingDown=" + mShuttingDown);
9364        }
9365        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9366                || mOrigWaitForDebugger) {
9367            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9368                    + " mDebugTransient=" + mDebugTransient
9369                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9370        }
9371        if (mOpenGlTraceApp != null) {
9372            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9373        }
9374        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9375                || mProfileFd != null) {
9376            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9377            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9378            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9379                    + mAutoStopProfiler);
9380        }
9381        if (mAlwaysFinishActivities || mController != null) {
9382            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9383                    + " mController=" + mController);
9384        }
9385        if (dumpAll) {
9386            pw.println("  Total persistent processes: " + numPers);
9387            pw.println("  mStartRunning=" + mStartRunning
9388                    + " mProcessesReady=" + mProcessesReady
9389                    + " mSystemReady=" + mSystemReady);
9390            pw.println("  mBooting=" + mBooting
9391                    + " mBooted=" + mBooted
9392                    + " mFactoryTest=" + mFactoryTest);
9393            pw.print("  mLastPowerCheckRealtime=");
9394                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9395                    pw.println("");
9396            pw.print("  mLastPowerCheckUptime=");
9397                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9398                    pw.println("");
9399            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9400            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9401            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9402            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9403                    + " mNumHiddenProcs=" + mNumHiddenProcs
9404                    + " mNumServiceProcs=" + mNumServiceProcs
9405                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9406        }
9407
9408        return true;
9409    }
9410
9411    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9412            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9413        if (mProcessesToGc.size() > 0) {
9414            boolean printed = false;
9415            long now = SystemClock.uptimeMillis();
9416            for (int i=0; i<mProcessesToGc.size(); i++) {
9417                ProcessRecord proc = mProcessesToGc.get(i);
9418                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9419                    continue;
9420                }
9421                if (!printed) {
9422                    if (needSep) pw.println(" ");
9423                    needSep = true;
9424                    pw.println("  Processes that are waiting to GC:");
9425                    printed = true;
9426                }
9427                pw.print("    Process "); pw.println(proc);
9428                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9429                        pw.print(", last gced=");
9430                        pw.print(now-proc.lastRequestedGc);
9431                        pw.print(" ms ago, last lowMem=");
9432                        pw.print(now-proc.lastLowMemory);
9433                        pw.println(" ms ago");
9434
9435            }
9436        }
9437        return needSep;
9438    }
9439
9440    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9441            int opti, boolean dumpAll) {
9442        boolean needSep = false;
9443
9444        if (mLruProcesses.size() > 0) {
9445            if (needSep) pw.println(" ");
9446            needSep = true;
9447            pw.println("  OOM levels:");
9448            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9449            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9450            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9451            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9452            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9453            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9454            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9455            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9456            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9457            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9458            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9459            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9460            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9461
9462            if (needSep) pw.println(" ");
9463            needSep = true;
9464            pw.println("  Process OOM control:");
9465            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9466                    "Proc", "PERS", true, null);
9467            needSep = true;
9468        }
9469
9470        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9471
9472        pw.println();
9473        pw.println("  mHomeProcess: " + mHomeProcess);
9474        pw.println("  mPreviousProcess: " + mPreviousProcess);
9475        if (mHeavyWeightProcess != null) {
9476            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9477        }
9478
9479        return true;
9480    }
9481
9482    /**
9483     * There are three ways to call this:
9484     *  - no provider specified: dump all the providers
9485     *  - a flattened component name that matched an existing provider was specified as the
9486     *    first arg: dump that one provider
9487     *  - the first arg isn't the flattened component name of an existing provider:
9488     *    dump all providers whose component contains the first arg as a substring
9489     */
9490    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9491            int opti, boolean dumpAll) {
9492        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9493    }
9494
9495    static class ItemMatcher {
9496        ArrayList<ComponentName> components;
9497        ArrayList<String> strings;
9498        ArrayList<Integer> objects;
9499        boolean all;
9500
9501        ItemMatcher() {
9502            all = true;
9503        }
9504
9505        void build(String name) {
9506            ComponentName componentName = ComponentName.unflattenFromString(name);
9507            if (componentName != null) {
9508                if (components == null) {
9509                    components = new ArrayList<ComponentName>();
9510                }
9511                components.add(componentName);
9512                all = false;
9513            } else {
9514                int objectId = 0;
9515                // Not a '/' separated full component name; maybe an object ID?
9516                try {
9517                    objectId = Integer.parseInt(name, 16);
9518                    if (objects == null) {
9519                        objects = new ArrayList<Integer>();
9520                    }
9521                    objects.add(objectId);
9522                    all = false;
9523                } catch (RuntimeException e) {
9524                    // Not an integer; just do string match.
9525                    if (strings == null) {
9526                        strings = new ArrayList<String>();
9527                    }
9528                    strings.add(name);
9529                    all = false;
9530                }
9531            }
9532        }
9533
9534        int build(String[] args, int opti) {
9535            for (; opti<args.length; opti++) {
9536                String name = args[opti];
9537                if ("--".equals(name)) {
9538                    return opti+1;
9539                }
9540                build(name);
9541            }
9542            return opti;
9543        }
9544
9545        boolean match(Object object, ComponentName comp) {
9546            if (all) {
9547                return true;
9548            }
9549            if (components != null) {
9550                for (int i=0; i<components.size(); i++) {
9551                    if (components.get(i).equals(comp)) {
9552                        return true;
9553                    }
9554                }
9555            }
9556            if (objects != null) {
9557                for (int i=0; i<objects.size(); i++) {
9558                    if (System.identityHashCode(object) == objects.get(i)) {
9559                        return true;
9560                    }
9561                }
9562            }
9563            if (strings != null) {
9564                String flat = comp.flattenToString();
9565                for (int i=0; i<strings.size(); i++) {
9566                    if (flat.contains(strings.get(i))) {
9567                        return true;
9568                    }
9569                }
9570            }
9571            return false;
9572        }
9573    }
9574
9575    /**
9576     * There are three things that cmd can be:
9577     *  - a flattened component name that matches an existing activity
9578     *  - the cmd arg isn't the flattened component name of an existing activity:
9579     *    dump all activity whose component contains the cmd as a substring
9580     *  - A hex number of the ActivityRecord object instance.
9581     */
9582    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9583            int opti, boolean dumpAll) {
9584        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9585
9586        if ("all".equals(name)) {
9587            synchronized (this) {
9588                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9589                    activities.add(r1);
9590                }
9591            }
9592        } else if ("top".equals(name)) {
9593            synchronized (this) {
9594                final int N = mMainStack.mHistory.size();
9595                if (N > 0) {
9596                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9597                }
9598            }
9599        } else {
9600            ItemMatcher matcher = new ItemMatcher();
9601            matcher.build(name);
9602
9603            synchronized (this) {
9604                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9605                    if (matcher.match(r1, r1.intent.getComponent())) {
9606                        activities.add(r1);
9607                    }
9608                }
9609            }
9610        }
9611
9612        if (activities.size() <= 0) {
9613            return false;
9614        }
9615
9616        String[] newArgs = new String[args.length - opti];
9617        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9618
9619        TaskRecord lastTask = null;
9620        boolean needSep = false;
9621        for (int i=activities.size()-1; i>=0; i--) {
9622            ActivityRecord r = (ActivityRecord)activities.get(i);
9623            if (needSep) {
9624                pw.println();
9625            }
9626            needSep = true;
9627            synchronized (this) {
9628                if (lastTask != r.task) {
9629                    lastTask = r.task;
9630                    pw.print("TASK "); pw.print(lastTask.affinity);
9631                            pw.print(" id="); pw.println(lastTask.taskId);
9632                    if (dumpAll) {
9633                        lastTask.dump(pw, "  ");
9634                    }
9635                }
9636            }
9637            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9638        }
9639        return true;
9640    }
9641
9642    /**
9643     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9644     * there is a thread associated with the activity.
9645     */
9646    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9647            final ActivityRecord r, String[] args, boolean dumpAll) {
9648        String innerPrefix = prefix + "  ";
9649        synchronized (this) {
9650            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9651                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9652                    pw.print(" pid=");
9653                    if (r.app != null) pw.println(r.app.pid);
9654                    else pw.println("(not running)");
9655            if (dumpAll) {
9656                r.dump(pw, innerPrefix);
9657            }
9658        }
9659        if (r.app != null && r.app.thread != null) {
9660            // flush anything that is already in the PrintWriter since the thread is going
9661            // to write to the file descriptor directly
9662            pw.flush();
9663            try {
9664                TransferPipe tp = new TransferPipe();
9665                try {
9666                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9667                            r.appToken, innerPrefix, args);
9668                    tp.go(fd);
9669                } finally {
9670                    tp.kill();
9671                }
9672            } catch (IOException e) {
9673                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9674            } catch (RemoteException e) {
9675                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9676            }
9677        }
9678    }
9679
9680    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9681            int opti, boolean dumpAll, String dumpPackage) {
9682        boolean needSep = false;
9683        boolean onlyHistory = false;
9684
9685        if ("history".equals(dumpPackage)) {
9686            onlyHistory = true;
9687            dumpPackage = null;
9688        }
9689
9690        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9691        if (!onlyHistory && dumpAll) {
9692            if (mRegisteredReceivers.size() > 0) {
9693                boolean printed = false;
9694                Iterator it = mRegisteredReceivers.values().iterator();
9695                while (it.hasNext()) {
9696                    ReceiverList r = (ReceiverList)it.next();
9697                    if (dumpPackage != null && (r.app == null ||
9698                            !dumpPackage.equals(r.app.info.packageName))) {
9699                        continue;
9700                    }
9701                    if (!printed) {
9702                        pw.println("  Registered Receivers:");
9703                        needSep = true;
9704                        printed = true;
9705                    }
9706                    pw.print("  * "); pw.println(r);
9707                    r.dump(pw, "    ");
9708                }
9709            }
9710
9711            if (mReceiverResolver.dump(pw, needSep ?
9712                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9713                    "    ", dumpPackage, false)) {
9714                needSep = true;
9715            }
9716        }
9717
9718        for (BroadcastQueue q : mBroadcastQueues) {
9719            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9720        }
9721
9722        needSep = true;
9723
9724        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9725            for (int user=0; user<mStickyBroadcasts.size(); user++) {
9726                if (needSep) {
9727                    pw.println();
9728                }
9729                needSep = true;
9730                pw.print("  Sticky broadcasts for user ");
9731                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9732                StringBuilder sb = new StringBuilder(128);
9733                for (Map.Entry<String, ArrayList<Intent>> ent
9734                        : mStickyBroadcasts.valueAt(user).entrySet()) {
9735                    pw.print("  * Sticky action "); pw.print(ent.getKey());
9736                    if (dumpAll) {
9737                        pw.println(":");
9738                        ArrayList<Intent> intents = ent.getValue();
9739                        final int N = intents.size();
9740                        for (int i=0; i<N; i++) {
9741                            sb.setLength(0);
9742                            sb.append("    Intent: ");
9743                            intents.get(i).toShortString(sb, false, true, false, false);
9744                            pw.println(sb.toString());
9745                            Bundle bundle = intents.get(i).getExtras();
9746                            if (bundle != null) {
9747                                pw.print("      ");
9748                                pw.println(bundle.toString());
9749                            }
9750                        }
9751                    } else {
9752                        pw.println("");
9753                    }
9754                }
9755            }
9756        }
9757
9758        if (!onlyHistory && dumpAll) {
9759            pw.println();
9760            for (BroadcastQueue queue : mBroadcastQueues) {
9761                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9762                        + queue.mBroadcastsScheduled);
9763            }
9764            pw.println("  mHandler:");
9765            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9766            needSep = true;
9767        }
9768
9769        return needSep;
9770    }
9771
9772    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9773            int opti, boolean dumpAll, String dumpPackage) {
9774        boolean needSep = true;
9775
9776        ItemMatcher matcher = new ItemMatcher();
9777        matcher.build(args, opti);
9778
9779        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9780
9781        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9782
9783        if (mLaunchingProviders.size() > 0) {
9784            boolean printed = false;
9785            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9786                ContentProviderRecord r = mLaunchingProviders.get(i);
9787                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9788                    continue;
9789                }
9790                if (!printed) {
9791                    if (needSep) pw.println(" ");
9792                    needSep = true;
9793                    pw.println("  Launching content providers:");
9794                    printed = true;
9795                }
9796                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9797                        pw.println(r);
9798            }
9799        }
9800
9801        if (mGrantedUriPermissions.size() > 0) {
9802            if (needSep) pw.println();
9803            needSep = true;
9804            pw.println("Granted Uri Permissions:");
9805            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9806                int uid = mGrantedUriPermissions.keyAt(i);
9807                HashMap<Uri, UriPermission> perms
9808                        = mGrantedUriPermissions.valueAt(i);
9809                pw.print("  * UID "); pw.print(uid);
9810                        pw.println(" holds:");
9811                for (UriPermission perm : perms.values()) {
9812                    pw.print("    "); pw.println(perm);
9813                    if (dumpAll) {
9814                        perm.dump(pw, "      ");
9815                    }
9816                }
9817            }
9818            needSep = true;
9819        }
9820
9821        return needSep;
9822    }
9823
9824    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9825            int opti, boolean dumpAll, String dumpPackage) {
9826        boolean needSep = false;
9827
9828        if (mIntentSenderRecords.size() > 0) {
9829            boolean printed = false;
9830            Iterator<WeakReference<PendingIntentRecord>> it
9831                    = mIntentSenderRecords.values().iterator();
9832            while (it.hasNext()) {
9833                WeakReference<PendingIntentRecord> ref = it.next();
9834                PendingIntentRecord rec = ref != null ? ref.get(): null;
9835                if (dumpPackage != null && (rec == null
9836                        || !dumpPackage.equals(rec.key.packageName))) {
9837                    continue;
9838                }
9839                if (!printed) {
9840                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9841                    printed = true;
9842                }
9843                needSep = true;
9844                if (rec != null) {
9845                    pw.print("  * "); pw.println(rec);
9846                    if (dumpAll) {
9847                        rec.dump(pw, "    ");
9848                    }
9849                } else {
9850                    pw.print("  * "); pw.println(ref);
9851                }
9852            }
9853        }
9854
9855        return needSep;
9856    }
9857
9858    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9859            String prefix, String label, boolean complete, boolean brief, boolean client,
9860            String dumpPackage) {
9861        TaskRecord lastTask = null;
9862        boolean needNL = false;
9863        final String innerPrefix = prefix + "      ";
9864        final String[] args = new String[0];
9865        for (int i=list.size()-1; i>=0; i--) {
9866            final ActivityRecord r = (ActivityRecord)list.get(i);
9867            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9868                continue;
9869            }
9870            final boolean full = !brief && (complete || !r.isInHistory());
9871            if (needNL) {
9872                pw.println(" ");
9873                needNL = false;
9874            }
9875            if (lastTask != r.task) {
9876                lastTask = r.task;
9877                pw.print(prefix);
9878                pw.print(full ? "* " : "  ");
9879                pw.println(lastTask);
9880                if (full) {
9881                    lastTask.dump(pw, prefix + "  ");
9882                } else if (complete) {
9883                    // Complete + brief == give a summary.  Isn't that obvious?!?
9884                    if (lastTask.intent != null) {
9885                        pw.print(prefix); pw.print("  ");
9886                                pw.println(lastTask.intent.toInsecureStringWithClip());
9887                    }
9888                }
9889            }
9890            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9891            pw.print(" #"); pw.print(i); pw.print(": ");
9892            pw.println(r);
9893            if (full) {
9894                r.dump(pw, innerPrefix);
9895            } else if (complete) {
9896                // Complete + brief == give a summary.  Isn't that obvious?!?
9897                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9898                if (r.app != null) {
9899                    pw.print(innerPrefix); pw.println(r.app);
9900                }
9901            }
9902            if (client && r.app != null && r.app.thread != null) {
9903                // flush anything that is already in the PrintWriter since the thread is going
9904                // to write to the file descriptor directly
9905                pw.flush();
9906                try {
9907                    TransferPipe tp = new TransferPipe();
9908                    try {
9909                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9910                                r.appToken, innerPrefix, args);
9911                        // Short timeout, since blocking here can
9912                        // deadlock with the application.
9913                        tp.go(fd, 2000);
9914                    } finally {
9915                        tp.kill();
9916                    }
9917                } catch (IOException e) {
9918                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9919                } catch (RemoteException e) {
9920                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9921                }
9922                needNL = true;
9923            }
9924        }
9925    }
9926
9927    private static String buildOomTag(String prefix, String space, int val, int base) {
9928        if (val == base) {
9929            if (space == null) return prefix;
9930            return prefix + "  ";
9931        }
9932        return prefix + "+" + Integer.toString(val-base);
9933    }
9934
9935    private static final int dumpProcessList(PrintWriter pw,
9936            ActivityManagerService service, List list,
9937            String prefix, String normalLabel, String persistentLabel,
9938            String dumpPackage) {
9939        int numPers = 0;
9940        final int N = list.size()-1;
9941        for (int i=N; i>=0; i--) {
9942            ProcessRecord r = (ProcessRecord)list.get(i);
9943            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9944                continue;
9945            }
9946            pw.println(String.format("%s%s #%2d: %s",
9947                    prefix, (r.persistent ? persistentLabel : normalLabel),
9948                    i, r.toString()));
9949            if (r.persistent) {
9950                numPers++;
9951            }
9952        }
9953        return numPers;
9954    }
9955
9956    private static final boolean dumpProcessOomList(PrintWriter pw,
9957            ActivityManagerService service, List<ProcessRecord> origList,
9958            String prefix, String normalLabel, String persistentLabel,
9959            boolean inclDetails, String dumpPackage) {
9960
9961        ArrayList<Pair<ProcessRecord, Integer>> list
9962                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9963        for (int i=0; i<origList.size(); i++) {
9964            ProcessRecord r = origList.get(i);
9965            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9966                continue;
9967            }
9968            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9969        }
9970
9971        if (list.size() <= 0) {
9972            return false;
9973        }
9974
9975        Comparator<Pair<ProcessRecord, Integer>> comparator
9976                = new Comparator<Pair<ProcessRecord, Integer>>() {
9977            @Override
9978            public int compare(Pair<ProcessRecord, Integer> object1,
9979                    Pair<ProcessRecord, Integer> object2) {
9980                if (object1.first.setAdj != object2.first.setAdj) {
9981                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9982                }
9983                if (object1.second.intValue() != object2.second.intValue()) {
9984                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9985                }
9986                return 0;
9987            }
9988        };
9989
9990        Collections.sort(list, comparator);
9991
9992        final long curRealtime = SystemClock.elapsedRealtime();
9993        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9994        final long curUptime = SystemClock.uptimeMillis();
9995        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9996
9997        for (int i=list.size()-1; i>=0; i--) {
9998            ProcessRecord r = list.get(i).first;
9999            String oomAdj;
10000            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
10001                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
10002            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10003                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
10004            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10005                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
10006            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10007                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
10008            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10009                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
10010            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
10011                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
10012            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10013                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10014            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10015                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10016            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10017                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10018            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10019                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
10020            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10021                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
10022            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10023                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
10024            } else {
10025                oomAdj = Integer.toString(r.setAdj);
10026            }
10027            String schedGroup;
10028            switch (r.setSchedGroup) {
10029                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10030                    schedGroup = "B";
10031                    break;
10032                case Process.THREAD_GROUP_DEFAULT:
10033                    schedGroup = "F";
10034                    break;
10035                default:
10036                    schedGroup = Integer.toString(r.setSchedGroup);
10037                    break;
10038            }
10039            String foreground;
10040            if (r.foregroundActivities) {
10041                foreground = "A";
10042            } else if (r.foregroundServices) {
10043                foreground = "S";
10044            } else {
10045                foreground = " ";
10046            }
10047            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10048                    prefix, (r.persistent ? persistentLabel : normalLabel),
10049                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10050                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10051            if (r.adjSource != null || r.adjTarget != null) {
10052                pw.print(prefix);
10053                pw.print("    ");
10054                if (r.adjTarget instanceof ComponentName) {
10055                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10056                } else if (r.adjTarget != null) {
10057                    pw.print(r.adjTarget.toString());
10058                } else {
10059                    pw.print("{null}");
10060                }
10061                pw.print("<=");
10062                if (r.adjSource instanceof ProcessRecord) {
10063                    pw.print("Proc{");
10064                    pw.print(((ProcessRecord)r.adjSource).toShortString());
10065                    pw.println("}");
10066                } else if (r.adjSource != null) {
10067                    pw.println(r.adjSource.toString());
10068                } else {
10069                    pw.println("{null}");
10070                }
10071            }
10072            if (inclDetails) {
10073                pw.print(prefix);
10074                pw.print("    ");
10075                pw.print("oom: max="); pw.print(r.maxAdj);
10076                pw.print(" hidden="); pw.print(r.hiddenAdj);
10077                pw.print(" empty="); pw.print(r.emptyAdj);
10078                pw.print(" curRaw="); pw.print(r.curRawAdj);
10079                pw.print(" setRaw="); pw.print(r.setRawAdj);
10080                pw.print(" cur="); pw.print(r.curAdj);
10081                pw.print(" set="); pw.println(r.setAdj);
10082                pw.print(prefix);
10083                pw.print("    ");
10084                pw.print("keeping="); pw.print(r.keeping);
10085                pw.print(" hidden="); pw.print(r.hidden);
10086                pw.print(" empty="); pw.print(r.empty);
10087                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10088
10089                if (!r.keeping) {
10090                    if (r.lastWakeTime != 0) {
10091                        long wtime;
10092                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10093                        synchronized (stats) {
10094                            wtime = stats.getProcessWakeTime(r.info.uid,
10095                                    r.pid, curRealtime);
10096                        }
10097                        long timeUsed = wtime - r.lastWakeTime;
10098                        pw.print(prefix);
10099                        pw.print("    ");
10100                        pw.print("keep awake over ");
10101                        TimeUtils.formatDuration(realtimeSince, pw);
10102                        pw.print(" used ");
10103                        TimeUtils.formatDuration(timeUsed, pw);
10104                        pw.print(" (");
10105                        pw.print((timeUsed*100)/realtimeSince);
10106                        pw.println("%)");
10107                    }
10108                    if (r.lastCpuTime != 0) {
10109                        long timeUsed = r.curCpuTime - r.lastCpuTime;
10110                        pw.print(prefix);
10111                        pw.print("    ");
10112                        pw.print("run cpu over ");
10113                        TimeUtils.formatDuration(uptimeSince, pw);
10114                        pw.print(" used ");
10115                        TimeUtils.formatDuration(timeUsed, pw);
10116                        pw.print(" (");
10117                        pw.print((timeUsed*100)/uptimeSince);
10118                        pw.println("%)");
10119                    }
10120                }
10121            }
10122        }
10123        return true;
10124    }
10125
10126    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10127        ArrayList<ProcessRecord> procs;
10128        synchronized (this) {
10129            if (args != null && args.length > start
10130                    && args[start].charAt(0) != '-') {
10131                procs = new ArrayList<ProcessRecord>();
10132                int pid = -1;
10133                try {
10134                    pid = Integer.parseInt(args[start]);
10135                } catch (NumberFormatException e) {
10136
10137                }
10138                for (int i=mLruProcesses.size()-1; i>=0; i--) {
10139                    ProcessRecord proc = mLruProcesses.get(i);
10140                    if (proc.pid == pid) {
10141                        procs.add(proc);
10142                    } else if (proc.processName.equals(args[start])) {
10143                        procs.add(proc);
10144                    }
10145                }
10146                if (procs.size() <= 0) {
10147                    pw.println("No process found for: " + args[start]);
10148                    return null;
10149                }
10150            } else {
10151                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10152            }
10153        }
10154        return procs;
10155    }
10156
10157    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10158            PrintWriter pw, String[] args) {
10159        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10160        if (procs == null) {
10161            return;
10162        }
10163
10164        long uptime = SystemClock.uptimeMillis();
10165        long realtime = SystemClock.elapsedRealtime();
10166        pw.println("Applications Graphics Acceleration Info:");
10167        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10168
10169        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10170            ProcessRecord r = procs.get(i);
10171            if (r.thread != null) {
10172                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10173                pw.flush();
10174                try {
10175                    TransferPipe tp = new TransferPipe();
10176                    try {
10177                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10178                        tp.go(fd);
10179                    } finally {
10180                        tp.kill();
10181                    }
10182                } catch (IOException e) {
10183                    pw.println("Failure while dumping the app: " + r);
10184                    pw.flush();
10185                } catch (RemoteException e) {
10186                    pw.println("Got a RemoteException while dumping the app " + r);
10187                    pw.flush();
10188                }
10189            }
10190        }
10191    }
10192
10193    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10194        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10195        if (procs == null) {
10196            return;
10197        }
10198
10199        pw.println("Applications Database Info:");
10200
10201        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10202            ProcessRecord r = procs.get(i);
10203            if (r.thread != null) {
10204                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10205                pw.flush();
10206                try {
10207                    TransferPipe tp = new TransferPipe();
10208                    try {
10209                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10210                        tp.go(fd);
10211                    } finally {
10212                        tp.kill();
10213                    }
10214                } catch (IOException e) {
10215                    pw.println("Failure while dumping the app: " + r);
10216                    pw.flush();
10217                } catch (RemoteException e) {
10218                    pw.println("Got a RemoteException while dumping the app " + r);
10219                    pw.flush();
10220                }
10221            }
10222        }
10223    }
10224
10225    final static class MemItem {
10226        final String label;
10227        final String shortLabel;
10228        final long pss;
10229        final int id;
10230        ArrayList<MemItem> subitems;
10231
10232        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10233            label = _label;
10234            shortLabel = _shortLabel;
10235            pss = _pss;
10236            id = _id;
10237        }
10238    }
10239
10240    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10241            boolean sort) {
10242        if (sort) {
10243            Collections.sort(items, new Comparator<MemItem>() {
10244                @Override
10245                public int compare(MemItem lhs, MemItem rhs) {
10246                    if (lhs.pss < rhs.pss) {
10247                        return 1;
10248                    } else if (lhs.pss > rhs.pss) {
10249                        return -1;
10250                    }
10251                    return 0;
10252                }
10253            });
10254        }
10255
10256        for (int i=0; i<items.size(); i++) {
10257            MemItem mi = items.get(i);
10258            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10259            if (mi.subitems != null) {
10260                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10261            }
10262        }
10263    }
10264
10265    // These are in KB.
10266    static final long[] DUMP_MEM_BUCKETS = new long[] {
10267        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10268        120*1024, 160*1024, 200*1024,
10269        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10270        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10271    };
10272
10273    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10274            boolean stackLike) {
10275        int start = label.lastIndexOf('.');
10276        if (start >= 0) start++;
10277        else start = 0;
10278        int end = label.length();
10279        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10280            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10281                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10282                out.append(bucket);
10283                out.append(stackLike ? "MB." : "MB ");
10284                out.append(label, start, end);
10285                return;
10286            }
10287        }
10288        out.append(memKB/1024);
10289        out.append(stackLike ? "MB." : "MB ");
10290        out.append(label, start, end);
10291    }
10292
10293    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10294            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10295            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10296            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10297            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10298    };
10299    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10300            "System", "Persistent", "Foreground",
10301            "Visible", "Perceptible", "Heavy Weight",
10302            "Backup", "A Services", "Home", "Previous",
10303            "B Services", "Background"
10304    };
10305
10306    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10307            PrintWriter pw, String prefix, String[] args, boolean brief,
10308            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10309        boolean dumpAll = false;
10310        boolean oomOnly = false;
10311
10312        int opti = 0;
10313        while (opti < args.length) {
10314            String opt = args[opti];
10315            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10316                break;
10317            }
10318            opti++;
10319            if ("-a".equals(opt)) {
10320                dumpAll = true;
10321            } else if ("--oom".equals(opt)) {
10322                oomOnly = true;
10323            } else if ("-h".equals(opt)) {
10324                pw.println("meminfo dump options: [-a] [--oom] [process]");
10325                pw.println("  -a: include all available information for each process.");
10326                pw.println("  --oom: only show processes organized by oom adj.");
10327                pw.println("If [process] is specified it can be the name or ");
10328                pw.println("pid of a specific process to dump.");
10329                return;
10330            } else {
10331                pw.println("Unknown argument: " + opt + "; use -h for help");
10332            }
10333        }
10334
10335        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10336        if (procs == null) {
10337            return;
10338        }
10339
10340        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10341        long uptime = SystemClock.uptimeMillis();
10342        long realtime = SystemClock.elapsedRealtime();
10343
10344        if (procs.size() == 1 || isCheckinRequest) {
10345            dumpAll = true;
10346        }
10347
10348        if (isCheckinRequest) {
10349            // short checkin version
10350            pw.println(uptime + "," + realtime);
10351            pw.flush();
10352        } else {
10353            pw.println("Applications Memory Usage (kB):");
10354            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10355        }
10356
10357        String[] innerArgs = new String[args.length-opti];
10358        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10359
10360        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10361        long nativePss=0, dalvikPss=0, otherPss=0;
10362        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10363
10364        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10365        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10366                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10367
10368        long totalPss = 0;
10369
10370        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10371            ProcessRecord r = procs.get(i);
10372            if (r.thread != null) {
10373                if (!isCheckinRequest && dumpAll) {
10374                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10375                    pw.flush();
10376                }
10377                Debug.MemoryInfo mi = null;
10378                if (dumpAll) {
10379                    try {
10380                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10381                    } catch (RemoteException e) {
10382                        if (!isCheckinRequest) {
10383                            pw.println("Got RemoteException!");
10384                            pw.flush();
10385                        }
10386                    }
10387                } else {
10388                    mi = new Debug.MemoryInfo();
10389                    Debug.getMemoryInfo(r.pid, mi);
10390                }
10391
10392                if (!isCheckinRequest && mi != null) {
10393                    long myTotalPss = mi.getTotalPss();
10394                    totalPss += myTotalPss;
10395                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10396                            r.processName, myTotalPss, 0);
10397                    procMems.add(pssItem);
10398
10399                    nativePss += mi.nativePss;
10400                    dalvikPss += mi.dalvikPss;
10401                    otherPss += mi.otherPss;
10402                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10403                        long mem = mi.getOtherPss(j);
10404                        miscPss[j] += mem;
10405                        otherPss -= mem;
10406                    }
10407
10408                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10409                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10410                                || oomIndex == (oomPss.length-1)) {
10411                            oomPss[oomIndex] += myTotalPss;
10412                            if (oomProcs[oomIndex] == null) {
10413                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10414                            }
10415                            oomProcs[oomIndex].add(pssItem);
10416                            break;
10417                        }
10418                    }
10419                }
10420            }
10421        }
10422
10423        if (!isCheckinRequest && procs.size() > 1) {
10424            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10425
10426            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10427            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10428            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10429            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10430                String label = Debug.MemoryInfo.getOtherLabel(j);
10431                catMems.add(new MemItem(label, label, miscPss[j], j));
10432            }
10433
10434            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10435            for (int j=0; j<oomPss.length; j++) {
10436                if (oomPss[j] != 0) {
10437                    String label = DUMP_MEM_OOM_LABEL[j];
10438                    MemItem item = new MemItem(label, label, oomPss[j],
10439                            DUMP_MEM_OOM_ADJ[j]);
10440                    item.subitems = oomProcs[j];
10441                    oomMems.add(item);
10442                }
10443            }
10444
10445            if (outTag != null || outStack != null) {
10446                if (outTag != null) {
10447                    appendMemBucket(outTag, totalPss, "total", false);
10448                }
10449                if (outStack != null) {
10450                    appendMemBucket(outStack, totalPss, "total", true);
10451                }
10452                boolean firstLine = true;
10453                for (int i=0; i<oomMems.size(); i++) {
10454                    MemItem miCat = oomMems.get(i);
10455                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10456                        continue;
10457                    }
10458                    if (miCat.id < ProcessList.SERVICE_ADJ
10459                            || miCat.id == ProcessList.HOME_APP_ADJ
10460                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10461                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10462                            outTag.append(" / ");
10463                        }
10464                        if (outStack != null) {
10465                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10466                                if (firstLine) {
10467                                    outStack.append(":");
10468                                    firstLine = false;
10469                                }
10470                                outStack.append("\n\t at ");
10471                            } else {
10472                                outStack.append("$");
10473                            }
10474                        }
10475                        for (int j=0; j<miCat.subitems.size(); j++) {
10476                            MemItem mi = miCat.subitems.get(j);
10477                            if (j > 0) {
10478                                if (outTag != null) {
10479                                    outTag.append(" ");
10480                                }
10481                                if (outStack != null) {
10482                                    outStack.append("$");
10483                                }
10484                            }
10485                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10486                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10487                            }
10488                            if (outStack != null) {
10489                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10490                            }
10491                        }
10492                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10493                            outStack.append("(");
10494                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10495                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10496                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10497                                    outStack.append(":");
10498                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10499                                }
10500                            }
10501                            outStack.append(")");
10502                        }
10503                    }
10504                }
10505            }
10506
10507            if (!brief && !oomOnly) {
10508                pw.println();
10509                pw.println("Total PSS by process:");
10510                dumpMemItems(pw, "  ", procMems, true);
10511                pw.println();
10512            }
10513            pw.println("Total PSS by OOM adjustment:");
10514            dumpMemItems(pw, "  ", oomMems, false);
10515            if (!oomOnly) {
10516                PrintWriter out = categoryPw != null ? categoryPw : pw;
10517                out.println();
10518                out.println("Total PSS by category:");
10519                dumpMemItems(out, "  ", catMems, true);
10520            }
10521            pw.println();
10522            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10523            final int[] SINGLE_LONG_FORMAT = new int[] {
10524                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10525            };
10526            long[] longOut = new long[1];
10527            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10528                    SINGLE_LONG_FORMAT, null, longOut, null);
10529            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10530            longOut[0] = 0;
10531            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10532                    SINGLE_LONG_FORMAT, null, longOut, null);
10533            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10534            longOut[0] = 0;
10535            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10536                    SINGLE_LONG_FORMAT, null, longOut, null);
10537            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10538            longOut[0] = 0;
10539            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10540                    SINGLE_LONG_FORMAT, null, longOut, null);
10541            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10542            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10543                    pw.print(shared); pw.println(" kB");
10544            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10545                    pw.print(voltile); pw.println(" kB volatile");
10546        }
10547    }
10548
10549    /**
10550     * Searches array of arguments for the specified string
10551     * @param args array of argument strings
10552     * @param value value to search for
10553     * @return true if the value is contained in the array
10554     */
10555    private static boolean scanArgs(String[] args, String value) {
10556        if (args != null) {
10557            for (String arg : args) {
10558                if (value.equals(arg)) {
10559                    return true;
10560                }
10561            }
10562        }
10563        return false;
10564    }
10565
10566    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10567            ContentProviderRecord cpr, boolean always) {
10568        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10569
10570        if (!inLaunching || always) {
10571            synchronized (cpr) {
10572                cpr.launchingApp = null;
10573                cpr.notifyAll();
10574            }
10575            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10576            String names[] = cpr.info.authority.split(";");
10577            for (int j = 0; j < names.length; j++) {
10578                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10579            }
10580        }
10581
10582        for (int i=0; i<cpr.connections.size(); i++) {
10583            ContentProviderConnection conn = cpr.connections.get(i);
10584            if (conn.waiting) {
10585                // If this connection is waiting for the provider, then we don't
10586                // need to mess with its process unless we are always removing
10587                // or for some reason the provider is not currently launching.
10588                if (inLaunching && !always) {
10589                    continue;
10590                }
10591            }
10592            ProcessRecord capp = conn.client;
10593            conn.dead = true;
10594            if (conn.stableCount > 0) {
10595                if (!capp.persistent && capp.thread != null
10596                        && capp.pid != 0
10597                        && capp.pid != MY_PID) {
10598                    Slog.i(TAG, "Kill " + capp.processName
10599                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10600                            + " in dying process " + (proc != null ? proc.processName : "??"));
10601                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10602                            capp.processName, capp.setAdj, "dying provider "
10603                                    + cpr.name.toShortString());
10604                    Process.killProcessQuiet(capp.pid);
10605                }
10606            } else if (capp.thread != null && conn.provider.provider != null) {
10607                try {
10608                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10609                } catch (RemoteException e) {
10610                }
10611                // In the protocol here, we don't expect the client to correctly
10612                // clean up this connection, we'll just remove it.
10613                cpr.connections.remove(i);
10614                conn.client.conProviders.remove(conn);
10615            }
10616        }
10617
10618        if (inLaunching && always) {
10619            mLaunchingProviders.remove(cpr);
10620        }
10621        return inLaunching;
10622    }
10623
10624    /**
10625     * Main code for cleaning up a process when it has gone away.  This is
10626     * called both as a result of the process dying, or directly when stopping
10627     * a process when running in single process mode.
10628     */
10629    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10630            boolean restarting, boolean allowRestart, int index) {
10631        if (index >= 0) {
10632            mLruProcesses.remove(index);
10633        }
10634
10635        mProcessesToGc.remove(app);
10636
10637        // Dismiss any open dialogs.
10638        if (app.crashDialog != null) {
10639            app.crashDialog.dismiss();
10640            app.crashDialog = null;
10641        }
10642        if (app.anrDialog != null) {
10643            app.anrDialog.dismiss();
10644            app.anrDialog = null;
10645        }
10646        if (app.waitDialog != null) {
10647            app.waitDialog.dismiss();
10648            app.waitDialog = null;
10649        }
10650
10651        app.crashing = false;
10652        app.notResponding = false;
10653
10654        app.resetPackageList();
10655        app.unlinkDeathRecipient();
10656        app.thread = null;
10657        app.forcingToForeground = null;
10658        app.foregroundServices = false;
10659        app.foregroundActivities = false;
10660        app.hasShownUi = false;
10661        app.hasAboveClient = false;
10662
10663        mServices.killServicesLocked(app, allowRestart);
10664
10665        boolean restart = false;
10666
10667        // Remove published content providers.
10668        if (!app.pubProviders.isEmpty()) {
10669            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10670            while (it.hasNext()) {
10671                ContentProviderRecord cpr = it.next();
10672
10673                final boolean always = app.bad || !allowRestart;
10674                if (removeDyingProviderLocked(app, cpr, always) || always) {
10675                    // We left the provider in the launching list, need to
10676                    // restart it.
10677                    restart = true;
10678                }
10679
10680                cpr.provider = null;
10681                cpr.proc = null;
10682            }
10683            app.pubProviders.clear();
10684        }
10685
10686        // Take care of any launching providers waiting for this process.
10687        if (checkAppInLaunchingProvidersLocked(app, false)) {
10688            restart = true;
10689        }
10690
10691        // Unregister from connected content providers.
10692        if (!app.conProviders.isEmpty()) {
10693            for (int i=0; i<app.conProviders.size(); i++) {
10694                ContentProviderConnection conn = app.conProviders.get(i);
10695                conn.provider.connections.remove(conn);
10696            }
10697            app.conProviders.clear();
10698        }
10699
10700        // At this point there may be remaining entries in mLaunchingProviders
10701        // where we were the only one waiting, so they are no longer of use.
10702        // Look for these and clean up if found.
10703        // XXX Commented out for now.  Trying to figure out a way to reproduce
10704        // the actual situation to identify what is actually going on.
10705        if (false) {
10706            for (int i=0; i<mLaunchingProviders.size(); i++) {
10707                ContentProviderRecord cpr = (ContentProviderRecord)
10708                        mLaunchingProviders.get(i);
10709                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10710                    synchronized (cpr) {
10711                        cpr.launchingApp = null;
10712                        cpr.notifyAll();
10713                    }
10714                }
10715            }
10716        }
10717
10718        skipCurrentReceiverLocked(app);
10719
10720        // Unregister any receivers.
10721        if (app.receivers.size() > 0) {
10722            Iterator<ReceiverList> it = app.receivers.iterator();
10723            while (it.hasNext()) {
10724                removeReceiverLocked(it.next());
10725            }
10726            app.receivers.clear();
10727        }
10728
10729        // If the app is undergoing backup, tell the backup manager about it
10730        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10731            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10732            try {
10733                IBackupManager bm = IBackupManager.Stub.asInterface(
10734                        ServiceManager.getService(Context.BACKUP_SERVICE));
10735                bm.agentDisconnected(app.info.packageName);
10736            } catch (RemoteException e) {
10737                // can't happen; backup manager is local
10738            }
10739        }
10740
10741        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10742            ProcessChangeItem item = mPendingProcessChanges.get(i);
10743            if (item.pid == app.pid) {
10744                mPendingProcessChanges.remove(i);
10745                mAvailProcessChanges.add(item);
10746            }
10747        }
10748        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10749
10750        // If the caller is restarting this app, then leave it in its
10751        // current lists and let the caller take care of it.
10752        if (restarting) {
10753            return;
10754        }
10755
10756        if (!app.persistent || app.isolated) {
10757            if (DEBUG_PROCESSES) Slog.v(TAG,
10758                    "Removing non-persistent process during cleanup: " + app);
10759            mProcessNames.remove(app.processName, app.uid);
10760            mIsolatedProcesses.remove(app.uid);
10761            if (mHeavyWeightProcess == app) {
10762                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10763                        mHeavyWeightProcess.userId, 0));
10764                mHeavyWeightProcess = null;
10765            }
10766        } else if (!app.removed) {
10767            // This app is persistent, so we need to keep its record around.
10768            // If it is not already on the pending app list, add it there
10769            // and start a new process for it.
10770            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10771                mPersistentStartingProcesses.add(app);
10772                restart = true;
10773            }
10774        }
10775        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10776                "Clean-up removing on hold: " + app);
10777        mProcessesOnHold.remove(app);
10778
10779        if (app == mHomeProcess) {
10780            mHomeProcess = null;
10781        }
10782        if (app == mPreviousProcess) {
10783            mPreviousProcess = null;
10784        }
10785
10786        if (restart && !app.isolated) {
10787            // We have components that still need to be running in the
10788            // process, so re-launch it.
10789            mProcessNames.put(app.processName, app.uid, app);
10790            startProcessLocked(app, "restart", app.processName);
10791        } else if (app.pid > 0 && app.pid != MY_PID) {
10792            // Goodbye!
10793            synchronized (mPidsSelfLocked) {
10794                mPidsSelfLocked.remove(app.pid);
10795                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10796            }
10797            app.setPid(0);
10798        }
10799    }
10800
10801    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10802        // Look through the content providers we are waiting to have launched,
10803        // and if any run in this process then either schedule a restart of
10804        // the process or kill the client waiting for it if this process has
10805        // gone bad.
10806        int NL = mLaunchingProviders.size();
10807        boolean restart = false;
10808        for (int i=0; i<NL; i++) {
10809            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10810            if (cpr.launchingApp == app) {
10811                if (!alwaysBad && !app.bad) {
10812                    restart = true;
10813                } else {
10814                    removeDyingProviderLocked(app, cpr, true);
10815                    // cpr should have been removed from mLaunchingProviders
10816                    NL = mLaunchingProviders.size();
10817                    i--;
10818                }
10819            }
10820        }
10821        return restart;
10822    }
10823
10824    // =========================================================
10825    // SERVICES
10826    // =========================================================
10827
10828    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10829            int flags) {
10830        enforceNotIsolatedCaller("getServices");
10831        synchronized (this) {
10832            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10833        }
10834    }
10835
10836    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10837        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10838        synchronized (this) {
10839            return mServices.getRunningServiceControlPanelLocked(name);
10840        }
10841    }
10842
10843    public ComponentName startService(IApplicationThread caller, Intent service,
10844            String resolvedType, int userId) {
10845        enforceNotIsolatedCaller("startService");
10846        // Refuse possible leaked file descriptors
10847        if (service != null && service.hasFileDescriptors() == true) {
10848            throw new IllegalArgumentException("File descriptors passed in Intent");
10849        }
10850
10851        if (DEBUG_SERVICE)
10852            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10853        synchronized(this) {
10854            final int callingPid = Binder.getCallingPid();
10855            final int callingUid = Binder.getCallingUid();
10856            checkValidCaller(callingUid, userId);
10857            final long origId = Binder.clearCallingIdentity();
10858            ComponentName res = mServices.startServiceLocked(caller, service,
10859                    resolvedType, callingPid, callingUid, userId);
10860            Binder.restoreCallingIdentity(origId);
10861            return res;
10862        }
10863    }
10864
10865    ComponentName startServiceInPackage(int uid,
10866            Intent service, String resolvedType, int userId) {
10867        synchronized(this) {
10868            if (DEBUG_SERVICE)
10869                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10870            final long origId = Binder.clearCallingIdentity();
10871            ComponentName res = mServices.startServiceLocked(null, service,
10872                    resolvedType, -1, uid, userId);
10873            Binder.restoreCallingIdentity(origId);
10874            return res;
10875        }
10876    }
10877
10878    public int stopService(IApplicationThread caller, Intent service,
10879            String resolvedType, int userId) {
10880        enforceNotIsolatedCaller("stopService");
10881        // Refuse possible leaked file descriptors
10882        if (service != null && service.hasFileDescriptors() == true) {
10883            throw new IllegalArgumentException("File descriptors passed in Intent");
10884        }
10885
10886        checkValidCaller(Binder.getCallingUid(), userId);
10887
10888        synchronized(this) {
10889            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10890        }
10891    }
10892
10893    public IBinder peekService(Intent service, String resolvedType) {
10894        enforceNotIsolatedCaller("peekService");
10895        // Refuse possible leaked file descriptors
10896        if (service != null && service.hasFileDescriptors() == true) {
10897            throw new IllegalArgumentException("File descriptors passed in Intent");
10898        }
10899        synchronized(this) {
10900            return mServices.peekServiceLocked(service, resolvedType);
10901        }
10902    }
10903
10904    public boolean stopServiceToken(ComponentName className, IBinder token,
10905            int startId) {
10906        synchronized(this) {
10907            return mServices.stopServiceTokenLocked(className, token, startId);
10908        }
10909    }
10910
10911    public void setServiceForeground(ComponentName className, IBinder token,
10912            int id, Notification notification, boolean removeNotification) {
10913        synchronized(this) {
10914            mServices.setServiceForegroundLocked(className, token, id, notification,
10915                    removeNotification);
10916        }
10917    }
10918
10919    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
10920            boolean requireFull, String name, String callerPackage) {
10921        synchronized(this) {
10922            return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll,
10923                    requireFull, name, callerPackage);
10924        }
10925    }
10926
10927    int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll,
10928            boolean requireFull, String name, String callerPackage) {
10929        final int callingUserId = UserHandle.getUserId(callingUid);
10930        if (callingUserId != userId) {
10931            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10932                if ((requireFull || checkComponentPermission(
10933                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10934                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
10935                        && checkComponentPermission(
10936                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10937                                callingPid, callingUid, -1, true)
10938                                != PackageManager.PERMISSION_GRANTED) {
10939                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
10940                        // In this case, they would like to just execute as their
10941                        // owner user instead of failing.
10942                        userId = callingUserId;
10943                    } else {
10944                        StringBuilder builder = new StringBuilder(128);
10945                        builder.append("Permission Denial: ");
10946                        builder.append(name);
10947                        if (callerPackage != null) {
10948                            builder.append(" from ");
10949                            builder.append(callerPackage);
10950                        }
10951                        builder.append(" asks to run as user ");
10952                        builder.append(userId);
10953                        builder.append(" but is calling from user ");
10954                        builder.append(UserHandle.getUserId(callingUid));
10955                        builder.append("; this requires ");
10956                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
10957                        if (!requireFull) {
10958                            builder.append(" or ");
10959                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
10960                        }
10961                        String msg = builder.toString();
10962                        Slog.w(TAG, msg);
10963                        throw new SecurityException(msg);
10964                    }
10965                }
10966            }
10967            if (userId == UserHandle.USER_CURRENT
10968                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
10969                userId = mCurrentUserId;
10970            }
10971            if (!allowAll && userId < 0) {
10972                throw new IllegalArgumentException(
10973                        "Call does not support special user #" + userId);
10974            }
10975        }
10976        return userId;
10977    }
10978
10979    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10980            String className, int flags) {
10981        boolean result = false;
10982        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10983            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10984                if (ActivityManager.checkUidPermission(
10985                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10986                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10987                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10988                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10989                            + " requests FLAG_SINGLE_USER, but app does not hold "
10990                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10991                    Slog.w(TAG, msg);
10992                    throw new SecurityException(msg);
10993                }
10994                result = true;
10995            }
10996        } else if (componentProcessName == aInfo.packageName) {
10997            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10998        } else if ("system".equals(componentProcessName)) {
10999            result = true;
11000        }
11001        if (DEBUG_MU) {
11002            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
11003                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
11004        }
11005        return result;
11006    }
11007
11008    public int bindService(IApplicationThread caller, IBinder token,
11009            Intent service, String resolvedType,
11010            IServiceConnection connection, int flags, int userId) {
11011        enforceNotIsolatedCaller("bindService");
11012        // Refuse possible leaked file descriptors
11013        if (service != null && service.hasFileDescriptors() == true) {
11014            throw new IllegalArgumentException("File descriptors passed in Intent");
11015        }
11016
11017        synchronized(this) {
11018            return mServices.bindServiceLocked(caller, token, service, resolvedType,
11019                    connection, flags, userId);
11020        }
11021    }
11022
11023    public boolean unbindService(IServiceConnection connection) {
11024        synchronized (this) {
11025            return mServices.unbindServiceLocked(connection);
11026        }
11027    }
11028
11029    public void publishService(IBinder token, Intent intent, IBinder service) {
11030        // Refuse possible leaked file descriptors
11031        if (intent != null && intent.hasFileDescriptors() == true) {
11032            throw new IllegalArgumentException("File descriptors passed in Intent");
11033        }
11034
11035        synchronized(this) {
11036            if (!(token instanceof ServiceRecord)) {
11037                throw new IllegalArgumentException("Invalid service token");
11038            }
11039            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
11040        }
11041    }
11042
11043    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11044        // Refuse possible leaked file descriptors
11045        if (intent != null && intent.hasFileDescriptors() == true) {
11046            throw new IllegalArgumentException("File descriptors passed in Intent");
11047        }
11048
11049        synchronized(this) {
11050            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
11051        }
11052    }
11053
11054    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11055        synchronized(this) {
11056            if (!(token instanceof ServiceRecord)) {
11057                throw new IllegalArgumentException("Invalid service token");
11058            }
11059            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
11060        }
11061    }
11062
11063    // =========================================================
11064    // BACKUP AND RESTORE
11065    // =========================================================
11066
11067    // Cause the target app to be launched if necessary and its backup agent
11068    // instantiated.  The backup agent will invoke backupAgentCreated() on the
11069    // activity manager to announce its creation.
11070    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11071        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
11072        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11073
11074        synchronized(this) {
11075            // !!! TODO: currently no check here that we're already bound
11076            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11077            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11078            synchronized (stats) {
11079                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11080            }
11081
11082            // Backup agent is now in use, its package can't be stopped.
11083            try {
11084                AppGlobals.getPackageManager().setPackageStoppedState(
11085                        app.packageName, false, UserHandle.getUserId(app.uid));
11086            } catch (RemoteException e) {
11087            } catch (IllegalArgumentException e) {
11088                Slog.w(TAG, "Failed trying to unstop package "
11089                        + app.packageName + ": " + e);
11090            }
11091
11092            BackupRecord r = new BackupRecord(ss, app, backupMode);
11093            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11094                    ? new ComponentName(app.packageName, app.backupAgentName)
11095                    : new ComponentName("android", "FullBackupAgent");
11096            // startProcessLocked() returns existing proc's record if it's already running
11097            ProcessRecord proc = startProcessLocked(app.processName, app,
11098                    false, 0, "backup", hostingName, false, false);
11099            if (proc == null) {
11100                Slog.e(TAG, "Unable to start backup agent process " + r);
11101                return false;
11102            }
11103
11104            r.app = proc;
11105            mBackupTarget = r;
11106            mBackupAppName = app.packageName;
11107
11108            // Try not to kill the process during backup
11109            updateOomAdjLocked(proc);
11110
11111            // If the process is already attached, schedule the creation of the backup agent now.
11112            // If it is not yet live, this will be done when it attaches to the framework.
11113            if (proc.thread != null) {
11114                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11115                try {
11116                    proc.thread.scheduleCreateBackupAgent(app,
11117                            compatibilityInfoForPackageLocked(app), backupMode);
11118                } catch (RemoteException e) {
11119                    // Will time out on the backup manager side
11120                }
11121            } else {
11122                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11123            }
11124            // Invariants: at this point, the target app process exists and the application
11125            // is either already running or in the process of coming up.  mBackupTarget and
11126            // mBackupAppName describe the app, so that when it binds back to the AM we
11127            // know that it's scheduled for a backup-agent operation.
11128        }
11129
11130        return true;
11131    }
11132
11133    // A backup agent has just come up
11134    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11135        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11136                + " = " + agent);
11137
11138        synchronized(this) {
11139            if (!agentPackageName.equals(mBackupAppName)) {
11140                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11141                return;
11142            }
11143        }
11144
11145        long oldIdent = Binder.clearCallingIdentity();
11146        try {
11147            IBackupManager bm = IBackupManager.Stub.asInterface(
11148                    ServiceManager.getService(Context.BACKUP_SERVICE));
11149            bm.agentConnected(agentPackageName, agent);
11150        } catch (RemoteException e) {
11151            // can't happen; the backup manager service is local
11152        } catch (Exception e) {
11153            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11154            e.printStackTrace();
11155        } finally {
11156            Binder.restoreCallingIdentity(oldIdent);
11157        }
11158    }
11159
11160    // done with this agent
11161    public void unbindBackupAgent(ApplicationInfo appInfo) {
11162        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11163        if (appInfo == null) {
11164            Slog.w(TAG, "unbind backup agent for null app");
11165            return;
11166        }
11167
11168        synchronized(this) {
11169            if (mBackupAppName == null) {
11170                Slog.w(TAG, "Unbinding backup agent with no active backup");
11171                return;
11172            }
11173
11174            if (!mBackupAppName.equals(appInfo.packageName)) {
11175                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11176                return;
11177            }
11178
11179            ProcessRecord proc = mBackupTarget.app;
11180            mBackupTarget = null;
11181            mBackupAppName = null;
11182
11183            // Not backing this app up any more; reset its OOM adjustment
11184            updateOomAdjLocked(proc);
11185
11186            // If the app crashed during backup, 'thread' will be null here
11187            if (proc.thread != null) {
11188                try {
11189                    proc.thread.scheduleDestroyBackupAgent(appInfo,
11190                            compatibilityInfoForPackageLocked(appInfo));
11191                } catch (Exception e) {
11192                    Slog.e(TAG, "Exception when unbinding backup agent:");
11193                    e.printStackTrace();
11194                }
11195            }
11196        }
11197    }
11198    // =========================================================
11199    // BROADCASTS
11200    // =========================================================
11201
11202    private final List getStickiesLocked(String action, IntentFilter filter,
11203            List cur, int userId) {
11204        final ContentResolver resolver = mContext.getContentResolver();
11205        HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11206        if (stickies == null) {
11207            return cur;
11208        }
11209        final ArrayList<Intent> list = stickies.get(action);
11210        if (list == null) {
11211            return cur;
11212        }
11213        int N = list.size();
11214        for (int i=0; i<N; i++) {
11215            Intent intent = list.get(i);
11216            if (filter.match(resolver, intent, true, TAG) >= 0) {
11217                if (cur == null) {
11218                    cur = new ArrayList<Intent>();
11219                }
11220                cur.add(intent);
11221            }
11222        }
11223        return cur;
11224    }
11225
11226    boolean isPendingBroadcastProcessLocked(int pid) {
11227        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11228                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11229    }
11230
11231    void skipPendingBroadcastLocked(int pid) {
11232            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11233            for (BroadcastQueue queue : mBroadcastQueues) {
11234                queue.skipPendingBroadcastLocked(pid);
11235            }
11236    }
11237
11238    // The app just attached; send any pending broadcasts that it should receive
11239    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11240        boolean didSomething = false;
11241        for (BroadcastQueue queue : mBroadcastQueues) {
11242            didSomething |= queue.sendPendingBroadcastsLocked(app);
11243        }
11244        return didSomething;
11245    }
11246
11247    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11248            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11249        enforceNotIsolatedCaller("registerReceiver");
11250        int callingUid;
11251        int callingPid;
11252        synchronized(this) {
11253            ProcessRecord callerApp = null;
11254            if (caller != null) {
11255                callerApp = getRecordForAppLocked(caller);
11256                if (callerApp == null) {
11257                    throw new SecurityException(
11258                            "Unable to find app for caller " + caller
11259                            + " (pid=" + Binder.getCallingPid()
11260                            + ") when registering receiver " + receiver);
11261                }
11262                if (callerApp.info.uid != Process.SYSTEM_UID &&
11263                        !callerApp.pkgList.contains(callerPackage)) {
11264                    throw new SecurityException("Given caller package " + callerPackage
11265                            + " is not running in process " + callerApp);
11266                }
11267                callingUid = callerApp.info.uid;
11268                callingPid = callerApp.pid;
11269            } else {
11270                callerPackage = null;
11271                callingUid = Binder.getCallingUid();
11272                callingPid = Binder.getCallingPid();
11273            }
11274
11275            userId = this.handleIncomingUserLocked(callingPid, callingUid, userId,
11276                    true, true, "registerReceiver", callerPackage);
11277
11278            List allSticky = null;
11279
11280            // Look for any matching sticky broadcasts...
11281            Iterator actions = filter.actionsIterator();
11282            if (actions != null) {
11283                while (actions.hasNext()) {
11284                    String action = (String)actions.next();
11285                    allSticky = getStickiesLocked(action, filter, allSticky,
11286                            UserHandle.USER_ALL);
11287                    allSticky = getStickiesLocked(action, filter, allSticky,
11288                            UserHandle.getUserId(callingUid));
11289                }
11290            } else {
11291                allSticky = getStickiesLocked(null, filter, allSticky,
11292                        UserHandle.USER_ALL);
11293                allSticky = getStickiesLocked(null, filter, allSticky,
11294                        UserHandle.getUserId(callingUid));
11295            }
11296
11297            // The first sticky in the list is returned directly back to
11298            // the client.
11299            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11300
11301            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11302                    + ": " + sticky);
11303
11304            if (receiver == null) {
11305                return sticky;
11306            }
11307
11308            ReceiverList rl
11309                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11310            if (rl == null) {
11311                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11312                        userId, receiver);
11313                if (rl.app != null) {
11314                    rl.app.receivers.add(rl);
11315                } else {
11316                    try {
11317                        receiver.asBinder().linkToDeath(rl, 0);
11318                    } catch (RemoteException e) {
11319                        return sticky;
11320                    }
11321                    rl.linkedToDeath = true;
11322                }
11323                mRegisteredReceivers.put(receiver.asBinder(), rl);
11324            } else if (rl.uid != callingUid) {
11325                throw new IllegalArgumentException(
11326                        "Receiver requested to register for uid " + callingUid
11327                        + " was previously registered for uid " + rl.uid);
11328            } else if (rl.pid != callingPid) {
11329                throw new IllegalArgumentException(
11330                        "Receiver requested to register for pid " + callingPid
11331                        + " was previously registered for pid " + rl.pid);
11332            } else if (rl.userId != userId) {
11333                throw new IllegalArgumentException(
11334                        "Receiver requested to register for user " + userId
11335                        + " was previously registered for user " + rl.userId);
11336            }
11337            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11338                    permission, callingUid, userId);
11339            rl.add(bf);
11340            if (!bf.debugCheck()) {
11341                Slog.w(TAG, "==> For Dynamic broadast");
11342            }
11343            mReceiverResolver.addFilter(bf);
11344
11345            // Enqueue broadcasts for all existing stickies that match
11346            // this filter.
11347            if (allSticky != null) {
11348                ArrayList receivers = new ArrayList();
11349                receivers.add(bf);
11350
11351                int N = allSticky.size();
11352                for (int i=0; i<N; i++) {
11353                    Intent intent = (Intent)allSticky.get(i);
11354                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11355                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11356                            null, -1, -1, null, receivers, null, 0, null, null,
11357                            false, true, true, -1);
11358                    queue.enqueueParallelBroadcastLocked(r);
11359                    queue.scheduleBroadcastsLocked();
11360                }
11361            }
11362
11363            return sticky;
11364        }
11365    }
11366
11367    public void unregisterReceiver(IIntentReceiver receiver) {
11368        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11369
11370        final long origId = Binder.clearCallingIdentity();
11371        try {
11372            boolean doTrim = false;
11373
11374            synchronized(this) {
11375                ReceiverList rl
11376                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11377                if (rl != null) {
11378                    if (rl.curBroadcast != null) {
11379                        BroadcastRecord r = rl.curBroadcast;
11380                        final boolean doNext = finishReceiverLocked(
11381                                receiver.asBinder(), r.resultCode, r.resultData,
11382                                r.resultExtras, r.resultAbort, true);
11383                        if (doNext) {
11384                            doTrim = true;
11385                            r.queue.processNextBroadcast(false);
11386                        }
11387                    }
11388
11389                    if (rl.app != null) {
11390                        rl.app.receivers.remove(rl);
11391                    }
11392                    removeReceiverLocked(rl);
11393                    if (rl.linkedToDeath) {
11394                        rl.linkedToDeath = false;
11395                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11396                    }
11397                }
11398            }
11399
11400            // If we actually concluded any broadcasts, we might now be able
11401            // to trim the recipients' apps from our working set
11402            if (doTrim) {
11403                trimApplications();
11404                return;
11405            }
11406
11407        } finally {
11408            Binder.restoreCallingIdentity(origId);
11409        }
11410    }
11411
11412    void removeReceiverLocked(ReceiverList rl) {
11413        mRegisteredReceivers.remove(rl.receiver.asBinder());
11414        int N = rl.size();
11415        for (int i=0; i<N; i++) {
11416            mReceiverResolver.removeFilter(rl.get(i));
11417        }
11418    }
11419
11420    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11421        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11422            ProcessRecord r = mLruProcesses.get(i);
11423            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11424                try {
11425                    r.thread.dispatchPackageBroadcast(cmd, packages);
11426                } catch (RemoteException ex) {
11427                }
11428            }
11429        }
11430    }
11431
11432    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11433            int[] users) {
11434        List<ResolveInfo> receivers = null;
11435        try {
11436            HashSet<ComponentName> singleUserReceivers = null;
11437            boolean scannedFirstReceivers = false;
11438            for (int user : users) {
11439                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11440                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11441                if (newReceivers != null && newReceivers.size() == 0) {
11442                    newReceivers = null;
11443                }
11444                if (receivers == null) {
11445                    receivers = newReceivers;
11446                } else if (newReceivers != null) {
11447                    // We need to concatenate the additional receivers
11448                    // found with what we have do far.  This would be easy,
11449                    // but we also need to de-dup any receivers that are
11450                    // singleUser.
11451                    if (!scannedFirstReceivers) {
11452                        // Collect any single user receivers we had already retrieved.
11453                        scannedFirstReceivers = true;
11454                        for (int i=0; i<receivers.size(); i++) {
11455                            ResolveInfo ri = receivers.get(i);
11456                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11457                                ComponentName cn = new ComponentName(
11458                                        ri.activityInfo.packageName, ri.activityInfo.name);
11459                                if (singleUserReceivers == null) {
11460                                    singleUserReceivers = new HashSet<ComponentName>();
11461                                }
11462                                singleUserReceivers.add(cn);
11463                            }
11464                        }
11465                    }
11466                    // Add the new results to the existing results, tracking
11467                    // and de-dupping single user receivers.
11468                    for (int i=0; i<newReceivers.size(); i++) {
11469                        ResolveInfo ri = newReceivers.get(i);
11470                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11471                            ComponentName cn = new ComponentName(
11472                                    ri.activityInfo.packageName, ri.activityInfo.name);
11473                            if (singleUserReceivers == null) {
11474                                singleUserReceivers = new HashSet<ComponentName>();
11475                            }
11476                            if (!singleUserReceivers.contains(cn)) {
11477                                singleUserReceivers.add(cn);
11478                                receivers.add(ri);
11479                            }
11480                        } else {
11481                            receivers.add(ri);
11482                        }
11483                    }
11484                }
11485            }
11486        } catch (RemoteException ex) {
11487            // pm is in same process, this will never happen.
11488        }
11489        return receivers;
11490    }
11491
11492    private final int broadcastIntentLocked(ProcessRecord callerApp,
11493            String callerPackage, Intent intent, String resolvedType,
11494            IIntentReceiver resultTo, int resultCode, String resultData,
11495            Bundle map, String requiredPermission,
11496            boolean ordered, boolean sticky, int callingPid, int callingUid,
11497            int userId) {
11498        intent = new Intent(intent);
11499
11500        // By default broadcasts do not go to stopped apps.
11501        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11502
11503        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11504            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11505            + " ordered=" + ordered + " userid=" + userId);
11506        if ((resultTo != null) && !ordered) {
11507            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11508        }
11509
11510        userId = handleIncomingUserLocked(callingPid, callingUid, userId,
11511                true, false, "broadcast", callerPackage);
11512
11513        // Make sure that the user who is receiving this broadcast is started.
11514        // If not, we will just skip it.
11515        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11516            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
11517                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
11518                Slog.w(TAG, "Skipping broadcast of " + intent
11519                        + ": user " + userId + " is stopped");
11520                return ActivityManager.BROADCAST_SUCCESS;
11521            }
11522        }
11523
11524        /*
11525         * Prevent non-system code (defined here to be non-persistent
11526         * processes) from sending protected broadcasts.
11527         */
11528        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11529            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11530            callingUid == 0) {
11531            // Always okay.
11532        } else if (callerApp == null || !callerApp.persistent) {
11533            try {
11534                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11535                        intent.getAction())) {
11536                    String msg = "Permission Denial: not allowed to send broadcast "
11537                            + intent.getAction() + " from pid="
11538                            + callingPid + ", uid=" + callingUid;
11539                    Slog.w(TAG, msg);
11540                    throw new SecurityException(msg);
11541                }
11542            } catch (RemoteException e) {
11543                Slog.w(TAG, "Remote exception", e);
11544                return ActivityManager.BROADCAST_SUCCESS;
11545            }
11546        }
11547
11548        // Handle special intents: if this broadcast is from the package
11549        // manager about a package being removed, we need to remove all of
11550        // its activities from the history stack.
11551        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11552                intent.getAction());
11553        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11554                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11555                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11556                || uidRemoved) {
11557            if (checkComponentPermission(
11558                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11559                    callingPid, callingUid, -1, true)
11560                    == PackageManager.PERMISSION_GRANTED) {
11561                if (uidRemoved) {
11562                    final Bundle intentExtras = intent.getExtras();
11563                    final int uid = intentExtras != null
11564                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11565                    if (uid >= 0) {
11566                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11567                        synchronized (bs) {
11568                            bs.removeUidStatsLocked(uid);
11569                        }
11570                    }
11571                } else {
11572                    // If resources are unavailable just force stop all
11573                    // those packages and flush the attribute cache as well.
11574                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11575                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11576                        if (list != null && (list.length > 0)) {
11577                            for (String pkg : list) {
11578                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11579                            }
11580                            sendPackageBroadcastLocked(
11581                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11582                        }
11583                    } else {
11584                        Uri data = intent.getData();
11585                        String ssp;
11586                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11587                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11588                                forceStopPackageLocked(ssp,
11589                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11590                                        false, userId);
11591                            }
11592                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11593                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11594                                        new String[] {ssp}, userId);
11595                            }
11596                        }
11597                    }
11598                }
11599            } else {
11600                String msg = "Permission Denial: " + intent.getAction()
11601                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11602                        + ", uid=" + callingUid + ")"
11603                        + " requires "
11604                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11605                Slog.w(TAG, msg);
11606                throw new SecurityException(msg);
11607            }
11608
11609        // Special case for adding a package: by default turn on compatibility
11610        // mode.
11611        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11612            Uri data = intent.getData();
11613            String ssp;
11614            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11615                mCompatModePackages.handlePackageAddedLocked(ssp,
11616                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11617            }
11618        }
11619
11620        /*
11621         * If this is the time zone changed action, queue up a message that will reset the timezone
11622         * of all currently running processes. This message will get queued up before the broadcast
11623         * happens.
11624         */
11625        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11626            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11627        }
11628
11629        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11630            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11631        }
11632
11633        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11634            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11635            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11636        }
11637
11638        // Add to the sticky list if requested.
11639        if (sticky) {
11640            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11641                    callingPid, callingUid)
11642                    != PackageManager.PERMISSION_GRANTED) {
11643                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11644                        + callingPid + ", uid=" + callingUid
11645                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11646                Slog.w(TAG, msg);
11647                throw new SecurityException(msg);
11648            }
11649            if (requiredPermission != null) {
11650                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11651                        + " and enforce permission " + requiredPermission);
11652                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11653            }
11654            if (intent.getComponent() != null) {
11655                throw new SecurityException(
11656                        "Sticky broadcasts can't target a specific component");
11657            }
11658            // We use userId directly here, since the "all" target is maintained
11659            // as a separate set of sticky broadcasts.
11660            if (userId != UserHandle.USER_ALL) {
11661                // But first, if this is not a broadcast to all users, then
11662                // make sure it doesn't conflict with an existing broadcast to
11663                // all users.
11664                HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11665                        UserHandle.USER_ALL);
11666                if (stickies != null) {
11667                    ArrayList<Intent> list = stickies.get(intent.getAction());
11668                    if (list != null) {
11669                        int N = list.size();
11670                        int i;
11671                        for (i=0; i<N; i++) {
11672                            if (intent.filterEquals(list.get(i))) {
11673                                throw new IllegalArgumentException(
11674                                        "Sticky broadcast " + intent + " for user "
11675                                        + userId + " conflicts with existing global broadcast");
11676                            }
11677                        }
11678                    }
11679                }
11680            }
11681            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11682            if (stickies == null) {
11683                stickies = new HashMap<String, ArrayList<Intent>>();
11684                mStickyBroadcasts.put(userId, stickies);
11685            }
11686            ArrayList<Intent> list = stickies.get(intent.getAction());
11687            if (list == null) {
11688                list = new ArrayList<Intent>();
11689                stickies.put(intent.getAction(), list);
11690            }
11691            int N = list.size();
11692            int i;
11693            for (i=0; i<N; i++) {
11694                if (intent.filterEquals(list.get(i))) {
11695                    // This sticky already exists, replace it.
11696                    list.set(i, new Intent(intent));
11697                    break;
11698                }
11699            }
11700            if (i >= N) {
11701                list.add(new Intent(intent));
11702            }
11703        }
11704
11705        int[] users;
11706        if (userId == UserHandle.USER_ALL) {
11707            // Caller wants broadcast to go to all started users.
11708            users = mStartedUserArray;
11709        } else {
11710            // Caller wants broadcast to go to one specific user.
11711            users = mCurrentUserArray;
11712        }
11713
11714        // Figure out who all will receive this broadcast.
11715        List receivers = null;
11716        List<BroadcastFilter> registeredReceivers = null;
11717        // Need to resolve the intent to interested receivers...
11718        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11719                 == 0) {
11720            receivers = collectReceiverComponents(intent, resolvedType, users);
11721        }
11722        if (intent.getComponent() == null) {
11723            registeredReceivers = mReceiverResolver.queryIntent(intent,
11724                    resolvedType, false, userId);
11725        }
11726
11727        final boolean replacePending =
11728                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11729
11730        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11731                + " replacePending=" + replacePending);
11732
11733        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11734        if (!ordered && NR > 0) {
11735            // If we are not serializing this broadcast, then send the
11736            // registered receivers separately so they don't wait for the
11737            // components to be launched.
11738            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11739            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11740                    callerPackage, callingPid, callingUid, requiredPermission,
11741                    registeredReceivers, resultTo, resultCode, resultData, map,
11742                    ordered, sticky, false, userId);
11743            if (DEBUG_BROADCAST) Slog.v(
11744                    TAG, "Enqueueing parallel broadcast " + r);
11745            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11746            if (!replaced) {
11747                queue.enqueueParallelBroadcastLocked(r);
11748                queue.scheduleBroadcastsLocked();
11749            }
11750            registeredReceivers = null;
11751            NR = 0;
11752        }
11753
11754        // Merge into one list.
11755        int ir = 0;
11756        if (receivers != null) {
11757            // A special case for PACKAGE_ADDED: do not allow the package
11758            // being added to see this broadcast.  This prevents them from
11759            // using this as a back door to get run as soon as they are
11760            // installed.  Maybe in the future we want to have a special install
11761            // broadcast or such for apps, but we'd like to deliberately make
11762            // this decision.
11763            String skipPackages[] = null;
11764            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11765                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11766                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11767                Uri data = intent.getData();
11768                if (data != null) {
11769                    String pkgName = data.getSchemeSpecificPart();
11770                    if (pkgName != null) {
11771                        skipPackages = new String[] { pkgName };
11772                    }
11773                }
11774            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11775                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11776            }
11777            if (skipPackages != null && (skipPackages.length > 0)) {
11778                for (String skipPackage : skipPackages) {
11779                    if (skipPackage != null) {
11780                        int NT = receivers.size();
11781                        for (int it=0; it<NT; it++) {
11782                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11783                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11784                                receivers.remove(it);
11785                                it--;
11786                                NT--;
11787                            }
11788                        }
11789                    }
11790                }
11791            }
11792
11793            int NT = receivers != null ? receivers.size() : 0;
11794            int it = 0;
11795            ResolveInfo curt = null;
11796            BroadcastFilter curr = null;
11797            while (it < NT && ir < NR) {
11798                if (curt == null) {
11799                    curt = (ResolveInfo)receivers.get(it);
11800                }
11801                if (curr == null) {
11802                    curr = registeredReceivers.get(ir);
11803                }
11804                if (curr.getPriority() >= curt.priority) {
11805                    // Insert this broadcast record into the final list.
11806                    receivers.add(it, curr);
11807                    ir++;
11808                    curr = null;
11809                    it++;
11810                    NT++;
11811                } else {
11812                    // Skip to the next ResolveInfo in the final list.
11813                    it++;
11814                    curt = null;
11815                }
11816            }
11817        }
11818        while (ir < NR) {
11819            if (receivers == null) {
11820                receivers = new ArrayList();
11821            }
11822            receivers.add(registeredReceivers.get(ir));
11823            ir++;
11824        }
11825
11826        if ((receivers != null && receivers.size() > 0)
11827                || resultTo != null) {
11828            BroadcastQueue queue = broadcastQueueForIntent(intent);
11829            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11830                    callerPackage, callingPid, callingUid, requiredPermission,
11831                    receivers, resultTo, resultCode, resultData, map, ordered,
11832                    sticky, false, userId);
11833            if (DEBUG_BROADCAST) Slog.v(
11834                    TAG, "Enqueueing ordered broadcast " + r
11835                    + ": prev had " + queue.mOrderedBroadcasts.size());
11836            if (DEBUG_BROADCAST) {
11837                int seq = r.intent.getIntExtra("seq", -1);
11838                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11839            }
11840            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11841            if (!replaced) {
11842                queue.enqueueOrderedBroadcastLocked(r);
11843                queue.scheduleBroadcastsLocked();
11844            }
11845        }
11846
11847        return ActivityManager.BROADCAST_SUCCESS;
11848    }
11849
11850    final Intent verifyBroadcastLocked(Intent intent) {
11851        // Refuse possible leaked file descriptors
11852        if (intent != null && intent.hasFileDescriptors() == true) {
11853            throw new IllegalArgumentException("File descriptors passed in Intent");
11854        }
11855
11856        int flags = intent.getFlags();
11857
11858        if (!mProcessesReady) {
11859            // if the caller really truly claims to know what they're doing, go
11860            // ahead and allow the broadcast without launching any receivers
11861            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11862                intent = new Intent(intent);
11863                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11864            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11865                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11866                        + " before boot completion");
11867                throw new IllegalStateException("Cannot broadcast before boot completed");
11868            }
11869        }
11870
11871        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11872            throw new IllegalArgumentException(
11873                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11874        }
11875
11876        return intent;
11877    }
11878
11879    public final int broadcastIntent(IApplicationThread caller,
11880            Intent intent, String resolvedType, IIntentReceiver resultTo,
11881            int resultCode, String resultData, Bundle map,
11882            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11883        enforceNotIsolatedCaller("broadcastIntent");
11884        synchronized(this) {
11885            intent = verifyBroadcastLocked(intent);
11886
11887            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11888            final int callingPid = Binder.getCallingPid();
11889            final int callingUid = Binder.getCallingUid();
11890            final long origId = Binder.clearCallingIdentity();
11891            int res = broadcastIntentLocked(callerApp,
11892                    callerApp != null ? callerApp.info.packageName : null,
11893                    intent, resolvedType, resultTo,
11894                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11895                    callingPid, callingUid, userId);
11896            Binder.restoreCallingIdentity(origId);
11897            return res;
11898        }
11899    }
11900
11901    int broadcastIntentInPackage(String packageName, int uid,
11902            Intent intent, String resolvedType, IIntentReceiver resultTo,
11903            int resultCode, String resultData, Bundle map,
11904            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11905        synchronized(this) {
11906            intent = verifyBroadcastLocked(intent);
11907
11908            final long origId = Binder.clearCallingIdentity();
11909            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11910                    resultTo, resultCode, resultData, map, requiredPermission,
11911                    serialized, sticky, -1, uid, userId);
11912            Binder.restoreCallingIdentity(origId);
11913            return res;
11914        }
11915    }
11916
11917    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11918        // Refuse possible leaked file descriptors
11919        if (intent != null && intent.hasFileDescriptors() == true) {
11920            throw new IllegalArgumentException("File descriptors passed in Intent");
11921        }
11922
11923        userId = handleIncomingUserLocked(Binder.getCallingPid(),
11924                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
11925
11926        synchronized(this) {
11927            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11928                    != PackageManager.PERMISSION_GRANTED) {
11929                String msg = "Permission Denial: unbroadcastIntent() from pid="
11930                        + Binder.getCallingPid()
11931                        + ", uid=" + Binder.getCallingUid()
11932                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11933                Slog.w(TAG, msg);
11934                throw new SecurityException(msg);
11935            }
11936            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11937            if (stickies != null) {
11938                ArrayList<Intent> list = stickies.get(intent.getAction());
11939                if (list != null) {
11940                    int N = list.size();
11941                    int i;
11942                    for (i=0; i<N; i++) {
11943                        if (intent.filterEquals(list.get(i))) {
11944                            list.remove(i);
11945                            break;
11946                        }
11947                    }
11948                    if (list.size() <= 0) {
11949                        stickies.remove(intent.getAction());
11950                    }
11951                }
11952                if (stickies.size() <= 0) {
11953                    mStickyBroadcasts.remove(userId);
11954                }
11955            }
11956        }
11957    }
11958
11959    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11960            String resultData, Bundle resultExtras, boolean resultAbort,
11961            boolean explicit) {
11962        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11963        if (r == null) {
11964            Slog.w(TAG, "finishReceiver called but not found on queue");
11965            return false;
11966        }
11967
11968        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11969                explicit);
11970    }
11971
11972    public void finishReceiver(IBinder who, int resultCode, String resultData,
11973            Bundle resultExtras, boolean resultAbort) {
11974        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11975
11976        // Refuse possible leaked file descriptors
11977        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11978            throw new IllegalArgumentException("File descriptors passed in Bundle");
11979        }
11980
11981        final long origId = Binder.clearCallingIdentity();
11982        try {
11983            boolean doNext = false;
11984            BroadcastRecord r = null;
11985
11986            synchronized(this) {
11987                r = broadcastRecordForReceiverLocked(who);
11988                if (r != null) {
11989                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11990                        resultData, resultExtras, resultAbort, true);
11991                }
11992            }
11993
11994            if (doNext) {
11995                r.queue.processNextBroadcast(false);
11996            }
11997            trimApplications();
11998        } finally {
11999            Binder.restoreCallingIdentity(origId);
12000        }
12001    }
12002
12003    // =========================================================
12004    // INSTRUMENTATION
12005    // =========================================================
12006
12007    public boolean startInstrumentation(ComponentName className,
12008            String profileFile, int flags, Bundle arguments,
12009            IInstrumentationWatcher watcher, int userId) {
12010        enforceNotIsolatedCaller("startInstrumentation");
12011        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
12012                userId, false, true, "startInstrumentation", null);
12013        // Refuse possible leaked file descriptors
12014        if (arguments != null && arguments.hasFileDescriptors()) {
12015            throw new IllegalArgumentException("File descriptors passed in Bundle");
12016        }
12017
12018        synchronized(this) {
12019            InstrumentationInfo ii = null;
12020            ApplicationInfo ai = null;
12021            try {
12022                ii = mContext.getPackageManager().getInstrumentationInfo(
12023                    className, STOCK_PM_FLAGS);
12024                ai = AppGlobals.getPackageManager().getApplicationInfo(
12025                        ii.targetPackage, STOCK_PM_FLAGS, userId);
12026            } catch (PackageManager.NameNotFoundException e) {
12027            } catch (RemoteException e) {
12028            }
12029            if (ii == null) {
12030                reportStartInstrumentationFailure(watcher, className,
12031                        "Unable to find instrumentation info for: " + className);
12032                return false;
12033            }
12034            if (ai == null) {
12035                reportStartInstrumentationFailure(watcher, className,
12036                        "Unable to find instrumentation target package: " + ii.targetPackage);
12037                return false;
12038            }
12039
12040            int match = mContext.getPackageManager().checkSignatures(
12041                    ii.targetPackage, ii.packageName);
12042            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12043                String msg = "Permission Denial: starting instrumentation "
12044                        + className + " from pid="
12045                        + Binder.getCallingPid()
12046                        + ", uid=" + Binder.getCallingPid()
12047                        + " not allowed because package " + ii.packageName
12048                        + " does not have a signature matching the target "
12049                        + ii.targetPackage;
12050                reportStartInstrumentationFailure(watcher, className, msg);
12051                throw new SecurityException(msg);
12052            }
12053
12054            final long origId = Binder.clearCallingIdentity();
12055            // Instrumentation can kill and relaunch even persistent processes
12056            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
12057            ProcessRecord app = addAppLocked(ai, false);
12058            app.instrumentationClass = className;
12059            app.instrumentationInfo = ai;
12060            app.instrumentationProfileFile = profileFile;
12061            app.instrumentationArguments = arguments;
12062            app.instrumentationWatcher = watcher;
12063            app.instrumentationResultClass = className;
12064            Binder.restoreCallingIdentity(origId);
12065        }
12066
12067        return true;
12068    }
12069
12070    /**
12071     * Report errors that occur while attempting to start Instrumentation.  Always writes the
12072     * error to the logs, but if somebody is watching, send the report there too.  This enables
12073     * the "am" command to report errors with more information.
12074     *
12075     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12076     * @param cn The component name of the instrumentation.
12077     * @param report The error report.
12078     */
12079    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12080            ComponentName cn, String report) {
12081        Slog.w(TAG, report);
12082        try {
12083            if (watcher != null) {
12084                Bundle results = new Bundle();
12085                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12086                results.putString("Error", report);
12087                watcher.instrumentationStatus(cn, -1, results);
12088            }
12089        } catch (RemoteException e) {
12090            Slog.w(TAG, e);
12091        }
12092    }
12093
12094    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12095        if (app.instrumentationWatcher != null) {
12096            try {
12097                // NOTE:  IInstrumentationWatcher *must* be oneway here
12098                app.instrumentationWatcher.instrumentationFinished(
12099                    app.instrumentationClass,
12100                    resultCode,
12101                    results);
12102            } catch (RemoteException e) {
12103            }
12104        }
12105        app.instrumentationWatcher = null;
12106        app.instrumentationClass = null;
12107        app.instrumentationInfo = null;
12108        app.instrumentationProfileFile = null;
12109        app.instrumentationArguments = null;
12110
12111        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12112    }
12113
12114    public void finishInstrumentation(IApplicationThread target,
12115            int resultCode, Bundle results) {
12116        int userId = UserHandle.getCallingUserId();
12117        // Refuse possible leaked file descriptors
12118        if (results != null && results.hasFileDescriptors()) {
12119            throw new IllegalArgumentException("File descriptors passed in Intent");
12120        }
12121
12122        synchronized(this) {
12123            ProcessRecord app = getRecordForAppLocked(target);
12124            if (app == null) {
12125                Slog.w(TAG, "finishInstrumentation: no app for " + target);
12126                return;
12127            }
12128            final long origId = Binder.clearCallingIdentity();
12129            finishInstrumentationLocked(app, resultCode, results);
12130            Binder.restoreCallingIdentity(origId);
12131        }
12132    }
12133
12134    // =========================================================
12135    // CONFIGURATION
12136    // =========================================================
12137
12138    public ConfigurationInfo getDeviceConfigurationInfo() {
12139        ConfigurationInfo config = new ConfigurationInfo();
12140        synchronized (this) {
12141            config.reqTouchScreen = mConfiguration.touchscreen;
12142            config.reqKeyboardType = mConfiguration.keyboard;
12143            config.reqNavigation = mConfiguration.navigation;
12144            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12145                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12146                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12147            }
12148            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12149                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12150                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12151            }
12152            config.reqGlEsVersion = GL_ES_VERSION;
12153        }
12154        return config;
12155    }
12156
12157    public Configuration getConfiguration() {
12158        Configuration ci;
12159        synchronized(this) {
12160            ci = new Configuration(mConfiguration);
12161        }
12162        return ci;
12163    }
12164
12165    public void updatePersistentConfiguration(Configuration values) {
12166        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12167                "updateConfiguration()");
12168        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12169                "updateConfiguration()");
12170        if (values == null) {
12171            throw new NullPointerException("Configuration must not be null");
12172        }
12173
12174        synchronized(this) {
12175            final long origId = Binder.clearCallingIdentity();
12176            updateConfigurationLocked(values, null, true, false);
12177            Binder.restoreCallingIdentity(origId);
12178        }
12179    }
12180
12181    public void updateConfiguration(Configuration values) {
12182        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12183                "updateConfiguration()");
12184
12185        synchronized(this) {
12186            if (values == null && mWindowManager != null) {
12187                // sentinel: fetch the current configuration from the window manager
12188                values = mWindowManager.computeNewConfiguration();
12189            }
12190
12191            if (mWindowManager != null) {
12192                mProcessList.applyDisplaySize(mWindowManager);
12193            }
12194
12195            final long origId = Binder.clearCallingIdentity();
12196            if (values != null) {
12197                Settings.System.clearConfiguration(values);
12198            }
12199            updateConfigurationLocked(values, null, false, false);
12200            Binder.restoreCallingIdentity(origId);
12201        }
12202    }
12203
12204    /**
12205     * Do either or both things: (1) change the current configuration, and (2)
12206     * make sure the given activity is running with the (now) current
12207     * configuration.  Returns true if the activity has been left running, or
12208     * false if <var>starting</var> is being destroyed to match the new
12209     * configuration.
12210     * @param persistent TODO
12211     */
12212    boolean updateConfigurationLocked(Configuration values,
12213            ActivityRecord starting, boolean persistent, boolean initLocale) {
12214        // do nothing if we are headless
12215        if (mHeadless) return true;
12216
12217        int changes = 0;
12218
12219        boolean kept = true;
12220
12221        if (values != null) {
12222            Configuration newConfig = new Configuration(mConfiguration);
12223            changes = newConfig.updateFrom(values);
12224            if (changes != 0) {
12225                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12226                    Slog.i(TAG, "Updating configuration to: " + values);
12227                }
12228
12229                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12230
12231                if (values.locale != null && !initLocale) {
12232                    saveLocaleLocked(values.locale,
12233                                     !values.locale.equals(mConfiguration.locale),
12234                                     values.userSetLocale);
12235                }
12236
12237                mConfigurationSeq++;
12238                if (mConfigurationSeq <= 0) {
12239                    mConfigurationSeq = 1;
12240                }
12241                newConfig.seq = mConfigurationSeq;
12242                mConfiguration = newConfig;
12243                Slog.i(TAG, "Config changed: " + newConfig);
12244
12245                final Configuration configCopy = new Configuration(mConfiguration);
12246
12247                // TODO: If our config changes, should we auto dismiss any currently
12248                // showing dialogs?
12249                mShowDialogs = shouldShowDialogs(newConfig);
12250
12251                AttributeCache ac = AttributeCache.instance();
12252                if (ac != null) {
12253                    ac.updateConfiguration(configCopy);
12254                }
12255
12256                // Make sure all resources in our process are updated
12257                // right now, so that anyone who is going to retrieve
12258                // resource values after we return will be sure to get
12259                // the new ones.  This is especially important during
12260                // boot, where the first config change needs to guarantee
12261                // all resources have that config before following boot
12262                // code is executed.
12263                mSystemThread.applyConfigurationToResources(configCopy);
12264
12265                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12266                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12267                    msg.obj = new Configuration(configCopy);
12268                    mHandler.sendMessage(msg);
12269                }
12270
12271                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12272                    ProcessRecord app = mLruProcesses.get(i);
12273                    try {
12274                        if (app.thread != null) {
12275                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12276                                    + app.processName + " new config " + mConfiguration);
12277                            app.thread.scheduleConfigurationChanged(configCopy);
12278                        }
12279                    } catch (Exception e) {
12280                    }
12281                }
12282                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12283                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12284                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
12285                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12286                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12287                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12288                    broadcastIntentLocked(null, null,
12289                            new Intent(Intent.ACTION_LOCALE_CHANGED),
12290                            null, null, 0, null, null,
12291                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12292                }
12293            }
12294        }
12295
12296        if (changes != 0 && starting == null) {
12297            // If the configuration changed, and the caller is not already
12298            // in the process of starting an activity, then find the top
12299            // activity to check if its configuration needs to change.
12300            starting = mMainStack.topRunningActivityLocked(null);
12301        }
12302
12303        if (starting != null) {
12304            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12305            // And we need to make sure at this point that all other activities
12306            // are made visible with the correct configuration.
12307            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12308        }
12309
12310        if (values != null && mWindowManager != null) {
12311            mWindowManager.setNewConfiguration(mConfiguration);
12312        }
12313
12314        return kept;
12315    }
12316
12317    /**
12318     * Decide based on the configuration whether we should shouw the ANR,
12319     * crash, etc dialogs.  The idea is that if there is no affordnace to
12320     * press the on-screen buttons, we shouldn't show the dialog.
12321     *
12322     * A thought: SystemUI might also want to get told about this, the Power
12323     * dialog / global actions also might want different behaviors.
12324     */
12325    private static final boolean shouldShowDialogs(Configuration config) {
12326        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12327                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12328    }
12329
12330    /**
12331     * Save the locale.  You must be inside a synchronized (this) block.
12332     */
12333    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12334        if(isDiff) {
12335            SystemProperties.set("user.language", l.getLanguage());
12336            SystemProperties.set("user.region", l.getCountry());
12337        }
12338
12339        if(isPersist) {
12340            SystemProperties.set("persist.sys.language", l.getLanguage());
12341            SystemProperties.set("persist.sys.country", l.getCountry());
12342            SystemProperties.set("persist.sys.localevar", l.getVariant());
12343        }
12344    }
12345
12346    @Override
12347    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12348        ActivityRecord srec = ActivityRecord.forToken(token);
12349        return srec != null && srec.task.affinity != null &&
12350                srec.task.affinity.equals(destAffinity);
12351    }
12352
12353    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12354            Intent resultData) {
12355        ComponentName dest = destIntent.getComponent();
12356
12357        synchronized (this) {
12358            ActivityRecord srec = ActivityRecord.forToken(token);
12359            if (srec == null) {
12360                return false;
12361            }
12362            ArrayList<ActivityRecord> history = srec.stack.mHistory;
12363            final int start = history.indexOf(srec);
12364            if (start < 0) {
12365                // Current activity is not in history stack; do nothing.
12366                return false;
12367            }
12368            int finishTo = start - 1;
12369            ActivityRecord parent = null;
12370            boolean foundParentInTask = false;
12371            if (dest != null) {
12372                TaskRecord tr = srec.task;
12373                for (int i = start - 1; i >= 0; i--) {
12374                    ActivityRecord r = history.get(i);
12375                    if (tr != r.task) {
12376                        // Couldn't find parent in the same task; stop at the one above this.
12377                        // (Root of current task; in-app "home" behavior)
12378                        // Always at least finish the current activity.
12379                        finishTo = Math.min(start - 1, i + 1);
12380                        parent = history.get(finishTo);
12381                        break;
12382                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
12383                            r.info.name.equals(dest.getClassName())) {
12384                        finishTo = i;
12385                        parent = r;
12386                        foundParentInTask = true;
12387                        break;
12388                    }
12389                }
12390            }
12391
12392            if (mController != null) {
12393                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12394                if (next != null) {
12395                    // ask watcher if this is allowed
12396                    boolean resumeOK = true;
12397                    try {
12398                        resumeOK = mController.activityResuming(next.packageName);
12399                    } catch (RemoteException e) {
12400                        mController = null;
12401                    }
12402
12403                    if (!resumeOK) {
12404                        return false;
12405                    }
12406                }
12407            }
12408            final long origId = Binder.clearCallingIdentity();
12409            for (int i = start; i > finishTo; i--) {
12410                ActivityRecord r = history.get(i);
12411                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12412                        "navigate-up", true);
12413                // Only return the supplied result for the first activity finished
12414                resultCode = Activity.RESULT_CANCELED;
12415                resultData = null;
12416            }
12417
12418            if (parent != null && foundParentInTask) {
12419                final int parentLaunchMode = parent.info.launchMode;
12420                final int destIntentFlags = destIntent.getFlags();
12421                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12422                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12423                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12424                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12425                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12426                } else {
12427                    try {
12428                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12429                                destIntent.getComponent(), 0, UserHandle.getCallingUserId());
12430                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12431                                null, aInfo, parent.appToken, null,
12432                                0, -1, parent.launchedFromUid, 0, null, true, null);
12433                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12434                    } catch (RemoteException e) {
12435                        foundParentInTask = false;
12436                    }
12437                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12438                            resultData, "navigate-up", true);
12439                }
12440            }
12441            Binder.restoreCallingIdentity(origId);
12442            return foundParentInTask;
12443        }
12444    }
12445
12446    public int getLaunchedFromUid(IBinder activityToken) {
12447        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12448        if (srec == null) {
12449            return -1;
12450        }
12451        return srec.launchedFromUid;
12452    }
12453
12454    // =========================================================
12455    // LIFETIME MANAGEMENT
12456    // =========================================================
12457
12458    // Returns which broadcast queue the app is the current [or imminent] receiver
12459    // on, or 'null' if the app is not an active broadcast recipient.
12460    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12461        BroadcastRecord r = app.curReceiver;
12462        if (r != null) {
12463            return r.queue;
12464        }
12465
12466        // It's not the current receiver, but it might be starting up to become one
12467        synchronized (this) {
12468            for (BroadcastQueue queue : mBroadcastQueues) {
12469                r = queue.mPendingBroadcast;
12470                if (r != null && r.curApp == app) {
12471                    // found it; report which queue it's in
12472                    return queue;
12473                }
12474            }
12475        }
12476
12477        return null;
12478    }
12479
12480    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12481            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12482        if (mAdjSeq == app.adjSeq) {
12483            // This adjustment has already been computed.  If we are calling
12484            // from the top, we may have already computed our adjustment with
12485            // an earlier hidden adjustment that isn't really for us... if
12486            // so, use the new hidden adjustment.
12487            if (!recursed && app.hidden) {
12488                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12489                        app.hasActivities ? hiddenAdj : emptyAdj;
12490            }
12491            return app.curRawAdj;
12492        }
12493
12494        if (app.thread == null) {
12495            app.adjSeq = mAdjSeq;
12496            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12497            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12498        }
12499
12500        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12501        app.adjSource = null;
12502        app.adjTarget = null;
12503        app.empty = false;
12504        app.hidden = false;
12505
12506        final int activitiesSize = app.activities.size();
12507
12508        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12509            // The max adjustment doesn't allow this app to be anything
12510            // below foreground, so it is not worth doing work for it.
12511            app.adjType = "fixed";
12512            app.adjSeq = mAdjSeq;
12513            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12514            app.hasActivities = false;
12515            app.foregroundActivities = false;
12516            app.keeping = true;
12517            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12518            // System process can do UI, and when they do we want to have
12519            // them trim their memory after the user leaves the UI.  To
12520            // facilitate this, here we need to determine whether or not it
12521            // is currently showing UI.
12522            app.systemNoUi = true;
12523            if (app == TOP_APP) {
12524                app.systemNoUi = false;
12525                app.hasActivities = true;
12526            } else if (activitiesSize > 0) {
12527                for (int j = 0; j < activitiesSize; j++) {
12528                    final ActivityRecord r = app.activities.get(j);
12529                    if (r.visible) {
12530                        app.systemNoUi = false;
12531                    }
12532                    if (r.app == app) {
12533                        app.hasActivities = true;
12534                    }
12535                }
12536            }
12537            return (app.curAdj=app.maxAdj);
12538        }
12539
12540        app.keeping = false;
12541        app.systemNoUi = false;
12542        app.hasActivities = false;
12543
12544        // Determine the importance of the process, starting with most
12545        // important to least, and assign an appropriate OOM adjustment.
12546        int adj;
12547        int schedGroup;
12548        boolean foregroundActivities = false;
12549        boolean interesting = false;
12550        BroadcastQueue queue;
12551        if (app == TOP_APP) {
12552            // The last app on the list is the foreground app.
12553            adj = ProcessList.FOREGROUND_APP_ADJ;
12554            schedGroup = Process.THREAD_GROUP_DEFAULT;
12555            app.adjType = "top-activity";
12556            foregroundActivities = true;
12557            interesting = true;
12558            app.hasActivities = true;
12559        } else if (app.instrumentationClass != null) {
12560            // Don't want to kill running instrumentation.
12561            adj = ProcessList.FOREGROUND_APP_ADJ;
12562            schedGroup = Process.THREAD_GROUP_DEFAULT;
12563            app.adjType = "instrumentation";
12564            interesting = true;
12565        } else if ((queue = isReceivingBroadcast(app)) != null) {
12566            // An app that is currently receiving a broadcast also
12567            // counts as being in the foreground for OOM killer purposes.
12568            // It's placed in a sched group based on the nature of the
12569            // broadcast as reflected by which queue it's active in.
12570            adj = ProcessList.FOREGROUND_APP_ADJ;
12571            schedGroup = (queue == mFgBroadcastQueue)
12572                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12573            app.adjType = "broadcast";
12574        } else if (app.executingServices.size() > 0) {
12575            // An app that is currently executing a service callback also
12576            // counts as being in the foreground.
12577            adj = ProcessList.FOREGROUND_APP_ADJ;
12578            schedGroup = Process.THREAD_GROUP_DEFAULT;
12579            app.adjType = "exec-service";
12580        } else {
12581            // Assume process is hidden (has activities); we will correct
12582            // later if this is not the case.
12583            adj = hiddenAdj;
12584            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12585            app.hidden = true;
12586            app.adjType = "bg-activities";
12587        }
12588
12589        boolean hasStoppingActivities = false;
12590
12591        // Examine all activities if not already foreground.
12592        if (!foregroundActivities && activitiesSize > 0) {
12593            for (int j = 0; j < activitiesSize; j++) {
12594                final ActivityRecord r = app.activities.get(j);
12595                if (r.visible) {
12596                    // App has a visible activity; only upgrade adjustment.
12597                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12598                        adj = ProcessList.VISIBLE_APP_ADJ;
12599                        app.adjType = "visible";
12600                    }
12601                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12602                    app.hidden = false;
12603                    app.hasActivities = true;
12604                    foregroundActivities = true;
12605                    break;
12606                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12607                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12608                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12609                        app.adjType = "pausing";
12610                    }
12611                    app.hidden = false;
12612                    foregroundActivities = true;
12613                } else if (r.state == ActivityState.STOPPING) {
12614                    // We will apply the actual adjustment later, because
12615                    // we want to allow this process to immediately go through
12616                    // any memory trimming that is in effect.
12617                    app.hidden = false;
12618                    foregroundActivities = true;
12619                    hasStoppingActivities = true;
12620                }
12621                if (r.app == app) {
12622                    app.hasActivities = true;
12623                }
12624            }
12625        }
12626
12627        if (adj == hiddenAdj && !app.hasActivities) {
12628            // Whoops, this process is completely empty as far as we know
12629            // at this point.
12630            adj = emptyAdj;
12631            app.empty = true;
12632            app.adjType = "bg-empty";
12633        }
12634
12635        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12636            if (app.foregroundServices) {
12637                // The user is aware of this app, so make it visible.
12638                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12639                app.hidden = false;
12640                app.adjType = "foreground-service";
12641                schedGroup = Process.THREAD_GROUP_DEFAULT;
12642            } else if (app.forcingToForeground != null) {
12643                // The user is aware of this app, so make it visible.
12644                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12645                app.hidden = false;
12646                app.adjType = "force-foreground";
12647                app.adjSource = app.forcingToForeground;
12648                schedGroup = Process.THREAD_GROUP_DEFAULT;
12649            }
12650        }
12651
12652        if (app.foregroundServices) {
12653            interesting = true;
12654        }
12655
12656        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12657            // We don't want to kill the current heavy-weight process.
12658            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12659            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12660            app.hidden = false;
12661            app.adjType = "heavy";
12662        }
12663
12664        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12665            // This process is hosting what we currently consider to be the
12666            // home app, so we don't want to let it go into the background.
12667            adj = ProcessList.HOME_APP_ADJ;
12668            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12669            app.hidden = false;
12670            app.adjType = "home";
12671        }
12672
12673        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12674                && app.activities.size() > 0) {
12675            // This was the previous process that showed UI to the user.
12676            // We want to try to keep it around more aggressively, to give
12677            // a good experience around switching between two apps.
12678            adj = ProcessList.PREVIOUS_APP_ADJ;
12679            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12680            app.hidden = false;
12681            app.adjType = "previous";
12682        }
12683
12684        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12685                + " reason=" + app.adjType);
12686
12687        // By default, we use the computed adjustment.  It may be changed if
12688        // there are applications dependent on our services or providers, but
12689        // this gives us a baseline and makes sure we don't get into an
12690        // infinite recursion.
12691        app.adjSeq = mAdjSeq;
12692        app.curRawAdj = app.nonStoppingAdj = adj;
12693
12694        if (mBackupTarget != null && app == mBackupTarget.app) {
12695            // If possible we want to avoid killing apps while they're being backed up
12696            if (adj > ProcessList.BACKUP_APP_ADJ) {
12697                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12698                adj = ProcessList.BACKUP_APP_ADJ;
12699                app.adjType = "backup";
12700                app.hidden = false;
12701            }
12702        }
12703
12704        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12705                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12706            final long now = SystemClock.uptimeMillis();
12707            // This process is more important if the top activity is
12708            // bound to the service.
12709            Iterator<ServiceRecord> jt = app.services.iterator();
12710            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12711                ServiceRecord s = jt.next();
12712                if (s.startRequested) {
12713                    if (app.hasShownUi && app != mHomeProcess) {
12714                        // If this process has shown some UI, let it immediately
12715                        // go to the LRU list because it may be pretty heavy with
12716                        // UI stuff.  We'll tag it with a label just to help
12717                        // debug and understand what is going on.
12718                        if (adj > ProcessList.SERVICE_ADJ) {
12719                            app.adjType = "started-bg-ui-services";
12720                        }
12721                    } else {
12722                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12723                            // This service has seen some activity within
12724                            // recent memory, so we will keep its process ahead
12725                            // of the background processes.
12726                            if (adj > ProcessList.SERVICE_ADJ) {
12727                                adj = ProcessList.SERVICE_ADJ;
12728                                app.adjType = "started-services";
12729                                app.hidden = false;
12730                            }
12731                        }
12732                        // If we have let the service slide into the background
12733                        // state, still have some text describing what it is doing
12734                        // even though the service no longer has an impact.
12735                        if (adj > ProcessList.SERVICE_ADJ) {
12736                            app.adjType = "started-bg-services";
12737                        }
12738                    }
12739                    // Don't kill this process because it is doing work; it
12740                    // has said it is doing work.
12741                    app.keeping = true;
12742                }
12743                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12744                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12745                    Iterator<ArrayList<ConnectionRecord>> kt
12746                            = s.connections.values().iterator();
12747                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12748                        ArrayList<ConnectionRecord> clist = kt.next();
12749                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12750                            // XXX should compute this based on the max of
12751                            // all connected clients.
12752                            ConnectionRecord cr = clist.get(i);
12753                            if (cr.binding.client == app) {
12754                                // Binding to ourself is not interesting.
12755                                continue;
12756                            }
12757                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12758                                ProcessRecord client = cr.binding.client;
12759                                int clientAdj = adj;
12760                                int myHiddenAdj = hiddenAdj;
12761                                if (myHiddenAdj > client.hiddenAdj) {
12762                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12763                                        myHiddenAdj = client.hiddenAdj;
12764                                    } else {
12765                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12766                                    }
12767                                }
12768                                int myEmptyAdj = emptyAdj;
12769                                if (myEmptyAdj > client.emptyAdj) {
12770                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12771                                        myEmptyAdj = client.emptyAdj;
12772                                    } else {
12773                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12774                                    }
12775                                }
12776                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12777                                        myEmptyAdj, TOP_APP, true, doingAll);
12778                                String adjType = null;
12779                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12780                                    // Not doing bind OOM management, so treat
12781                                    // this guy more like a started service.
12782                                    if (app.hasShownUi && app != mHomeProcess) {
12783                                        // If this process has shown some UI, let it immediately
12784                                        // go to the LRU list because it may be pretty heavy with
12785                                        // UI stuff.  We'll tag it with a label just to help
12786                                        // debug and understand what is going on.
12787                                        if (adj > clientAdj) {
12788                                            adjType = "bound-bg-ui-services";
12789                                        }
12790                                        app.hidden = false;
12791                                        clientAdj = adj;
12792                                    } else {
12793                                        if (now >= (s.lastActivity
12794                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12795                                            // This service has not seen activity within
12796                                            // recent memory, so allow it to drop to the
12797                                            // LRU list if there is no other reason to keep
12798                                            // it around.  We'll also tag it with a label just
12799                                            // to help debug and undertand what is going on.
12800                                            if (adj > clientAdj) {
12801                                                adjType = "bound-bg-services";
12802                                            }
12803                                            clientAdj = adj;
12804                                        }
12805                                    }
12806                                }
12807                                if (adj > clientAdj) {
12808                                    // If this process has recently shown UI, and
12809                                    // the process that is binding to it is less
12810                                    // important than being visible, then we don't
12811                                    // care about the binding as much as we care
12812                                    // about letting this process get into the LRU
12813                                    // list to be killed and restarted if needed for
12814                                    // memory.
12815                                    if (app.hasShownUi && app != mHomeProcess
12816                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12817                                        adjType = "bound-bg-ui-services";
12818                                    } else {
12819                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12820                                                |Context.BIND_IMPORTANT)) != 0) {
12821                                            adj = clientAdj;
12822                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12823                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12824                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12825                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12826                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12827                                            adj = clientAdj;
12828                                        } else {
12829                                            app.pendingUiClean = true;
12830                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12831                                                adj = ProcessList.VISIBLE_APP_ADJ;
12832                                            }
12833                                        }
12834                                        if (!client.hidden) {
12835                                            app.hidden = false;
12836                                        }
12837                                        if (client.keeping) {
12838                                            app.keeping = true;
12839                                        }
12840                                        adjType = "service";
12841                                    }
12842                                }
12843                                if (adjType != null) {
12844                                    app.adjType = adjType;
12845                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12846                                            .REASON_SERVICE_IN_USE;
12847                                    app.adjSource = cr.binding.client;
12848                                    app.adjSourceOom = clientAdj;
12849                                    app.adjTarget = s.name;
12850                                }
12851                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12852                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12853                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12854                                    }
12855                                }
12856                            }
12857                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12858                                ActivityRecord a = cr.activity;
12859                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12860                                        (a.visible || a.state == ActivityState.RESUMED
12861                                         || a.state == ActivityState.PAUSING)) {
12862                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12863                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12864                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12865                                    }
12866                                    app.hidden = false;
12867                                    app.adjType = "service";
12868                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12869                                            .REASON_SERVICE_IN_USE;
12870                                    app.adjSource = a;
12871                                    app.adjSourceOom = adj;
12872                                    app.adjTarget = s.name;
12873                                }
12874                            }
12875                        }
12876                    }
12877                }
12878            }
12879
12880            // Finally, if this process has active services running in it, we
12881            // would like to avoid killing it unless it would prevent the current
12882            // application from running.  By default we put the process in
12883            // with the rest of the background processes; as we scan through
12884            // its services we may bump it up from there.
12885            if (adj > hiddenAdj) {
12886                adj = hiddenAdj;
12887                app.hidden = false;
12888                app.adjType = "bg-services";
12889            }
12890        }
12891
12892        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12893                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12894            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12895            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12896                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12897                ContentProviderRecord cpr = jt.next();
12898                for (int i = cpr.connections.size()-1;
12899                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12900                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12901                        i--) {
12902                    ContentProviderConnection conn = cpr.connections.get(i);
12903                    ProcessRecord client = conn.client;
12904                    if (client == app) {
12905                        // Being our own client is not interesting.
12906                        continue;
12907                    }
12908                    int myHiddenAdj = hiddenAdj;
12909                    if (myHiddenAdj > client.hiddenAdj) {
12910                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12911                            myHiddenAdj = client.hiddenAdj;
12912                        } else {
12913                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12914                        }
12915                    }
12916                    int myEmptyAdj = emptyAdj;
12917                    if (myEmptyAdj > client.emptyAdj) {
12918                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12919                            myEmptyAdj = client.emptyAdj;
12920                        } else {
12921                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12922                        }
12923                    }
12924                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12925                            myEmptyAdj, TOP_APP, true, doingAll);
12926                    if (adj > clientAdj) {
12927                        if (app.hasShownUi && app != mHomeProcess
12928                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12929                            app.adjType = "bg-ui-provider";
12930                        } else {
12931                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12932                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12933                            app.adjType = "provider";
12934                        }
12935                        if (!client.hidden) {
12936                            app.hidden = false;
12937                        }
12938                        if (client.keeping) {
12939                            app.keeping = true;
12940                        }
12941                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12942                                .REASON_PROVIDER_IN_USE;
12943                        app.adjSource = client;
12944                        app.adjSourceOom = clientAdj;
12945                        app.adjTarget = cpr.name;
12946                    }
12947                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12948                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12949                    }
12950                }
12951                // If the provider has external (non-framework) process
12952                // dependencies, ensure that its adjustment is at least
12953                // FOREGROUND_APP_ADJ.
12954                if (cpr.hasExternalProcessHandles()) {
12955                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12956                        adj = ProcessList.FOREGROUND_APP_ADJ;
12957                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12958                        app.hidden = false;
12959                        app.keeping = true;
12960                        app.adjType = "provider";
12961                        app.adjTarget = cpr.name;
12962                    }
12963                }
12964            }
12965        }
12966
12967        if (adj == ProcessList.SERVICE_ADJ) {
12968            if (doingAll) {
12969                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12970                mNewNumServiceProcs++;
12971            }
12972            if (app.serviceb) {
12973                adj = ProcessList.SERVICE_B_ADJ;
12974            }
12975        } else {
12976            app.serviceb = false;
12977        }
12978
12979        app.nonStoppingAdj = adj;
12980
12981        if (hasStoppingActivities) {
12982            // Only upgrade adjustment.
12983            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12984                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12985                app.adjType = "stopping";
12986            }
12987        }
12988
12989        app.curRawAdj = adj;
12990
12991        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12992        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12993        if (adj > app.maxAdj) {
12994            adj = app.maxAdj;
12995            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12996                schedGroup = Process.THREAD_GROUP_DEFAULT;
12997            }
12998        }
12999        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13000            app.keeping = true;
13001        }
13002
13003        if (app.hasAboveClient) {
13004            // If this process has bound to any services with BIND_ABOVE_CLIENT,
13005            // then we need to drop its adjustment to be lower than the service's
13006            // in order to honor the request.  We want to drop it by one adjustment
13007            // level...  but there is special meaning applied to various levels so
13008            // we will skip some of them.
13009            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
13010                // System process will not get dropped, ever
13011            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13012                adj = ProcessList.VISIBLE_APP_ADJ;
13013            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13014                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13015            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13016                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13017            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
13018                adj++;
13019            }
13020        }
13021
13022        int importance = app.memImportance;
13023        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
13024            app.curAdj = adj;
13025            app.curSchedGroup = schedGroup;
13026            if (!interesting) {
13027                // For this reporting, if there is not something explicitly
13028                // interesting in this process then we will push it to the
13029                // background importance.
13030                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13031            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13032                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13033            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
13034                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13035            } else if (adj >= ProcessList.HOME_APP_ADJ) {
13036                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13037            } else if (adj >= ProcessList.SERVICE_ADJ) {
13038                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13039            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13040                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
13041            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
13042                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
13043            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
13044                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
13045            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
13046                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
13047            } else {
13048                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
13049            }
13050        }
13051
13052        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
13053        if (foregroundActivities != app.foregroundActivities) {
13054            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
13055        }
13056        if (changes != 0) {
13057            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
13058            app.memImportance = importance;
13059            app.foregroundActivities = foregroundActivities;
13060            int i = mPendingProcessChanges.size()-1;
13061            ProcessChangeItem item = null;
13062            while (i >= 0) {
13063                item = mPendingProcessChanges.get(i);
13064                if (item.pid == app.pid) {
13065                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
13066                    break;
13067                }
13068                i--;
13069            }
13070            if (i < 0) {
13071                // No existing item in pending changes; need a new one.
13072                final int NA = mAvailProcessChanges.size();
13073                if (NA > 0) {
13074                    item = mAvailProcessChanges.remove(NA-1);
13075                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
13076                } else {
13077                    item = new ProcessChangeItem();
13078                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
13079                }
13080                item.changes = 0;
13081                item.pid = app.pid;
13082                item.uid = app.info.uid;
13083                if (mPendingProcessChanges.size() == 0) {
13084                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
13085                            "*** Enqueueing dispatch processes changed!");
13086                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
13087                }
13088                mPendingProcessChanges.add(item);
13089            }
13090            item.changes |= changes;
13091            item.importance = importance;
13092            item.foregroundActivities = foregroundActivities;
13093            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
13094                    + Integer.toHexString(System.identityHashCode(item))
13095                    + " " + app.toShortString() + ": changes=" + item.changes
13096                    + " importance=" + item.importance
13097                    + " foreground=" + item.foregroundActivities
13098                    + " type=" + app.adjType + " source=" + app.adjSource
13099                    + " target=" + app.adjTarget);
13100        }
13101
13102        return app.curRawAdj;
13103    }
13104
13105    /**
13106     * Ask a given process to GC right now.
13107     */
13108    final void performAppGcLocked(ProcessRecord app) {
13109        try {
13110            app.lastRequestedGc = SystemClock.uptimeMillis();
13111            if (app.thread != null) {
13112                if (app.reportLowMemory) {
13113                    app.reportLowMemory = false;
13114                    app.thread.scheduleLowMemory();
13115                } else {
13116                    app.thread.processInBackground();
13117                }
13118            }
13119        } catch (Exception e) {
13120            // whatever.
13121        }
13122    }
13123
13124    /**
13125     * Returns true if things are idle enough to perform GCs.
13126     */
13127    private final boolean canGcNowLocked() {
13128        boolean processingBroadcasts = false;
13129        for (BroadcastQueue q : mBroadcastQueues) {
13130            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13131                processingBroadcasts = true;
13132            }
13133        }
13134        return !processingBroadcasts
13135                && (mSleeping || (mMainStack.mResumedActivity != null &&
13136                        mMainStack.mResumedActivity.idle));
13137    }
13138
13139    /**
13140     * Perform GCs on all processes that are waiting for it, but only
13141     * if things are idle.
13142     */
13143    final void performAppGcsLocked() {
13144        final int N = mProcessesToGc.size();
13145        if (N <= 0) {
13146            return;
13147        }
13148        if (canGcNowLocked()) {
13149            while (mProcessesToGc.size() > 0) {
13150                ProcessRecord proc = mProcessesToGc.remove(0);
13151                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13152                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13153                            <= SystemClock.uptimeMillis()) {
13154                        // To avoid spamming the system, we will GC processes one
13155                        // at a time, waiting a few seconds between each.
13156                        performAppGcLocked(proc);
13157                        scheduleAppGcsLocked();
13158                        return;
13159                    } else {
13160                        // It hasn't been long enough since we last GCed this
13161                        // process...  put it in the list to wait for its time.
13162                        addProcessToGcListLocked(proc);
13163                        break;
13164                    }
13165                }
13166            }
13167
13168            scheduleAppGcsLocked();
13169        }
13170    }
13171
13172    /**
13173     * If all looks good, perform GCs on all processes waiting for them.
13174     */
13175    final void performAppGcsIfAppropriateLocked() {
13176        if (canGcNowLocked()) {
13177            performAppGcsLocked();
13178            return;
13179        }
13180        // Still not idle, wait some more.
13181        scheduleAppGcsLocked();
13182    }
13183
13184    /**
13185     * Schedule the execution of all pending app GCs.
13186     */
13187    final void scheduleAppGcsLocked() {
13188        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13189
13190        if (mProcessesToGc.size() > 0) {
13191            // Schedule a GC for the time to the next process.
13192            ProcessRecord proc = mProcessesToGc.get(0);
13193            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13194
13195            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13196            long now = SystemClock.uptimeMillis();
13197            if (when < (now+GC_TIMEOUT)) {
13198                when = now + GC_TIMEOUT;
13199            }
13200            mHandler.sendMessageAtTime(msg, when);
13201        }
13202    }
13203
13204    /**
13205     * Add a process to the array of processes waiting to be GCed.  Keeps the
13206     * list in sorted order by the last GC time.  The process can't already be
13207     * on the list.
13208     */
13209    final void addProcessToGcListLocked(ProcessRecord proc) {
13210        boolean added = false;
13211        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13212            if (mProcessesToGc.get(i).lastRequestedGc <
13213                    proc.lastRequestedGc) {
13214                added = true;
13215                mProcessesToGc.add(i+1, proc);
13216                break;
13217            }
13218        }
13219        if (!added) {
13220            mProcessesToGc.add(0, proc);
13221        }
13222    }
13223
13224    /**
13225     * Set up to ask a process to GC itself.  This will either do it
13226     * immediately, or put it on the list of processes to gc the next
13227     * time things are idle.
13228     */
13229    final void scheduleAppGcLocked(ProcessRecord app) {
13230        long now = SystemClock.uptimeMillis();
13231        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13232            return;
13233        }
13234        if (!mProcessesToGc.contains(app)) {
13235            addProcessToGcListLocked(app);
13236            scheduleAppGcsLocked();
13237        }
13238    }
13239
13240    final void checkExcessivePowerUsageLocked(boolean doKills) {
13241        updateCpuStatsNow();
13242
13243        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13244        boolean doWakeKills = doKills;
13245        boolean doCpuKills = doKills;
13246        if (mLastPowerCheckRealtime == 0) {
13247            doWakeKills = false;
13248        }
13249        if (mLastPowerCheckUptime == 0) {
13250            doCpuKills = false;
13251        }
13252        if (stats.isScreenOn()) {
13253            doWakeKills = false;
13254        }
13255        final long curRealtime = SystemClock.elapsedRealtime();
13256        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13257        final long curUptime = SystemClock.uptimeMillis();
13258        final long uptimeSince = curUptime - mLastPowerCheckUptime;
13259        mLastPowerCheckRealtime = curRealtime;
13260        mLastPowerCheckUptime = curUptime;
13261        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13262            doWakeKills = false;
13263        }
13264        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13265            doCpuKills = false;
13266        }
13267        int i = mLruProcesses.size();
13268        while (i > 0) {
13269            i--;
13270            ProcessRecord app = mLruProcesses.get(i);
13271            if (!app.keeping) {
13272                long wtime;
13273                synchronized (stats) {
13274                    wtime = stats.getProcessWakeTime(app.info.uid,
13275                            app.pid, curRealtime);
13276                }
13277                long wtimeUsed = wtime - app.lastWakeTime;
13278                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13279                if (DEBUG_POWER) {
13280                    StringBuilder sb = new StringBuilder(128);
13281                    sb.append("Wake for ");
13282                    app.toShortString(sb);
13283                    sb.append(": over ");
13284                    TimeUtils.formatDuration(realtimeSince, sb);
13285                    sb.append(" used ");
13286                    TimeUtils.formatDuration(wtimeUsed, sb);
13287                    sb.append(" (");
13288                    sb.append((wtimeUsed*100)/realtimeSince);
13289                    sb.append("%)");
13290                    Slog.i(TAG, sb.toString());
13291                    sb.setLength(0);
13292                    sb.append("CPU for ");
13293                    app.toShortString(sb);
13294                    sb.append(": over ");
13295                    TimeUtils.formatDuration(uptimeSince, sb);
13296                    sb.append(" used ");
13297                    TimeUtils.formatDuration(cputimeUsed, sb);
13298                    sb.append(" (");
13299                    sb.append((cputimeUsed*100)/uptimeSince);
13300                    sb.append("%)");
13301                    Slog.i(TAG, sb.toString());
13302                }
13303                // If a process has held a wake lock for more
13304                // than 50% of the time during this period,
13305                // that sounds bad.  Kill!
13306                if (doWakeKills && realtimeSince > 0
13307                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13308                    synchronized (stats) {
13309                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13310                                realtimeSince, wtimeUsed);
13311                    }
13312                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13313                            + " (pid " + app.pid + "): held " + wtimeUsed
13314                            + " during " + realtimeSince);
13315                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13316                            app.processName, app.setAdj, "excessive wake lock");
13317                    Process.killProcessQuiet(app.pid);
13318                } else if (doCpuKills && uptimeSince > 0
13319                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13320                    synchronized (stats) {
13321                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13322                                uptimeSince, cputimeUsed);
13323                    }
13324                    Slog.w(TAG, "Excessive CPU in " + app.processName
13325                            + " (pid " + app.pid + "): used " + cputimeUsed
13326                            + " during " + uptimeSince);
13327                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13328                            app.processName, app.setAdj, "excessive cpu");
13329                    Process.killProcessQuiet(app.pid);
13330                } else {
13331                    app.lastWakeTime = wtime;
13332                    app.lastCpuTime = app.curCpuTime;
13333                }
13334            }
13335        }
13336    }
13337
13338    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13339            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13340        app.hiddenAdj = hiddenAdj;
13341        app.emptyAdj = emptyAdj;
13342
13343        if (app.thread == null) {
13344            return false;
13345        }
13346
13347        final boolean wasKeeping = app.keeping;
13348
13349        boolean success = true;
13350
13351        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13352
13353        if (app.curRawAdj != app.setRawAdj) {
13354            if (wasKeeping && !app.keeping) {
13355                // This app is no longer something we want to keep.  Note
13356                // its current wake lock time to later know to kill it if
13357                // it is not behaving well.
13358                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13359                synchronized (stats) {
13360                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13361                            app.pid, SystemClock.elapsedRealtime());
13362                }
13363                app.lastCpuTime = app.curCpuTime;
13364            }
13365
13366            app.setRawAdj = app.curRawAdj;
13367        }
13368
13369        if (app.curAdj != app.setAdj) {
13370            if (Process.setOomAdj(app.pid, app.curAdj)) {
13371                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13372                    TAG, "Set " + app.pid + " " + app.processName +
13373                    " adj " + app.curAdj + ": " + app.adjType);
13374                app.setAdj = app.curAdj;
13375            } else {
13376                success = false;
13377                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13378            }
13379        }
13380        if (app.setSchedGroup != app.curSchedGroup) {
13381            app.setSchedGroup = app.curSchedGroup;
13382            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13383                    "Setting process group of " + app.processName
13384                    + " to " + app.curSchedGroup);
13385            if (app.waitingToKill != null &&
13386                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13387                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13388                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13389                        app.processName, app.setAdj, app.waitingToKill);
13390                app.killedBackground = true;
13391                Process.killProcessQuiet(app.pid);
13392                success = false;
13393            } else {
13394                if (true) {
13395                    long oldId = Binder.clearCallingIdentity();
13396                    try {
13397                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13398                    } catch (Exception e) {
13399                        Slog.w(TAG, "Failed setting process group of " + app.pid
13400                                + " to " + app.curSchedGroup);
13401                        e.printStackTrace();
13402                    } finally {
13403                        Binder.restoreCallingIdentity(oldId);
13404                    }
13405                } else {
13406                    if (app.thread != null) {
13407                        try {
13408                            app.thread.setSchedulingGroup(app.curSchedGroup);
13409                        } catch (RemoteException e) {
13410                        }
13411                    }
13412                }
13413            }
13414        }
13415        return success;
13416    }
13417
13418    private final ActivityRecord resumedAppLocked() {
13419        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13420        if (resumedActivity == null || resumedActivity.app == null) {
13421            resumedActivity = mMainStack.mPausingActivity;
13422            if (resumedActivity == null || resumedActivity.app == null) {
13423                resumedActivity = mMainStack.topRunningActivityLocked(null);
13424            }
13425        }
13426        return resumedActivity;
13427    }
13428
13429    final boolean updateOomAdjLocked(ProcessRecord app) {
13430        final ActivityRecord TOP_ACT = resumedAppLocked();
13431        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13432        int curAdj = app.curAdj;
13433        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13434            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13435
13436        mAdjSeq++;
13437
13438        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
13439                TOP_APP, false);
13440        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13441            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13442        if (nowHidden != wasHidden) {
13443            // Changed to/from hidden state, so apps after it in the LRU
13444            // list may also be changed.
13445            updateOomAdjLocked();
13446        }
13447        return success;
13448    }
13449
13450    final void updateOomAdjLocked() {
13451        final ActivityRecord TOP_ACT = resumedAppLocked();
13452        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13453
13454        if (false) {
13455            RuntimeException e = new RuntimeException();
13456            e.fillInStackTrace();
13457            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13458        }
13459
13460        mAdjSeq++;
13461        mNewNumServiceProcs = 0;
13462
13463        // Let's determine how many processes we have running vs.
13464        // how many slots we have for background processes; we may want
13465        // to put multiple processes in a slot of there are enough of
13466        // them.
13467        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13468                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13469        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
13470        if (emptyFactor < 1) emptyFactor = 1;
13471        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13472        if (hiddenFactor < 1) hiddenFactor = 1;
13473        int stepHidden = 0;
13474        int stepEmpty = 0;
13475        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13476        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13477        int numHidden = 0;
13478        int numEmpty = 0;
13479        int numTrimming = 0;
13480
13481        mNumNonHiddenProcs = 0;
13482        mNumHiddenProcs = 0;
13483
13484        // First update the OOM adjustment for each of the
13485        // application processes based on their current state.
13486        int i = mLruProcesses.size();
13487        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13488        int nextHiddenAdj = curHiddenAdj+1;
13489        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13490        int nextEmptyAdj = curEmptyAdj+2;
13491        while (i > 0) {
13492            i--;
13493            ProcessRecord app = mLruProcesses.get(i);
13494            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13495            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
13496            if (!app.killedBackground) {
13497                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13498                    // This process was assigned as a hidden process...  step the
13499                    // hidden level.
13500                    mNumHiddenProcs++;
13501                    if (curHiddenAdj != nextHiddenAdj) {
13502                        stepHidden++;
13503                        if (stepHidden >= hiddenFactor) {
13504                            stepHidden = 0;
13505                            curHiddenAdj = nextHiddenAdj;
13506                            nextHiddenAdj += 2;
13507                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13508                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13509                            }
13510                        }
13511                    }
13512                    numHidden++;
13513                    if (numHidden > hiddenProcessLimit) {
13514                        Slog.i(TAG, "No longer want " + app.processName
13515                                + " (pid " + app.pid + "): hidden #" + numHidden);
13516                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13517                                app.processName, app.setAdj, "too many background");
13518                        app.killedBackground = true;
13519                        Process.killProcessQuiet(app.pid);
13520                    }
13521                } else {
13522                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13523                        // This process was assigned as an empty process...  step the
13524                        // empty level.
13525                        if (curEmptyAdj != nextEmptyAdj) {
13526                            stepEmpty++;
13527                            if (stepEmpty >= emptyFactor) {
13528                                stepEmpty = 0;
13529                                curEmptyAdj = nextEmptyAdj;
13530                                nextEmptyAdj += 2;
13531                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13532                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13533                                }
13534                            }
13535                        }
13536                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13537                        mNumNonHiddenProcs++;
13538                    }
13539                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13540                        numEmpty++;
13541                        if (numEmpty > emptyProcessLimit) {
13542                            Slog.i(TAG, "No longer want " + app.processName
13543                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13544                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13545                                    app.processName, app.setAdj, "too many background");
13546                            app.killedBackground = true;
13547                            Process.killProcessQuiet(app.pid);
13548                        }
13549                    }
13550                }
13551                if (app.isolated && app.services.size() <= 0) {
13552                    // If this is an isolated process, and there are no
13553                    // services running in it, then the process is no longer
13554                    // needed.  We agressively kill these because we can by
13555                    // definition not re-use the same process again, and it is
13556                    // good to avoid having whatever code was running in them
13557                    // left sitting around after no longer needed.
13558                    Slog.i(TAG, "Isolated process " + app.processName
13559                            + " (pid " + app.pid + ") no longer needed");
13560                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13561                            app.processName, app.setAdj, "isolated not needed");
13562                    app.killedBackground = true;
13563                    Process.killProcessQuiet(app.pid);
13564                }
13565                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13566                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13567                        && !app.killedBackground) {
13568                    numTrimming++;
13569                }
13570            }
13571        }
13572
13573        mNumServiceProcs = mNewNumServiceProcs;
13574
13575        // Now determine the memory trimming level of background processes.
13576        // Unfortunately we need to start at the back of the list to do this
13577        // properly.  We only do this if the number of background apps we
13578        // are managing to keep around is less than half the maximum we desire;
13579        // if we are keeping a good number around, we'll let them use whatever
13580        // memory they want.
13581        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13582                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13583            final int numHiddenAndEmpty = numHidden + numEmpty;
13584            final int N = mLruProcesses.size();
13585            int factor = numTrimming/3;
13586            int minFactor = 2;
13587            if (mHomeProcess != null) minFactor++;
13588            if (mPreviousProcess != null) minFactor++;
13589            if (factor < minFactor) factor = minFactor;
13590            int step = 0;
13591            int fgTrimLevel;
13592            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13593                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13594            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13595                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13596            } else {
13597                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13598            }
13599            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13600            for (i=0; i<N; i++) {
13601                ProcessRecord app = mLruProcesses.get(i);
13602                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13603                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13604                        && !app.killedBackground) {
13605                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13606                        try {
13607                            app.thread.scheduleTrimMemory(curLevel);
13608                        } catch (RemoteException e) {
13609                        }
13610                        if (false) {
13611                            // For now we won't do this; our memory trimming seems
13612                            // to be good enough at this point that destroying
13613                            // activities causes more harm than good.
13614                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13615                                    && app != mHomeProcess && app != mPreviousProcess) {
13616                                // Need to do this on its own message because the stack may not
13617                                // be in a consistent state at this point.
13618                                // For these apps we will also finish their activities
13619                                // to help them free memory.
13620                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13621                            }
13622                        }
13623                    }
13624                    app.trimMemoryLevel = curLevel;
13625                    step++;
13626                    if (step >= factor) {
13627                        step = 0;
13628                        switch (curLevel) {
13629                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13630                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13631                                break;
13632                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13633                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13634                                break;
13635                        }
13636                    }
13637                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13638                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13639                            && app.thread != null) {
13640                        try {
13641                            app.thread.scheduleTrimMemory(
13642                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13643                        } catch (RemoteException e) {
13644                        }
13645                    }
13646                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13647                } else {
13648                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13649                            && app.pendingUiClean) {
13650                        // If this application is now in the background and it
13651                        // had done UI, then give it the special trim level to
13652                        // have it free UI resources.
13653                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13654                        if (app.trimMemoryLevel < level && app.thread != null) {
13655                            try {
13656                                app.thread.scheduleTrimMemory(level);
13657                            } catch (RemoteException e) {
13658                            }
13659                        }
13660                        app.pendingUiClean = false;
13661                    }
13662                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13663                        try {
13664                            app.thread.scheduleTrimMemory(fgTrimLevel);
13665                        } catch (RemoteException e) {
13666                        }
13667                    }
13668                    app.trimMemoryLevel = fgTrimLevel;
13669                }
13670            }
13671        } else {
13672            final int N = mLruProcesses.size();
13673            for (i=0; i<N; i++) {
13674                ProcessRecord app = mLruProcesses.get(i);
13675                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13676                        && app.pendingUiClean) {
13677                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13678                            && app.thread != null) {
13679                        try {
13680                            app.thread.scheduleTrimMemory(
13681                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13682                        } catch (RemoteException e) {
13683                        }
13684                    }
13685                    app.pendingUiClean = false;
13686                }
13687                app.trimMemoryLevel = 0;
13688            }
13689        }
13690
13691        if (mAlwaysFinishActivities) {
13692            // Need to do this on its own message because the stack may not
13693            // be in a consistent state at this point.
13694            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13695        }
13696    }
13697
13698    final void trimApplications() {
13699        synchronized (this) {
13700            int i;
13701
13702            // First remove any unused application processes whose package
13703            // has been removed.
13704            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13705                final ProcessRecord app = mRemovedProcesses.get(i);
13706                if (app.activities.size() == 0
13707                        && app.curReceiver == null && app.services.size() == 0) {
13708                    Slog.i(
13709                        TAG, "Exiting empty application process "
13710                        + app.processName + " ("
13711                        + (app.thread != null ? app.thread.asBinder() : null)
13712                        + ")\n");
13713                    if (app.pid > 0 && app.pid != MY_PID) {
13714                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13715                                app.processName, app.setAdj, "empty");
13716                        Process.killProcessQuiet(app.pid);
13717                    } else {
13718                        try {
13719                            app.thread.scheduleExit();
13720                        } catch (Exception e) {
13721                            // Ignore exceptions.
13722                        }
13723                    }
13724                    cleanUpApplicationRecordLocked(app, false, true, -1);
13725                    mRemovedProcesses.remove(i);
13726
13727                    if (app.persistent) {
13728                        if (app.persistent) {
13729                            addAppLocked(app.info, false);
13730                        }
13731                    }
13732                }
13733            }
13734
13735            // Now update the oom adj for all processes.
13736            updateOomAdjLocked();
13737        }
13738    }
13739
13740    /** This method sends the specified signal to each of the persistent apps */
13741    public void signalPersistentProcesses(int sig) throws RemoteException {
13742        if (sig != Process.SIGNAL_USR1) {
13743            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13744        }
13745
13746        synchronized (this) {
13747            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13748                    != PackageManager.PERMISSION_GRANTED) {
13749                throw new SecurityException("Requires permission "
13750                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13751            }
13752
13753            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13754                ProcessRecord r = mLruProcesses.get(i);
13755                if (r.thread != null && r.persistent) {
13756                    Process.sendSignal(r.pid, sig);
13757                }
13758            }
13759        }
13760    }
13761
13762    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13763        if (proc == null || proc == mProfileProc) {
13764            proc = mProfileProc;
13765            path = mProfileFile;
13766            profileType = mProfileType;
13767            clearProfilerLocked();
13768        }
13769        if (proc == null) {
13770            return;
13771        }
13772        try {
13773            proc.thread.profilerControl(false, path, null, profileType);
13774        } catch (RemoteException e) {
13775            throw new IllegalStateException("Process disappeared");
13776        }
13777    }
13778
13779    private void clearProfilerLocked() {
13780        if (mProfileFd != null) {
13781            try {
13782                mProfileFd.close();
13783            } catch (IOException e) {
13784            }
13785        }
13786        mProfileApp = null;
13787        mProfileProc = null;
13788        mProfileFile = null;
13789        mProfileType = 0;
13790        mAutoStopProfiler = false;
13791    }
13792
13793    public boolean profileControl(String process, int userId, boolean start,
13794            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13795
13796        try {
13797            synchronized (this) {
13798                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13799                // its own permission.
13800                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13801                        != PackageManager.PERMISSION_GRANTED) {
13802                    throw new SecurityException("Requires permission "
13803                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13804                }
13805
13806                if (start && fd == null) {
13807                    throw new IllegalArgumentException("null fd");
13808                }
13809
13810                ProcessRecord proc = null;
13811                if (process != null) {
13812                    proc = findProcessLocked(process, userId, "profileControl");
13813                }
13814
13815                if (start && (proc == null || proc.thread == null)) {
13816                    throw new IllegalArgumentException("Unknown process: " + process);
13817                }
13818
13819                if (start) {
13820                    stopProfilerLocked(null, null, 0);
13821                    setProfileApp(proc.info, proc.processName, path, fd, false);
13822                    mProfileProc = proc;
13823                    mProfileType = profileType;
13824                    try {
13825                        fd = fd.dup();
13826                    } catch (IOException e) {
13827                        fd = null;
13828                    }
13829                    proc.thread.profilerControl(start, path, fd, profileType);
13830                    fd = null;
13831                    mProfileFd = null;
13832                } else {
13833                    stopProfilerLocked(proc, path, profileType);
13834                    if (fd != null) {
13835                        try {
13836                            fd.close();
13837                        } catch (IOException e) {
13838                        }
13839                    }
13840                }
13841
13842                return true;
13843            }
13844        } catch (RemoteException e) {
13845            throw new IllegalStateException("Process disappeared");
13846        } finally {
13847            if (fd != null) {
13848                try {
13849                    fd.close();
13850                } catch (IOException e) {
13851                }
13852            }
13853        }
13854    }
13855
13856    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
13857        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
13858                userId, true, true, callName, null);
13859        ProcessRecord proc = null;
13860        try {
13861            int pid = Integer.parseInt(process);
13862            synchronized (mPidsSelfLocked) {
13863                proc = mPidsSelfLocked.get(pid);
13864            }
13865        } catch (NumberFormatException e) {
13866        }
13867
13868        if (proc == null) {
13869            HashMap<String, SparseArray<ProcessRecord>> all
13870                    = mProcessNames.getMap();
13871            SparseArray<ProcessRecord> procs = all.get(process);
13872            if (procs != null && procs.size() > 0) {
13873                proc = procs.valueAt(0);
13874                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
13875                    for (int i=1; i<procs.size(); i++) {
13876                        ProcessRecord thisProc = procs.valueAt(i);
13877                        if (thisProc.userId == userId) {
13878                            proc = thisProc;
13879                            break;
13880                        }
13881                    }
13882                }
13883            }
13884        }
13885
13886        return proc;
13887    }
13888
13889    public boolean dumpHeap(String process, int userId, boolean managed,
13890            String path, ParcelFileDescriptor fd) throws RemoteException {
13891
13892        try {
13893            synchronized (this) {
13894                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13895                // its own permission (same as profileControl).
13896                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13897                        != PackageManager.PERMISSION_GRANTED) {
13898                    throw new SecurityException("Requires permission "
13899                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13900                }
13901
13902                if (fd == null) {
13903                    throw new IllegalArgumentException("null fd");
13904                }
13905
13906                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
13907                if (proc == null || proc.thread == null) {
13908                    throw new IllegalArgumentException("Unknown process: " + process);
13909                }
13910
13911                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13912                if (!isDebuggable) {
13913                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13914                        throw new SecurityException("Process not debuggable: " + proc);
13915                    }
13916                }
13917
13918                proc.thread.dumpHeap(managed, path, fd);
13919                fd = null;
13920                return true;
13921            }
13922        } catch (RemoteException e) {
13923            throw new IllegalStateException("Process disappeared");
13924        } finally {
13925            if (fd != null) {
13926                try {
13927                    fd.close();
13928                } catch (IOException e) {
13929                }
13930            }
13931        }
13932    }
13933
13934    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13935    public void monitor() {
13936        synchronized (this) { }
13937    }
13938
13939    void onCoreSettingsChange(Bundle settings) {
13940        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13941            ProcessRecord processRecord = mLruProcesses.get(i);
13942            try {
13943                if (processRecord.thread != null) {
13944                    processRecord.thread.setCoreSettings(settings);
13945                }
13946            } catch (RemoteException re) {
13947                /* ignore */
13948            }
13949        }
13950    }
13951
13952    // Multi-user methods
13953
13954    @Override
13955    public boolean switchUser(int userId) {
13956        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13957                != PackageManager.PERMISSION_GRANTED) {
13958            String msg = "Permission Denial: switchUser() from pid="
13959                    + Binder.getCallingPid()
13960                    + ", uid=" + Binder.getCallingUid()
13961                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13962            Slog.w(TAG, msg);
13963            throw new SecurityException(msg);
13964        }
13965
13966        final long ident = Binder.clearCallingIdentity();
13967        try {
13968            synchronized (this) {
13969                final int oldUserId = mCurrentUserId;
13970                if (oldUserId == userId) {
13971                    return true;
13972                }
13973
13974                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
13975                if (userInfo == null) {
13976                    Slog.w(TAG, "No user info for user #" + userId);
13977                    return false;
13978                }
13979
13980                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
13981                        R.anim.screen_user_enter);
13982
13983                // If the user we are switching to is not currently started, then
13984                // we need to start it now.
13985                if (mStartedUsers.get(userId) == null) {
13986                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
13987                    updateStartedUserArrayLocked();
13988                }
13989
13990                mCurrentUserId = userId;
13991                mCurrentUserArray = new int[] { userId };
13992                final Integer userIdInt = Integer.valueOf(userId);
13993                mUserLru.remove(userIdInt);
13994                mUserLru.add(userIdInt);
13995
13996                mWindowManager.setCurrentUser(userId);
13997
13998                final UserStartedState uss = mStartedUsers.get(userId);
13999
14000                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
14001                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14002                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
14003                        oldUserId, userId, uss));
14004                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
14005                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
14006                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14007                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14008                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14009                broadcastIntentLocked(null, null, intent,
14010                        null, null, 0, null, null, null,
14011                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14012
14013                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
14014                    if (userId != 0) {
14015                        intent = new Intent(Intent.ACTION_USER_INITIALIZE);
14016                        broadcastIntentLocked(null, null, intent, null,
14017                                new IIntentReceiver.Stub() {
14018                                    public void performReceive(Intent intent, int resultCode,
14019                                            String data, Bundle extras, boolean ordered,
14020                                            boolean sticky, int sendingUser) {
14021                                        synchronized (ActivityManagerService.this) {
14022                                            getUserManagerLocked().makeInitialized(userInfo.id);
14023                                        }
14024                                    }
14025                                }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
14026                                userId);
14027                    } else {
14028                        getUserManagerLocked().makeInitialized(userInfo.id);
14029                    }
14030                }
14031
14032                boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
14033                if (!haveActivities) {
14034                    startHomeActivityLocked(userId);
14035                }
14036
14037                getUserManagerLocked().userForeground(userId);
14038                sendUserSwitchBroadcastsLocked(oldUserId, userId);
14039            }
14040        } finally {
14041            Binder.restoreCallingIdentity(ident);
14042        }
14043
14044        return true;
14045    }
14046
14047    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
14048        long ident = Binder.clearCallingIdentity();
14049        try {
14050            Intent intent;
14051            if (oldUserId >= 0) {
14052                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
14053                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14054                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
14055                broadcastIntentLocked(null, null, intent,
14056                        null, null, 0, null, null, null,
14057                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
14058            }
14059            if (newUserId >= 0) {
14060                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
14061                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14062                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14063                broadcastIntentLocked(null, null, intent,
14064                        null, null, 0, null, null, null,
14065                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
14066                intent = new Intent(Intent.ACTION_USER_SWITCHED);
14067                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14068                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14069                broadcastIntentLocked(null, null, intent,
14070                        null, null, 0, null, null,
14071                        android.Manifest.permission.MANAGE_USERS,
14072                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14073            }
14074        } finally {
14075            Binder.restoreCallingIdentity(ident);
14076        }
14077    }
14078
14079    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
14080            final int newUserId) {
14081        final int N = mUserSwitchObservers.beginBroadcast();
14082        if (N > 0) {
14083            final IRemoteCallback callback = new IRemoteCallback.Stub() {
14084                int mCount = 0;
14085                @Override
14086                public void sendResult(Bundle data) throws RemoteException {
14087                    synchronized (ActivityManagerService.this) {
14088                        if (mCurUserSwitchCallback == this) {
14089                            mCount++;
14090                            if (mCount == N) {
14091                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14092                            }
14093                        }
14094                    }
14095                }
14096            };
14097            synchronized (this) {
14098                mCurUserSwitchCallback = callback;
14099            }
14100            for (int i=0; i<N; i++) {
14101                try {
14102                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
14103                            newUserId, callback);
14104                } catch (RemoteException e) {
14105                }
14106            }
14107        } else {
14108            synchronized (this) {
14109                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14110            }
14111        }
14112        mUserSwitchObservers.finishBroadcast();
14113    }
14114
14115    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14116        synchronized (this) {
14117            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
14118            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14119        }
14120    }
14121
14122    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
14123        mCurUserSwitchCallback = null;
14124        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14125        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
14126                oldUserId, newUserId, uss));
14127    }
14128
14129    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14130        final int N = mUserSwitchObservers.beginBroadcast();
14131        for (int i=0; i<N; i++) {
14132            try {
14133                mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
14134            } catch (RemoteException e) {
14135            }
14136        }
14137        mUserSwitchObservers.finishBroadcast();
14138        synchronized (this) {
14139            mWindowManager.stopFreezingScreen();
14140        }
14141    }
14142
14143    void finishUserSwitch(UserStartedState uss) {
14144        synchronized (this) {
14145            if (uss.mState == UserStartedState.STATE_BOOTING
14146                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
14147                uss.mState = UserStartedState.STATE_RUNNING;
14148                final int userId = uss.mHandle.getIdentifier();
14149                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
14150                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14151                broadcastIntentLocked(null, null, intent,
14152                        null, null, 0, null, null,
14153                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
14154                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14155            }
14156            int num = mUserLru.size();
14157            int i = 0;
14158            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
14159                Integer oldUserId = mUserLru.get(i);
14160                UserStartedState oldUss = mStartedUsers.get(oldUserId);
14161                if (oldUss == null) {
14162                    // Shouldn't happen, but be sane if it does.
14163                    mUserLru.remove(i);
14164                    num--;
14165                    continue;
14166                }
14167                if (oldUss.mState == UserStartedState.STATE_STOPPING) {
14168                    // This user is already stopping, doesn't count.
14169                    num--;
14170                    i++;
14171                    continue;
14172                }
14173                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
14174                    // Owner and current can't be stopped, but count as running.
14175                    i++;
14176                    continue;
14177                }
14178                // This is a user to be stopped.
14179                stopUserLocked(oldUserId, null);
14180                num--;
14181                i++;
14182            }
14183        }
14184    }
14185
14186    @Override
14187    public int stopUser(final int userId, final IStopUserCallback callback) {
14188        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14189                != PackageManager.PERMISSION_GRANTED) {
14190            String msg = "Permission Denial: switchUser() from pid="
14191                    + Binder.getCallingPid()
14192                    + ", uid=" + Binder.getCallingUid()
14193                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14194            Slog.w(TAG, msg);
14195            throw new SecurityException(msg);
14196        }
14197        if (userId <= 0) {
14198            throw new IllegalArgumentException("Can't stop primary user " + userId);
14199        }
14200        synchronized (this) {
14201            return stopUserLocked(userId, callback);
14202        }
14203    }
14204
14205    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
14206        if (mCurrentUserId == userId) {
14207            return ActivityManager.USER_OP_IS_CURRENT;
14208        }
14209
14210        final UserStartedState uss = mStartedUsers.get(userId);
14211        if (uss == null) {
14212            // User is not started, nothing to do...  but we do need to
14213            // callback if requested.
14214            if (callback != null) {
14215                mHandler.post(new Runnable() {
14216                    @Override
14217                    public void run() {
14218                        try {
14219                            callback.userStopped(userId);
14220                        } catch (RemoteException e) {
14221                        }
14222                    }
14223                });
14224            }
14225            return ActivityManager.USER_OP_SUCCESS;
14226        }
14227
14228        if (callback != null) {
14229            uss.mStopCallbacks.add(callback);
14230        }
14231
14232        if (uss.mState != UserStartedState.STATE_STOPPING) {
14233            uss.mState = UserStartedState.STATE_STOPPING;
14234
14235            long ident = Binder.clearCallingIdentity();
14236            try {
14237                // Inform of user switch
14238                Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14239                final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() {
14240                    @Override
14241                    public void performReceive(Intent intent, int resultCode, String data,
14242                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14243                        finishUserStop(uss);
14244                    }
14245                };
14246                broadcastIntentLocked(null, null, intent,
14247                        null, resultReceiver, 0, null, null, null,
14248                        true, false, MY_PID, Process.SYSTEM_UID, userId);
14249            } finally {
14250                Binder.restoreCallingIdentity(ident);
14251            }
14252        }
14253
14254        return ActivityManager.USER_OP_SUCCESS;
14255    }
14256
14257    void finishUserStop(UserStartedState uss) {
14258        final int userId = uss.mHandle.getIdentifier();
14259        boolean stopped;
14260        ArrayList<IStopUserCallback> callbacks;
14261        synchronized (this) {
14262            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
14263            if (uss.mState != UserStartedState.STATE_STOPPING
14264                    || mStartedUsers.get(userId) != uss) {
14265                stopped = false;
14266            } else {
14267                stopped = true;
14268                // User can no longer run.
14269                mStartedUsers.remove(userId);
14270                mUserLru.remove(Integer.valueOf(userId));
14271                updateStartedUserArrayLocked();
14272
14273                // Clean up all state and processes associated with the user.
14274                // Kill all the processes for the user.
14275                forceStopUserLocked(userId);
14276            }
14277        }
14278
14279        for (int i=0; i<callbacks.size(); i++) {
14280            try {
14281                if (stopped) callbacks.get(i).userStopped(userId);
14282                else callbacks.get(i).userStopAborted(userId);
14283            } catch (RemoteException e) {
14284            }
14285        }
14286    }
14287
14288    @Override
14289    public UserInfo getCurrentUser() {
14290        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14291                != PackageManager.PERMISSION_GRANTED) && (
14292                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14293                != PackageManager.PERMISSION_GRANTED)) {
14294            String msg = "Permission Denial: getCurrentUser() from pid="
14295                    + Binder.getCallingPid()
14296                    + ", uid=" + Binder.getCallingUid()
14297                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14298            Slog.w(TAG, msg);
14299            throw new SecurityException(msg);
14300        }
14301        synchronized (this) {
14302            return getUserManagerLocked().getUserInfo(mCurrentUserId);
14303        }
14304    }
14305
14306    @Override
14307    public boolean isUserRunning(int userId) {
14308        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14309                != PackageManager.PERMISSION_GRANTED) {
14310            String msg = "Permission Denial: isUserRunning() from pid="
14311                    + Binder.getCallingPid()
14312                    + ", uid=" + Binder.getCallingUid()
14313                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14314            Slog.w(TAG, msg);
14315            throw new SecurityException(msg);
14316        }
14317        synchronized (this) {
14318            return isUserRunningLocked(userId);
14319        }
14320    }
14321
14322    boolean isUserRunningLocked(int userId) {
14323        UserStartedState state = mStartedUsers.get(userId);
14324        return state != null && state.mState != UserStartedState.STATE_STOPPING;
14325    }
14326
14327    @Override
14328    public int[] getRunningUserIds() {
14329        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14330                != PackageManager.PERMISSION_GRANTED) {
14331            String msg = "Permission Denial: isUserRunning() from pid="
14332                    + Binder.getCallingPid()
14333                    + ", uid=" + Binder.getCallingUid()
14334                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14335            Slog.w(TAG, msg);
14336            throw new SecurityException(msg);
14337        }
14338        synchronized (this) {
14339            return mStartedUserArray;
14340        }
14341    }
14342
14343    private void updateStartedUserArrayLocked() {
14344        mStartedUserArray = new int[mStartedUsers.size()];
14345        for (int i=0; i<mStartedUsers.size();  i++) {
14346            mStartedUserArray[i] = mStartedUsers.keyAt(i);
14347        }
14348    }
14349
14350    @Override
14351    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
14352        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14353                != PackageManager.PERMISSION_GRANTED) {
14354            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
14355                    + Binder.getCallingPid()
14356                    + ", uid=" + Binder.getCallingUid()
14357                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14358            Slog.w(TAG, msg);
14359            throw new SecurityException(msg);
14360        }
14361
14362        mUserSwitchObservers.register(observer);
14363    }
14364
14365    @Override
14366    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
14367        mUserSwitchObservers.unregister(observer);
14368    }
14369
14370    private boolean userExists(int userId) {
14371        if (userId == 0) {
14372            return true;
14373        }
14374        UserManagerService ums = getUserManagerLocked();
14375        return ums != null ? (ums.getUserInfo(userId) != null) : false;
14376    }
14377
14378    int[] getUsersLocked() {
14379        UserManagerService ums = getUserManagerLocked();
14380        return ums != null ? ums.getUserIds() : new int[] { 0 };
14381    }
14382
14383    UserManagerService getUserManagerLocked() {
14384        if (mUserManager == null) {
14385            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
14386            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
14387        }
14388        return mUserManager;
14389    }
14390
14391    private void checkValidCaller(int uid, int userId) {
14392        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
14393
14394        throw new SecurityException("Caller uid=" + uid
14395                + " is not privileged to communicate with user=" + userId);
14396    }
14397
14398    private int applyUserId(int uid, int userId) {
14399        return UserHandle.getUid(userId, uid);
14400    }
14401
14402    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
14403        if (info == null) return null;
14404        ApplicationInfo newInfo = new ApplicationInfo(info);
14405        newInfo.uid = applyUserId(info.uid, userId);
14406        newInfo.dataDir = USER_DATA_DIR + userId + "/"
14407                + info.packageName;
14408        return newInfo;
14409    }
14410
14411    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
14412        if (aInfo == null
14413                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
14414            return aInfo;
14415        }
14416
14417        ActivityInfo info = new ActivityInfo(aInfo);
14418        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
14419        return info;
14420    }
14421}
14422