ActivityManagerService.java revision 259d5e56a82d721ccb7e7f514c80de69acae309e
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.wm.WindowManagerService;
31
32import dalvik.system.Zygote;
33
34import android.app.Activity;
35import android.app.ActivityManager;
36import android.app.ActivityManagerNative;
37import android.app.ActivityOptions;
38import android.app.ActivityThread;
39import android.app.AlertDialog;
40import android.app.AppGlobals;
41import android.app.ApplicationErrorReport;
42import android.app.Dialog;
43import android.app.IActivityController;
44import android.app.IApplicationThread;
45import android.app.IInstrumentationWatcher;
46import android.app.INotificationManager;
47import android.app.IProcessObserver;
48import android.app.IServiceConnection;
49import android.app.IStopUserCallback;
50import android.app.IThumbnailReceiver;
51import android.app.Instrumentation;
52import android.app.Notification;
53import android.app.NotificationManager;
54import android.app.PendingIntent;
55import android.app.backup.IBackupManager;
56import android.content.ActivityNotFoundException;
57import android.content.BroadcastReceiver;
58import android.content.ClipData;
59import android.content.ComponentCallbacks2;
60import android.content.ComponentName;
61import android.content.ContentProvider;
62import android.content.ContentResolver;
63import android.content.Context;
64import android.content.DialogInterface;
65import android.content.IContentProvider;
66import android.content.IIntentReceiver;
67import android.content.IIntentSender;
68import android.content.Intent;
69import android.content.IntentFilter;
70import android.content.IntentSender;
71import android.content.pm.ActivityInfo;
72import android.content.pm.ApplicationInfo;
73import android.content.pm.ConfigurationInfo;
74import android.content.pm.IPackageDataObserver;
75import android.content.pm.IPackageManager;
76import android.content.pm.InstrumentationInfo;
77import android.content.pm.PackageInfo;
78import android.content.pm.PackageManager;
79import android.content.pm.UserInfo;
80import android.content.pm.PackageManager.NameNotFoundException;
81import android.content.pm.PathPermission;
82import android.content.pm.ProviderInfo;
83import android.content.pm.ResolveInfo;
84import android.content.pm.ServiceInfo;
85import android.content.res.CompatibilityInfo;
86import android.content.res.Configuration;
87import android.graphics.Bitmap;
88import android.net.Proxy;
89import android.net.ProxyProperties;
90import android.net.Uri;
91import android.os.Binder;
92import android.os.Build;
93import android.os.Bundle;
94import android.os.Debug;
95import android.os.DropBoxManager;
96import android.os.Environment;
97import android.os.FileObserver;
98import android.os.FileUtils;
99import android.os.Handler;
100import android.os.IBinder;
101import android.os.IPermissionController;
102import android.os.Looper;
103import android.os.Message;
104import android.os.Parcel;
105import android.os.ParcelFileDescriptor;
106import android.os.Process;
107import android.os.RemoteCallbackList;
108import android.os.RemoteException;
109import android.os.SELinux;
110import android.os.ServiceManager;
111import android.os.StrictMode;
112import android.os.SystemClock;
113import android.os.SystemProperties;
114import android.os.UserHandle;
115import android.os.UserManager;
116import android.provider.Settings;
117import android.text.format.Time;
118import android.util.EventLog;
119import android.util.LocaleUtil;
120import android.util.Log;
121import android.util.Pair;
122import android.util.PrintWriterPrinter;
123import android.util.Slog;
124import android.util.SparseArray;
125import android.util.SparseIntArray;
126import android.util.TimeUtils;
127import android.view.Gravity;
128import android.view.LayoutInflater;
129import android.view.View;
130import android.view.WindowManager;
131import android.view.WindowManagerPolicy;
132
133import java.io.BufferedInputStream;
134import java.io.BufferedOutputStream;
135import java.io.BufferedReader;
136import java.io.DataInputStream;
137import java.io.DataOutputStream;
138import java.io.File;
139import java.io.FileDescriptor;
140import java.io.FileInputStream;
141import java.io.FileNotFoundException;
142import java.io.FileOutputStream;
143import java.io.IOException;
144import java.io.InputStreamReader;
145import java.io.PrintWriter;
146import java.io.StringWriter;
147import java.lang.ref.WeakReference;
148import java.util.ArrayList;
149import java.util.Collections;
150import java.util.Comparator;
151import java.util.HashMap;
152import java.util.HashSet;
153import java.util.Iterator;
154import java.util.List;
155import java.util.Locale;
156import java.util.Map;
157import java.util.Set;
158import java.util.concurrent.atomic.AtomicBoolean;
159import java.util.concurrent.atomic.AtomicLong;
160
161public final class ActivityManagerService extends ActivityManagerNative
162        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
163    private static final String USER_DATA_DIR = "/data/user/";
164    static final String TAG = "ActivityManager";
165    static final String TAG_MU = "ActivityManagerServiceMU";
166    static final boolean DEBUG = false;
167    static final boolean localLOGV = DEBUG;
168    static final boolean DEBUG_SWITCH = localLOGV || false;
169    static final boolean DEBUG_TASKS = localLOGV || false;
170    static final boolean DEBUG_PAUSE = localLOGV || false;
171    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
172    static final boolean DEBUG_TRANSITION = localLOGV || false;
173    static final boolean DEBUG_BROADCAST = localLOGV || false;
174    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
175    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
176    static final boolean DEBUG_SERVICE = localLOGV || false;
177    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
178    static final boolean DEBUG_VISBILITY = localLOGV || false;
179    static final boolean DEBUG_PROCESSES = localLOGV || false;
180    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
181    static final boolean DEBUG_PROVIDER = localLOGV || false;
182    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
183    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
184    static final boolean DEBUG_RESULTS = localLOGV || false;
185    static final boolean DEBUG_BACKUP = localLOGV || false;
186    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
187    static final boolean DEBUG_POWER = localLOGV || false;
188    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
189    static final boolean DEBUG_MU = localLOGV || false;
190    static final boolean VALIDATE_TOKENS = false;
191    static final boolean SHOW_ACTIVITY_START_TIME = true;
192
193    // Control over CPU and battery monitoring.
194    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
195    static final boolean MONITOR_CPU_USAGE = true;
196    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
197    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
198    static final boolean MONITOR_THREAD_CPU_USAGE = false;
199
200    // The flags that are set for all calls we make to the package manager.
201    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
202
203    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
204
205    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
206
207    // Maximum number of recent tasks that we can remember.
208    static final int MAX_RECENT_TASKS = 20;
209
210    // Amount of time after a call to stopAppSwitches() during which we will
211    // prevent further untrusted switches from happening.
212    static final long APP_SWITCH_DELAY_TIME = 5*1000;
213
214    // How long we wait for a launched process to attach to the activity manager
215    // before we decide it's never going to come up for real.
216    static final int PROC_START_TIMEOUT = 10*1000;
217
218    // How long we wait for a launched process to attach to the activity manager
219    // before we decide it's never going to come up for real, when the process was
220    // started with a wrapper for instrumentation (such as Valgrind) because it
221    // could take much longer than usual.
222    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
223
224    // How long to wait after going idle before forcing apps to GC.
225    static final int GC_TIMEOUT = 5*1000;
226
227    // The minimum amount of time between successive GC requests for a process.
228    static final int GC_MIN_INTERVAL = 60*1000;
229
230    // The rate at which we check for apps using excessive power -- 15 mins.
231    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
232
233    // The minimum sample duration we will allow before deciding we have
234    // enough data on wake locks to start killing things.
235    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
236
237    // The minimum sample duration we will allow before deciding we have
238    // enough data on CPU usage to start killing things.
239    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
240
241    // How long we allow a receiver to run before giving up on it.
242    static final int BROADCAST_FG_TIMEOUT = 10*1000;
243    static final int BROADCAST_BG_TIMEOUT = 60*1000;
244
245    // How long we wait until we timeout on key dispatching.
246    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
247
248    // How long we wait until we timeout on key dispatching during instrumentation.
249    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
250
251    static final int MY_PID = Process.myPid();
252
253    static final String[] EMPTY_STRING_ARRAY = new String[0];
254
255    public ActivityStack mMainStack;
256
257    private final boolean mHeadless;
258
259    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
260    // default actuion automatically.  Important for devices without direct input
261    // devices.
262    private boolean mShowDialogs = true;
263
264    /**
265     * Description of a request to start a new activity, which has been held
266     * due to app switches being disabled.
267     */
268    static class PendingActivityLaunch {
269        ActivityRecord r;
270        ActivityRecord sourceRecord;
271        int startFlags;
272    }
273
274    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
275            = new ArrayList<PendingActivityLaunch>();
276
277
278    BroadcastQueue mFgBroadcastQueue;
279    BroadcastQueue mBgBroadcastQueue;
280    // Convenient for easy iteration over the queues. Foreground is first
281    // so that dispatch of foreground broadcasts gets precedence.
282    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
283
284    BroadcastQueue broadcastQueueForIntent(Intent intent) {
285        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
286        if (DEBUG_BACKGROUND_BROADCAST) {
287            Slog.i(TAG, "Broadcast intent " + intent + " on "
288                    + (isFg ? "foreground" : "background")
289                    + " queue");
290        }
291        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
292    }
293
294    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
295        for (BroadcastQueue queue : mBroadcastQueues) {
296            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
297            if (r != null) {
298                return r;
299            }
300        }
301        return null;
302    }
303
304    /**
305     * Activity we have told the window manager to have key focus.
306     */
307    ActivityRecord mFocusedActivity = null;
308    /**
309     * List of intents that were used to start the most recent tasks.
310     */
311    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
312
313    /**
314     * Process management.
315     */
316    final ProcessList mProcessList = new ProcessList();
317
318    /**
319     * All of the applications we currently have running organized by name.
320     * The keys are strings of the application package name (as
321     * returned by the package manager), and the keys are ApplicationRecord
322     * objects.
323     */
324    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
325
326    /**
327     * The currently running isolated processes.
328     */
329    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
330
331    /**
332     * Counter for assigning isolated process uids, to avoid frequently reusing the
333     * same ones.
334     */
335    int mNextIsolatedProcessUid = 0;
336
337    /**
338     * The currently running heavy-weight process, if any.
339     */
340    ProcessRecord mHeavyWeightProcess = null;
341
342    /**
343     * The last time that various processes have crashed.
344     */
345    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
346
347    /**
348     * Set of applications that we consider to be bad, and will reject
349     * incoming broadcasts from (which the user has no control over).
350     * Processes are added to this set when they have crashed twice within
351     * a minimum amount of time; they are removed from it when they are
352     * later restarted (hopefully due to some user action).  The value is the
353     * time it was added to the list.
354     */
355    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
356
357    /**
358     * All of the processes we currently have running organized by pid.
359     * The keys are the pid running the application.
360     *
361     * <p>NOTE: This object is protected by its own lock, NOT the global
362     * activity manager lock!
363     */
364    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
365
366    /**
367     * All of the processes that have been forced to be foreground.  The key
368     * is the pid of the caller who requested it (we hold a death
369     * link on it).
370     */
371    abstract class ForegroundToken implements IBinder.DeathRecipient {
372        int pid;
373        IBinder token;
374    }
375    final SparseArray<ForegroundToken> mForegroundProcesses
376            = new SparseArray<ForegroundToken>();
377
378    /**
379     * List of records for processes that someone had tried to start before the
380     * system was ready.  We don't start them at that point, but ensure they
381     * are started by the time booting is complete.
382     */
383    final ArrayList<ProcessRecord> mProcessesOnHold
384            = new ArrayList<ProcessRecord>();
385
386    /**
387     * List of persistent applications that are in the process
388     * of being started.
389     */
390    final ArrayList<ProcessRecord> mPersistentStartingProcesses
391            = new ArrayList<ProcessRecord>();
392
393    /**
394     * Processes that are being forcibly torn down.
395     */
396    final ArrayList<ProcessRecord> mRemovedProcesses
397            = new ArrayList<ProcessRecord>();
398
399    /**
400     * List of running applications, sorted by recent usage.
401     * The first entry in the list is the least recently used.
402     * It contains ApplicationRecord objects.  This list does NOT include
403     * any persistent application records (since we never want to exit them).
404     */
405    final ArrayList<ProcessRecord> mLruProcesses
406            = new ArrayList<ProcessRecord>();
407
408    /**
409     * List of processes that should gc as soon as things are idle.
410     */
411    final ArrayList<ProcessRecord> mProcessesToGc
412            = new ArrayList<ProcessRecord>();
413
414    /**
415     * This is the process holding what we currently consider to be
416     * the "home" activity.
417     */
418    ProcessRecord mHomeProcess;
419
420    /**
421     * This is the process holding the activity the user last visited that
422     * is in a different process from the one they are currently in.
423     */
424    ProcessRecord mPreviousProcess;
425
426    /**
427     * The time at which the previous process was last visible.
428     */
429    long mPreviousProcessVisibleTime;
430
431    /**
432     * Which uses have been started, so are allowed to run code.
433     */
434    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
435
436    /**
437     * Packages that the user has asked to have run in screen size
438     * compatibility mode instead of filling the screen.
439     */
440    final CompatModePackages mCompatModePackages;
441
442    /**
443     * Set of PendingResultRecord objects that are currently active.
444     */
445    final HashSet mPendingResultRecords = new HashSet();
446
447    /**
448     * Set of IntentSenderRecord objects that are currently active.
449     */
450    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
451            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
452
453    /**
454     * Fingerprints (hashCode()) of stack traces that we've
455     * already logged DropBox entries for.  Guarded by itself.  If
456     * something (rogue user app) forces this over
457     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
458     */
459    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
460    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
461
462    /**
463     * Strict Mode background batched logging state.
464     *
465     * The string buffer is guarded by itself, and its lock is also
466     * used to determine if another batched write is already
467     * in-flight.
468     */
469    private final StringBuilder mStrictModeBuffer = new StringBuilder();
470
471    /**
472     * Keeps track of all IIntentReceivers that have been registered for
473     * broadcasts.  Hash keys are the receiver IBinder, hash value is
474     * a ReceiverList.
475     */
476    final HashMap mRegisteredReceivers = new HashMap();
477
478    /**
479     * Resolver for broadcast intents to registered receivers.
480     * Holds BroadcastFilter (subclass of IntentFilter).
481     */
482    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
483            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
484        @Override
485        protected boolean allowFilterResult(
486                BroadcastFilter filter, List<BroadcastFilter> dest) {
487            IBinder target = filter.receiverList.receiver.asBinder();
488            for (int i=dest.size()-1; i>=0; i--) {
489                if (dest.get(i).receiverList.receiver.asBinder() == target) {
490                    return false;
491                }
492            }
493            return true;
494        }
495
496        @Override
497        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
498            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
499                    || userId == filter.owningUserId) {
500                return super.newResult(filter, match, userId);
501            }
502            return null;
503        }
504
505        @Override
506        protected BroadcastFilter[] newArray(int size) {
507            return new BroadcastFilter[size];
508        }
509
510        @Override
511        protected String packageForFilter(BroadcastFilter filter) {
512            return filter.packageName;
513        }
514    };
515
516    /**
517     * State of all active sticky broadcasts per user.  Keys are the action of the
518     * sticky Intent, values are an ArrayList of all broadcasted intents with
519     * that action (which should usually be one).  The SparseArray is keyed
520     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
521     * for stickies that are sent to all users.
522     */
523    final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
524            new SparseArray<HashMap<String, ArrayList<Intent>>>();
525
526    final ActiveServices mServices;
527
528    /**
529     * Backup/restore process management
530     */
531    String mBackupAppName = null;
532    BackupRecord mBackupTarget = null;
533
534    /**
535     * List of PendingThumbnailsRecord objects of clients who are still
536     * waiting to receive all of the thumbnails for a task.
537     */
538    final ArrayList mPendingThumbnails = new ArrayList();
539
540    /**
541     * List of HistoryRecord objects that have been finished and must
542     * still report back to a pending thumbnail receiver.
543     */
544    final ArrayList mCancelledThumbnails = new ArrayList();
545
546    final ProviderMap mProviderMap = new ProviderMap();
547
548    /**
549     * List of content providers who have clients waiting for them.  The
550     * application is currently being launched and the provider will be
551     * removed from this list once it is published.
552     */
553    final ArrayList<ContentProviderRecord> mLaunchingProviders
554            = new ArrayList<ContentProviderRecord>();
555
556    /**
557     * Global set of specific Uri permissions that have been granted.
558     */
559    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
560            = new SparseArray<HashMap<Uri, UriPermission>>();
561
562    CoreSettingsObserver mCoreSettingsObserver;
563
564    /**
565     * Thread-local storage used to carry caller permissions over through
566     * indirect content-provider access.
567     * @see #ActivityManagerService.openContentUri()
568     */
569    private class Identity {
570        public int pid;
571        public int uid;
572
573        Identity(int _pid, int _uid) {
574            pid = _pid;
575            uid = _uid;
576        }
577    }
578
579    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
580
581    /**
582     * All information we have collected about the runtime performance of
583     * any user id that can impact battery performance.
584     */
585    final BatteryStatsService mBatteryStatsService;
586
587    /**
588     * information about component usage
589     */
590    final UsageStatsService mUsageStatsService;
591
592    /**
593     * Current configuration information.  HistoryRecord objects are given
594     * a reference to this object to indicate which configuration they are
595     * currently running in, so this object must be kept immutable.
596     */
597    Configuration mConfiguration = new Configuration();
598
599    /**
600     * Current sequencing integer of the configuration, for skipping old
601     * configurations.
602     */
603    int mConfigurationSeq = 0;
604
605    /**
606     * Hardware-reported OpenGLES version.
607     */
608    final int GL_ES_VERSION;
609
610    /**
611     * List of initialization arguments to pass to all processes when binding applications to them.
612     * For example, references to the commonly used services.
613     */
614    HashMap<String, IBinder> mAppBindArgs;
615
616    /**
617     * Temporary to avoid allocations.  Protected by main lock.
618     */
619    final StringBuilder mStringBuilder = new StringBuilder(256);
620
621    /**
622     * Used to control how we initialize the service.
623     */
624    boolean mStartRunning = false;
625    ComponentName mTopComponent;
626    String mTopAction;
627    String mTopData;
628    boolean mProcessesReady = false;
629    boolean mSystemReady = false;
630    boolean mBooting = false;
631    boolean mWaitingUpdate = false;
632    boolean mDidUpdate = false;
633    boolean mOnBattery = false;
634    boolean mLaunchWarningShown = false;
635
636    Context mContext;
637
638    int mFactoryTest;
639
640    boolean mCheckedForSetup;
641
642    /**
643     * The time at which we will allow normal application switches again,
644     * after a call to {@link #stopAppSwitches()}.
645     */
646    long mAppSwitchesAllowedTime;
647
648    /**
649     * This is set to true after the first switch after mAppSwitchesAllowedTime
650     * is set; any switches after that will clear the time.
651     */
652    boolean mDidAppSwitch;
653
654    /**
655     * Last time (in realtime) at which we checked for power usage.
656     */
657    long mLastPowerCheckRealtime;
658
659    /**
660     * Last time (in uptime) at which we checked for power usage.
661     */
662    long mLastPowerCheckUptime;
663
664    /**
665     * Set while we are wanting to sleep, to prevent any
666     * activities from being started/resumed.
667     */
668    boolean mSleeping = false;
669
670    /**
671     * State of external calls telling us if the device is asleep.
672     */
673    boolean mWentToSleep = false;
674
675    /**
676     * State of external call telling us if the lock screen is shown.
677     */
678    boolean mLockScreenShown = false;
679
680    /**
681     * Set if we are shutting down the system, similar to sleeping.
682     */
683    boolean mShuttingDown = false;
684
685    /**
686     * Task identifier that activities are currently being started
687     * in.  Incremented each time a new task is created.
688     * todo: Replace this with a TokenSpace class that generates non-repeating
689     * integers that won't wrap.
690     */
691    int mCurTask = 1;
692
693    /**
694     * Current sequence id for oom_adj computation traversal.
695     */
696    int mAdjSeq = 0;
697
698    /**
699     * Current sequence id for process LRU updating.
700     */
701    int mLruSeq = 0;
702
703    /**
704     * Keep track of the non-hidden/empty process we last found, to help
705     * determine how to distribute hidden/empty processes next time.
706     */
707    int mNumNonHiddenProcs = 0;
708
709    /**
710     * Keep track of the number of hidden procs, to balance oom adj
711     * distribution between those and empty procs.
712     */
713    int mNumHiddenProcs = 0;
714
715    /**
716     * Keep track of the number of service processes we last found, to
717     * determine on the next iteration which should be B services.
718     */
719    int mNumServiceProcs = 0;
720    int mNewNumServiceProcs = 0;
721
722    /**
723     * System monitoring: number of processes that died since the last
724     * N procs were started.
725     */
726    int[] mProcDeaths = new int[20];
727
728    /**
729     * This is set if we had to do a delayed dexopt of an app before launching
730     * it, to increasing the ANR timeouts in that case.
731     */
732    boolean mDidDexOpt;
733
734    String mDebugApp = null;
735    boolean mWaitForDebugger = false;
736    boolean mDebugTransient = false;
737    String mOrigDebugApp = null;
738    boolean mOrigWaitForDebugger = false;
739    boolean mAlwaysFinishActivities = false;
740    IActivityController mController = null;
741    String mProfileApp = null;
742    ProcessRecord mProfileProc = null;
743    String mProfileFile;
744    ParcelFileDescriptor mProfileFd;
745    int mProfileType = 0;
746    boolean mAutoStopProfiler = false;
747    String mOpenGlTraceApp = null;
748
749    static class ProcessChangeItem {
750        static final int CHANGE_ACTIVITIES = 1<<0;
751        static final int CHANGE_IMPORTANCE= 1<<1;
752        int changes;
753        int uid;
754        int pid;
755        int importance;
756        boolean foregroundActivities;
757    }
758
759    final RemoteCallbackList<IProcessObserver> mProcessObservers
760            = new RemoteCallbackList<IProcessObserver>();
761    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
762
763    final ArrayList<ProcessChangeItem> mPendingProcessChanges
764            = new ArrayList<ProcessChangeItem>();
765    final ArrayList<ProcessChangeItem> mAvailProcessChanges
766            = new ArrayList<ProcessChangeItem>();
767
768    /**
769     * Callback of last caller to {@link #requestPss}.
770     */
771    Runnable mRequestPssCallback;
772
773    /**
774     * Remaining processes for which we are waiting results from the last
775     * call to {@link #requestPss}.
776     */
777    final ArrayList<ProcessRecord> mRequestPssList
778            = new ArrayList<ProcessRecord>();
779
780    /**
781     * Runtime statistics collection thread.  This object's lock is used to
782     * protect all related state.
783     */
784    final Thread mProcessStatsThread;
785
786    /**
787     * Used to collect process stats when showing not responding dialog.
788     * Protected by mProcessStatsThread.
789     */
790    final ProcessStats mProcessStats = new ProcessStats(
791            MONITOR_THREAD_CPU_USAGE);
792    final AtomicLong mLastCpuTime = new AtomicLong(0);
793    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
794
795    long mLastWriteTime = 0;
796
797    /**
798     * Set to true after the system has finished booting.
799     */
800    boolean mBooted = false;
801
802    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
803    int mProcessLimitOverride = -1;
804
805    WindowManagerService mWindowManager;
806
807    static ActivityManagerService mSelf;
808    static ActivityThread mSystemThread;
809
810    private int mCurrentUserId;
811    private UserManager mUserManager;
812
813    private final class AppDeathRecipient implements IBinder.DeathRecipient {
814        final ProcessRecord mApp;
815        final int mPid;
816        final IApplicationThread mAppThread;
817
818        AppDeathRecipient(ProcessRecord app, int pid,
819                IApplicationThread thread) {
820            if (localLOGV) Slog.v(
821                TAG, "New death recipient " + this
822                + " for thread " + thread.asBinder());
823            mApp = app;
824            mPid = pid;
825            mAppThread = thread;
826        }
827
828        public void binderDied() {
829            if (localLOGV) Slog.v(
830                TAG, "Death received in " + this
831                + " for thread " + mAppThread.asBinder());
832            synchronized(ActivityManagerService.this) {
833                appDiedLocked(mApp, mPid, mAppThread);
834            }
835        }
836    }
837
838    static final int SHOW_ERROR_MSG = 1;
839    static final int SHOW_NOT_RESPONDING_MSG = 2;
840    static final int SHOW_FACTORY_ERROR_MSG = 3;
841    static final int UPDATE_CONFIGURATION_MSG = 4;
842    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
843    static final int WAIT_FOR_DEBUGGER_MSG = 6;
844    static final int SERVICE_TIMEOUT_MSG = 12;
845    static final int UPDATE_TIME_ZONE = 13;
846    static final int SHOW_UID_ERROR_MSG = 14;
847    static final int IM_FEELING_LUCKY_MSG = 15;
848    static final int PROC_START_TIMEOUT_MSG = 20;
849    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
850    static final int KILL_APPLICATION_MSG = 22;
851    static final int FINALIZE_PENDING_INTENT_MSG = 23;
852    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
853    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
854    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
855    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
856    static final int CLEAR_DNS_CACHE = 28;
857    static final int UPDATE_HTTP_PROXY = 29;
858    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
859    static final int DISPATCH_PROCESSES_CHANGED = 31;
860    static final int DISPATCH_PROCESS_DIED = 32;
861    static final int REPORT_MEM_USAGE = 33;
862
863    static final int FIRST_ACTIVITY_STACK_MSG = 100;
864    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
865    static final int FIRST_COMPAT_MODE_MSG = 300;
866
867    AlertDialog mUidAlert;
868    CompatModeDialog mCompatModeDialog;
869    long mLastMemUsageReportTime = 0;
870
871    final Handler mHandler = new Handler() {
872        //public Handler() {
873        //    if (localLOGV) Slog.v(TAG, "Handler started!");
874        //}
875
876        public void handleMessage(Message msg) {
877            switch (msg.what) {
878            case SHOW_ERROR_MSG: {
879                HashMap data = (HashMap) msg.obj;
880                synchronized (ActivityManagerService.this) {
881                    ProcessRecord proc = (ProcessRecord)data.get("app");
882                    if (proc != null && proc.crashDialog != null) {
883                        Slog.e(TAG, "App already has crash dialog: " + proc);
884                        return;
885                    }
886                    AppErrorResult res = (AppErrorResult) data.get("result");
887                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
888                        Dialog d = new AppErrorDialog(mContext, res, proc);
889                        d.show();
890                        proc.crashDialog = d;
891                    } else {
892                        // The device is asleep, so just pretend that the user
893                        // saw a crash dialog and hit "force quit".
894                        res.set(0);
895                    }
896                }
897
898                ensureBootCompleted();
899            } break;
900            case SHOW_NOT_RESPONDING_MSG: {
901                synchronized (ActivityManagerService.this) {
902                    HashMap data = (HashMap) msg.obj;
903                    ProcessRecord proc = (ProcessRecord)data.get("app");
904                    if (proc != null && proc.anrDialog != null) {
905                        Slog.e(TAG, "App already has anr dialog: " + proc);
906                        return;
907                    }
908
909                    Intent intent = new Intent("android.intent.action.ANR");
910                    if (!mProcessesReady) {
911                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
912                                | Intent.FLAG_RECEIVER_FOREGROUND);
913                    }
914                    broadcastIntentLocked(null, null, intent,
915                            null, null, 0, null, null, null,
916                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
917
918                    if (mShowDialogs) {
919                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
920                                mContext, proc, (ActivityRecord)data.get("activity"));
921                        d.show();
922                        proc.anrDialog = d;
923                    } else {
924                        // Just kill the app if there is no dialog to be shown.
925                        killAppAtUsersRequest(proc, null);
926                    }
927                }
928
929                ensureBootCompleted();
930            } break;
931            case SHOW_STRICT_MODE_VIOLATION_MSG: {
932                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
933                synchronized (ActivityManagerService.this) {
934                    ProcessRecord proc = (ProcessRecord) data.get("app");
935                    if (proc == null) {
936                        Slog.e(TAG, "App not found when showing strict mode dialog.");
937                        break;
938                    }
939                    if (proc.crashDialog != null) {
940                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
941                        return;
942                    }
943                    AppErrorResult res = (AppErrorResult) data.get("result");
944                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
945                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
946                        d.show();
947                        proc.crashDialog = d;
948                    } else {
949                        // The device is asleep, so just pretend that the user
950                        // saw a crash dialog and hit "force quit".
951                        res.set(0);
952                    }
953                }
954                ensureBootCompleted();
955            } break;
956            case SHOW_FACTORY_ERROR_MSG: {
957                Dialog d = new FactoryErrorDialog(
958                    mContext, msg.getData().getCharSequence("msg"));
959                d.show();
960                ensureBootCompleted();
961            } break;
962            case UPDATE_CONFIGURATION_MSG: {
963                final ContentResolver resolver = mContext.getContentResolver();
964                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
965            } break;
966            case GC_BACKGROUND_PROCESSES_MSG: {
967                synchronized (ActivityManagerService.this) {
968                    performAppGcsIfAppropriateLocked();
969                }
970            } break;
971            case WAIT_FOR_DEBUGGER_MSG: {
972                synchronized (ActivityManagerService.this) {
973                    ProcessRecord app = (ProcessRecord)msg.obj;
974                    if (msg.arg1 != 0) {
975                        if (!app.waitedForDebugger) {
976                            Dialog d = new AppWaitingForDebuggerDialog(
977                                    ActivityManagerService.this,
978                                    mContext, app);
979                            app.waitDialog = d;
980                            app.waitedForDebugger = true;
981                            d.show();
982                        }
983                    } else {
984                        if (app.waitDialog != null) {
985                            app.waitDialog.dismiss();
986                            app.waitDialog = null;
987                        }
988                    }
989                }
990            } break;
991            case SERVICE_TIMEOUT_MSG: {
992                if (mDidDexOpt) {
993                    mDidDexOpt = false;
994                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
995                    nmsg.obj = msg.obj;
996                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
997                    return;
998                }
999                mServices.serviceTimeout((ProcessRecord)msg.obj);
1000            } break;
1001            case UPDATE_TIME_ZONE: {
1002                synchronized (ActivityManagerService.this) {
1003                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1004                        ProcessRecord r = mLruProcesses.get(i);
1005                        if (r.thread != null) {
1006                            try {
1007                                r.thread.updateTimeZone();
1008                            } catch (RemoteException ex) {
1009                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1010                            }
1011                        }
1012                    }
1013                }
1014            } break;
1015            case CLEAR_DNS_CACHE: {
1016                synchronized (ActivityManagerService.this) {
1017                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1018                        ProcessRecord r = mLruProcesses.get(i);
1019                        if (r.thread != null) {
1020                            try {
1021                                r.thread.clearDnsCache();
1022                            } catch (RemoteException ex) {
1023                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1024                            }
1025                        }
1026                    }
1027                }
1028            } break;
1029            case UPDATE_HTTP_PROXY: {
1030                ProxyProperties proxy = (ProxyProperties)msg.obj;
1031                String host = "";
1032                String port = "";
1033                String exclList = "";
1034                if (proxy != null) {
1035                    host = proxy.getHost();
1036                    port = Integer.toString(proxy.getPort());
1037                    exclList = proxy.getExclusionList();
1038                }
1039                synchronized (ActivityManagerService.this) {
1040                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1041                        ProcessRecord r = mLruProcesses.get(i);
1042                        if (r.thread != null) {
1043                            try {
1044                                r.thread.setHttpProxy(host, port, exclList);
1045                            } catch (RemoteException ex) {
1046                                Slog.w(TAG, "Failed to update http proxy for: " +
1047                                        r.info.processName);
1048                            }
1049                        }
1050                    }
1051                }
1052            } break;
1053            case SHOW_UID_ERROR_MSG: {
1054                String title = "System UIDs Inconsistent";
1055                String text = "UIDs on the system are inconsistent, you need to wipe your"
1056                        + " data partition or your device will be unstable.";
1057                Log.e(TAG, title + ": " + text);
1058                if (mShowDialogs) {
1059                    // XXX This is a temporary dialog, no need to localize.
1060                    AlertDialog d = new BaseErrorDialog(mContext);
1061                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1062                    d.setCancelable(false);
1063                    d.setTitle(title);
1064                    d.setMessage(text);
1065                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1066                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1067                    mUidAlert = d;
1068                    d.show();
1069                }
1070            } break;
1071            case IM_FEELING_LUCKY_MSG: {
1072                if (mUidAlert != null) {
1073                    mUidAlert.dismiss();
1074                    mUidAlert = null;
1075                }
1076            } break;
1077            case PROC_START_TIMEOUT_MSG: {
1078                if (mDidDexOpt) {
1079                    mDidDexOpt = false;
1080                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1081                    nmsg.obj = msg.obj;
1082                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1083                    return;
1084                }
1085                ProcessRecord app = (ProcessRecord)msg.obj;
1086                synchronized (ActivityManagerService.this) {
1087                    processStartTimedOutLocked(app);
1088                }
1089            } break;
1090            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1091                synchronized (ActivityManagerService.this) {
1092                    doPendingActivityLaunchesLocked(true);
1093                }
1094            } break;
1095            case KILL_APPLICATION_MSG: {
1096                synchronized (ActivityManagerService.this) {
1097                    int uid = msg.arg1;
1098                    boolean restart = (msg.arg2 == 1);
1099                    String pkg = (String) msg.obj;
1100                    forceStopPackageLocked(pkg, uid, restart, false, true, false,
1101                            UserHandle.getUserId(uid));
1102                }
1103            } break;
1104            case FINALIZE_PENDING_INTENT_MSG: {
1105                ((PendingIntentRecord)msg.obj).completeFinalize();
1106            } break;
1107            case POST_HEAVY_NOTIFICATION_MSG: {
1108                INotificationManager inm = NotificationManager.getService();
1109                if (inm == null) {
1110                    return;
1111                }
1112
1113                ActivityRecord root = (ActivityRecord)msg.obj;
1114                ProcessRecord process = root.app;
1115                if (process == null) {
1116                    return;
1117                }
1118
1119                try {
1120                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1121                    String text = mContext.getString(R.string.heavy_weight_notification,
1122                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1123                    Notification notification = new Notification();
1124                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1125                    notification.when = 0;
1126                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1127                    notification.tickerText = text;
1128                    notification.defaults = 0; // please be quiet
1129                    notification.sound = null;
1130                    notification.vibrate = null;
1131                    notification.setLatestEventInfo(context, text,
1132                            mContext.getText(R.string.heavy_weight_notification_detail),
1133                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1134                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1135                                    new UserHandle(root.userId)));
1136
1137                    try {
1138                        int[] outId = new int[1];
1139                        inm.enqueueNotificationWithTag("android", null,
1140                                R.string.heavy_weight_notification,
1141                                notification, outId, root.userId);
1142                    } catch (RuntimeException e) {
1143                        Slog.w(ActivityManagerService.TAG,
1144                                "Error showing notification for heavy-weight app", e);
1145                    } catch (RemoteException e) {
1146                    }
1147                } catch (NameNotFoundException e) {
1148                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1149                }
1150            } break;
1151            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1152                INotificationManager inm = NotificationManager.getService();
1153                if (inm == null) {
1154                    return;
1155                }
1156                try {
1157                    inm.cancelNotificationWithTag("android", null,
1158                            R.string.heavy_weight_notification,  msg.arg1);
1159                } catch (RuntimeException e) {
1160                    Slog.w(ActivityManagerService.TAG,
1161                            "Error canceling notification for service", e);
1162                } catch (RemoteException e) {
1163                }
1164            } break;
1165            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1166                synchronized (ActivityManagerService.this) {
1167                    checkExcessivePowerUsageLocked(true);
1168                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1169                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1170                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1171                }
1172            } break;
1173            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1174                synchronized (ActivityManagerService.this) {
1175                    ActivityRecord ar = (ActivityRecord)msg.obj;
1176                    if (mCompatModeDialog != null) {
1177                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1178                                ar.info.applicationInfo.packageName)) {
1179                            return;
1180                        }
1181                        mCompatModeDialog.dismiss();
1182                        mCompatModeDialog = null;
1183                    }
1184                    if (ar != null && false) {
1185                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1186                                ar.packageName)) {
1187                            int mode = mCompatModePackages.computeCompatModeLocked(
1188                                    ar.info.applicationInfo);
1189                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1190                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1191                                mCompatModeDialog = new CompatModeDialog(
1192                                        ActivityManagerService.this, mContext,
1193                                        ar.info.applicationInfo);
1194                                mCompatModeDialog.show();
1195                            }
1196                        }
1197                    }
1198                }
1199                break;
1200            }
1201            case DISPATCH_PROCESSES_CHANGED: {
1202                dispatchProcessesChanged();
1203                break;
1204            }
1205            case DISPATCH_PROCESS_DIED: {
1206                final int pid = msg.arg1;
1207                final int uid = msg.arg2;
1208                dispatchProcessDied(pid, uid);
1209                break;
1210            }
1211            case REPORT_MEM_USAGE: {
1212                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1213                if (!isDebuggable) {
1214                    return;
1215                }
1216                synchronized (ActivityManagerService.this) {
1217                    long now = SystemClock.uptimeMillis();
1218                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1219                        // Don't report more than every 5 minutes to somewhat
1220                        // avoid spamming.
1221                        return;
1222                    }
1223                    mLastMemUsageReportTime = now;
1224                }
1225                Thread thread = new Thread() {
1226                    @Override public void run() {
1227                        StringBuilder dropBuilder = new StringBuilder(1024);
1228                        StringBuilder logBuilder = new StringBuilder(1024);
1229                        StringWriter oomSw = new StringWriter();
1230                        PrintWriter oomPw = new PrintWriter(oomSw);
1231                        StringWriter catSw = new StringWriter();
1232                        PrintWriter catPw = new PrintWriter(catSw);
1233                        String[] emptyArgs = new String[] { };
1234                        StringBuilder tag = new StringBuilder(128);
1235                        StringBuilder stack = new StringBuilder(128);
1236                        tag.append("Low on memory -- ");
1237                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1238                                tag, stack);
1239                        dropBuilder.append(stack);
1240                        dropBuilder.append('\n');
1241                        dropBuilder.append('\n');
1242                        String oomString = oomSw.toString();
1243                        dropBuilder.append(oomString);
1244                        dropBuilder.append('\n');
1245                        logBuilder.append(oomString);
1246                        try {
1247                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1248                                    "procrank", });
1249                            final InputStreamReader converter = new InputStreamReader(
1250                                    proc.getInputStream());
1251                            BufferedReader in = new BufferedReader(converter);
1252                            String line;
1253                            while (true) {
1254                                line = in.readLine();
1255                                if (line == null) {
1256                                    break;
1257                                }
1258                                if (line.length() > 0) {
1259                                    logBuilder.append(line);
1260                                    logBuilder.append('\n');
1261                                }
1262                                dropBuilder.append(line);
1263                                dropBuilder.append('\n');
1264                            }
1265                            converter.close();
1266                        } catch (IOException e) {
1267                        }
1268                        synchronized (ActivityManagerService.this) {
1269                            catPw.println();
1270                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1271                            catPw.println();
1272                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1273                                    false, false, null);
1274                            catPw.println();
1275                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1276                        }
1277                        dropBuilder.append(catSw.toString());
1278                        addErrorToDropBox("lowmem", null, "system_server", null,
1279                                null, tag.toString(), dropBuilder.toString(), null, null);
1280                        Slog.i(TAG, logBuilder.toString());
1281                        synchronized (ActivityManagerService.this) {
1282                            long now = SystemClock.uptimeMillis();
1283                            if (mLastMemUsageReportTime < now) {
1284                                mLastMemUsageReportTime = now;
1285                            }
1286                        }
1287                    }
1288                };
1289                thread.start();
1290                break;
1291            }
1292            }
1293        }
1294    };
1295
1296    public static void setSystemProcess() {
1297        try {
1298            ActivityManagerService m = mSelf;
1299
1300            ServiceManager.addService("activity", m, true);
1301            ServiceManager.addService("meminfo", new MemBinder(m));
1302            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1303            ServiceManager.addService("dbinfo", new DbBinder(m));
1304            if (MONITOR_CPU_USAGE) {
1305                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1306            }
1307            ServiceManager.addService("permission", new PermissionController(m));
1308
1309            ApplicationInfo info =
1310                mSelf.mContext.getPackageManager().getApplicationInfo(
1311                            "android", STOCK_PM_FLAGS);
1312            mSystemThread.installSystemApplicationInfo(info);
1313
1314            synchronized (mSelf) {
1315                ProcessRecord app = mSelf.newProcessRecordLocked(
1316                        mSystemThread.getApplicationThread(), info,
1317                        info.processName, false);
1318                app.persistent = true;
1319                app.pid = MY_PID;
1320                app.maxAdj = ProcessList.SYSTEM_ADJ;
1321                mSelf.mProcessNames.put(app.processName, app.uid, app);
1322                synchronized (mSelf.mPidsSelfLocked) {
1323                    mSelf.mPidsSelfLocked.put(app.pid, app);
1324                }
1325                mSelf.updateLruProcessLocked(app, true, true);
1326            }
1327        } catch (PackageManager.NameNotFoundException e) {
1328            throw new RuntimeException(
1329                    "Unable to find android system package", e);
1330        }
1331    }
1332
1333    public void setWindowManager(WindowManagerService wm) {
1334        mWindowManager = wm;
1335    }
1336
1337    public static final Context main(int factoryTest) {
1338        AThread thr = new AThread();
1339        thr.start();
1340
1341        synchronized (thr) {
1342            while (thr.mService == null) {
1343                try {
1344                    thr.wait();
1345                } catch (InterruptedException e) {
1346                }
1347            }
1348        }
1349
1350        ActivityManagerService m = thr.mService;
1351        mSelf = m;
1352        ActivityThread at = ActivityThread.systemMain();
1353        mSystemThread = at;
1354        Context context = at.getSystemContext();
1355        context.setTheme(android.R.style.Theme_Holo);
1356        m.mContext = context;
1357        m.mFactoryTest = factoryTest;
1358        m.mMainStack = new ActivityStack(m, context, true);
1359
1360        m.mBatteryStatsService.publish(context);
1361        m.mUsageStatsService.publish(context);
1362
1363        synchronized (thr) {
1364            thr.mReady = true;
1365            thr.notifyAll();
1366        }
1367
1368        m.startRunning(null, null, null, null);
1369
1370        return context;
1371    }
1372
1373    public static ActivityManagerService self() {
1374        return mSelf;
1375    }
1376
1377    static class AThread extends Thread {
1378        ActivityManagerService mService;
1379        boolean mReady = false;
1380
1381        public AThread() {
1382            super("ActivityManager");
1383        }
1384
1385        public void run() {
1386            Looper.prepare();
1387
1388            android.os.Process.setThreadPriority(
1389                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1390            android.os.Process.setCanSelfBackground(false);
1391
1392            ActivityManagerService m = new ActivityManagerService();
1393
1394            synchronized (this) {
1395                mService = m;
1396                notifyAll();
1397            }
1398
1399            synchronized (this) {
1400                while (!mReady) {
1401                    try {
1402                        wait();
1403                    } catch (InterruptedException e) {
1404                    }
1405                }
1406            }
1407
1408            // For debug builds, log event loop stalls to dropbox for analysis.
1409            if (StrictMode.conditionallyEnableDebugLogging()) {
1410                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1411            }
1412
1413            Looper.loop();
1414        }
1415    }
1416
1417    static class MemBinder extends Binder {
1418        ActivityManagerService mActivityManagerService;
1419        MemBinder(ActivityManagerService activityManagerService) {
1420            mActivityManagerService = activityManagerService;
1421        }
1422
1423        @Override
1424        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1425            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1426                    != PackageManager.PERMISSION_GRANTED) {
1427                pw.println("Permission Denial: can't dump meminfo from from pid="
1428                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1429                        + " without permission " + android.Manifest.permission.DUMP);
1430                return;
1431            }
1432
1433            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1434                    false, null, null, null);
1435        }
1436    }
1437
1438    static class GraphicsBinder extends Binder {
1439        ActivityManagerService mActivityManagerService;
1440        GraphicsBinder(ActivityManagerService activityManagerService) {
1441            mActivityManagerService = activityManagerService;
1442        }
1443
1444        @Override
1445        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1446            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1447                    != PackageManager.PERMISSION_GRANTED) {
1448                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1449                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1450                        + " without permission " + android.Manifest.permission.DUMP);
1451                return;
1452            }
1453
1454            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1455        }
1456    }
1457
1458    static class DbBinder extends Binder {
1459        ActivityManagerService mActivityManagerService;
1460        DbBinder(ActivityManagerService activityManagerService) {
1461            mActivityManagerService = activityManagerService;
1462        }
1463
1464        @Override
1465        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1466            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1467                    != PackageManager.PERMISSION_GRANTED) {
1468                pw.println("Permission Denial: can't dump dbinfo from from pid="
1469                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1470                        + " without permission " + android.Manifest.permission.DUMP);
1471                return;
1472            }
1473
1474            mActivityManagerService.dumpDbInfo(fd, pw, args);
1475        }
1476    }
1477
1478    static class CpuBinder extends Binder {
1479        ActivityManagerService mActivityManagerService;
1480        CpuBinder(ActivityManagerService activityManagerService) {
1481            mActivityManagerService = activityManagerService;
1482        }
1483
1484        @Override
1485        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1486            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1487                    != PackageManager.PERMISSION_GRANTED) {
1488                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1489                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1490                        + " without permission " + android.Manifest.permission.DUMP);
1491                return;
1492            }
1493
1494            synchronized (mActivityManagerService.mProcessStatsThread) {
1495                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1496                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1497                        SystemClock.uptimeMillis()));
1498            }
1499        }
1500    }
1501
1502    private ActivityManagerService() {
1503        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1504
1505        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1506        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1507        mBroadcastQueues[0] = mFgBroadcastQueue;
1508        mBroadcastQueues[1] = mBgBroadcastQueue;
1509
1510        mServices = new ActiveServices(this);
1511
1512        File dataDir = Environment.getDataDirectory();
1513        File systemDir = new File(dataDir, "system");
1514        systemDir.mkdirs();
1515        mBatteryStatsService = new BatteryStatsService(new File(
1516                systemDir, "batterystats.bin").toString());
1517        mBatteryStatsService.getActiveStatistics().readLocked();
1518        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1519        mOnBattery = DEBUG_POWER ? true
1520                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1521        mBatteryStatsService.getActiveStatistics().setCallback(this);
1522
1523        mUsageStatsService = new UsageStatsService(new File(
1524                systemDir, "usagestats").toString());
1525        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1526
1527        // User 0 is the first and only user that runs at boot.
1528        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1529
1530        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1531            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1532
1533        mConfiguration.setToDefaults();
1534        mConfiguration.setLocale(Locale.getDefault());
1535
1536        mConfigurationSeq = mConfiguration.seq = 1;
1537        mProcessStats.init();
1538
1539        mCompatModePackages = new CompatModePackages(this, systemDir);
1540
1541        // Add ourself to the Watchdog monitors.
1542        Watchdog.getInstance().addMonitor(this);
1543
1544        mProcessStatsThread = new Thread("ProcessStats") {
1545            public void run() {
1546                while (true) {
1547                    try {
1548                        try {
1549                            synchronized(this) {
1550                                final long now = SystemClock.uptimeMillis();
1551                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1552                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1553                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1554                                //        + ", write delay=" + nextWriteDelay);
1555                                if (nextWriteDelay < nextCpuDelay) {
1556                                    nextCpuDelay = nextWriteDelay;
1557                                }
1558                                if (nextCpuDelay > 0) {
1559                                    mProcessStatsMutexFree.set(true);
1560                                    this.wait(nextCpuDelay);
1561                                }
1562                            }
1563                        } catch (InterruptedException e) {
1564                        }
1565                        updateCpuStatsNow();
1566                    } catch (Exception e) {
1567                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1568                    }
1569                }
1570            }
1571        };
1572        mProcessStatsThread.start();
1573    }
1574
1575    @Override
1576    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1577            throws RemoteException {
1578        if (code == SYSPROPS_TRANSACTION) {
1579            // We need to tell all apps about the system property change.
1580            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1581            synchronized(this) {
1582                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1583                    final int NA = apps.size();
1584                    for (int ia=0; ia<NA; ia++) {
1585                        ProcessRecord app = apps.valueAt(ia);
1586                        if (app.thread != null) {
1587                            procs.add(app.thread.asBinder());
1588                        }
1589                    }
1590                }
1591            }
1592
1593            int N = procs.size();
1594            for (int i=0; i<N; i++) {
1595                Parcel data2 = Parcel.obtain();
1596                try {
1597                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1598                } catch (RemoteException e) {
1599                }
1600                data2.recycle();
1601            }
1602        }
1603        try {
1604            return super.onTransact(code, data, reply, flags);
1605        } catch (RuntimeException e) {
1606            // The activity manager only throws security exceptions, so let's
1607            // log all others.
1608            if (!(e instanceof SecurityException)) {
1609                Slog.e(TAG, "Activity Manager Crash", e);
1610            }
1611            throw e;
1612        }
1613    }
1614
1615    void updateCpuStats() {
1616        final long now = SystemClock.uptimeMillis();
1617        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1618            return;
1619        }
1620        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1621            synchronized (mProcessStatsThread) {
1622                mProcessStatsThread.notify();
1623            }
1624        }
1625    }
1626
1627    void updateCpuStatsNow() {
1628        synchronized (mProcessStatsThread) {
1629            mProcessStatsMutexFree.set(false);
1630            final long now = SystemClock.uptimeMillis();
1631            boolean haveNewCpuStats = false;
1632
1633            if (MONITOR_CPU_USAGE &&
1634                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1635                mLastCpuTime.set(now);
1636                haveNewCpuStats = true;
1637                mProcessStats.update();
1638                //Slog.i(TAG, mProcessStats.printCurrentState());
1639                //Slog.i(TAG, "Total CPU usage: "
1640                //        + mProcessStats.getTotalCpuPercent() + "%");
1641
1642                // Slog the cpu usage if the property is set.
1643                if ("true".equals(SystemProperties.get("events.cpu"))) {
1644                    int user = mProcessStats.getLastUserTime();
1645                    int system = mProcessStats.getLastSystemTime();
1646                    int iowait = mProcessStats.getLastIoWaitTime();
1647                    int irq = mProcessStats.getLastIrqTime();
1648                    int softIrq = mProcessStats.getLastSoftIrqTime();
1649                    int idle = mProcessStats.getLastIdleTime();
1650
1651                    int total = user + system + iowait + irq + softIrq + idle;
1652                    if (total == 0) total = 1;
1653
1654                    EventLog.writeEvent(EventLogTags.CPU,
1655                            ((user+system+iowait+irq+softIrq) * 100) / total,
1656                            (user * 100) / total,
1657                            (system * 100) / total,
1658                            (iowait * 100) / total,
1659                            (irq * 100) / total,
1660                            (softIrq * 100) / total);
1661                }
1662            }
1663
1664            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1665            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1666            synchronized(bstats) {
1667                synchronized(mPidsSelfLocked) {
1668                    if (haveNewCpuStats) {
1669                        if (mOnBattery) {
1670                            int perc = bstats.startAddingCpuLocked();
1671                            int totalUTime = 0;
1672                            int totalSTime = 0;
1673                            final int N = mProcessStats.countStats();
1674                            for (int i=0; i<N; i++) {
1675                                ProcessStats.Stats st = mProcessStats.getStats(i);
1676                                if (!st.working) {
1677                                    continue;
1678                                }
1679                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1680                                int otherUTime = (st.rel_utime*perc)/100;
1681                                int otherSTime = (st.rel_stime*perc)/100;
1682                                totalUTime += otherUTime;
1683                                totalSTime += otherSTime;
1684                                if (pr != null) {
1685                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1686                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1687                                            st.rel_stime-otherSTime);
1688                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1689                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1690                                } else {
1691                                    BatteryStatsImpl.Uid.Proc ps =
1692                                            bstats.getProcessStatsLocked(st.name, st.pid);
1693                                    if (ps != null) {
1694                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1695                                                st.rel_stime-otherSTime);
1696                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1697                                    }
1698                                }
1699                            }
1700                            bstats.finishAddingCpuLocked(perc, totalUTime,
1701                                    totalSTime, cpuSpeedTimes);
1702                        }
1703                    }
1704                }
1705
1706                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1707                    mLastWriteTime = now;
1708                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1709                }
1710            }
1711        }
1712    }
1713
1714    @Override
1715    public void batteryNeedsCpuUpdate() {
1716        updateCpuStatsNow();
1717    }
1718
1719    @Override
1720    public void batteryPowerChanged(boolean onBattery) {
1721        // When plugging in, update the CPU stats first before changing
1722        // the plug state.
1723        updateCpuStatsNow();
1724        synchronized (this) {
1725            synchronized(mPidsSelfLocked) {
1726                mOnBattery = DEBUG_POWER ? true : onBattery;
1727            }
1728        }
1729    }
1730
1731    /**
1732     * Initialize the application bind args. These are passed to each
1733     * process when the bindApplication() IPC is sent to the process. They're
1734     * lazily setup to make sure the services are running when they're asked for.
1735     */
1736    private HashMap<String, IBinder> getCommonServicesLocked() {
1737        if (mAppBindArgs == null) {
1738            mAppBindArgs = new HashMap<String, IBinder>();
1739
1740            // Setup the application init args
1741            mAppBindArgs.put("package", ServiceManager.getService("package"));
1742            mAppBindArgs.put("window", ServiceManager.getService("window"));
1743            mAppBindArgs.put(Context.ALARM_SERVICE,
1744                    ServiceManager.getService(Context.ALARM_SERVICE));
1745        }
1746        return mAppBindArgs;
1747    }
1748
1749    final void setFocusedActivityLocked(ActivityRecord r) {
1750        if (mFocusedActivity != r) {
1751            mFocusedActivity = r;
1752            if (r != null) {
1753                mWindowManager.setFocusedApp(r.appToken, true);
1754            }
1755        }
1756    }
1757
1758    private final void updateLruProcessInternalLocked(ProcessRecord app,
1759            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1760        // put it on the LRU to keep track of when it should be exited.
1761        int lrui = mLruProcesses.indexOf(app);
1762        if (lrui >= 0) mLruProcesses.remove(lrui);
1763
1764        int i = mLruProcesses.size()-1;
1765        int skipTop = 0;
1766
1767        app.lruSeq = mLruSeq;
1768
1769        // compute the new weight for this process.
1770        if (updateActivityTime) {
1771            app.lastActivityTime = SystemClock.uptimeMillis();
1772        }
1773        if (app.activities.size() > 0) {
1774            // If this process has activities, we more strongly want to keep
1775            // it around.
1776            app.lruWeight = app.lastActivityTime;
1777        } else if (app.pubProviders.size() > 0) {
1778            // If this process contains content providers, we want to keep
1779            // it a little more strongly.
1780            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1781            // Also don't let it kick out the first few "real" hidden processes.
1782            skipTop = ProcessList.MIN_HIDDEN_APPS;
1783        } else {
1784            // If this process doesn't have activities, we less strongly
1785            // want to keep it around, and generally want to avoid getting
1786            // in front of any very recently used activities.
1787            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1788            // Also don't let it kick out the first few "real" hidden processes.
1789            skipTop = ProcessList.MIN_HIDDEN_APPS;
1790        }
1791
1792        while (i >= 0) {
1793            ProcessRecord p = mLruProcesses.get(i);
1794            // If this app shouldn't be in front of the first N background
1795            // apps, then skip over that many that are currently hidden.
1796            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1797                skipTop--;
1798            }
1799            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1800                mLruProcesses.add(i+1, app);
1801                break;
1802            }
1803            i--;
1804        }
1805        if (i < 0) {
1806            mLruProcesses.add(0, app);
1807        }
1808
1809        // If the app is currently using a content provider or service,
1810        // bump those processes as well.
1811        if (app.connections.size() > 0) {
1812            for (ConnectionRecord cr : app.connections) {
1813                if (cr.binding != null && cr.binding.service != null
1814                        && cr.binding.service.app != null
1815                        && cr.binding.service.app.lruSeq != mLruSeq) {
1816                    updateLruProcessInternalLocked(cr.binding.service.app, false,
1817                            updateActivityTime, i+1);
1818                }
1819            }
1820        }
1821        for (int j=app.conProviders.size()-1; j>=0; j--) {
1822            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1823            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1824                updateLruProcessInternalLocked(cpr.proc, false,
1825                        updateActivityTime, i+1);
1826            }
1827        }
1828
1829        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1830        if (oomAdj) {
1831            updateOomAdjLocked();
1832        }
1833    }
1834
1835    final void updateLruProcessLocked(ProcessRecord app,
1836            boolean oomAdj, boolean updateActivityTime) {
1837        mLruSeq++;
1838        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1839    }
1840
1841    final ProcessRecord getProcessRecordLocked(
1842            String processName, int uid) {
1843        if (uid == Process.SYSTEM_UID) {
1844            // The system gets to run in any process.  If there are multiple
1845            // processes with the same uid, just pick the first (this
1846            // should never happen).
1847            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1848                    processName);
1849            if (procs == null) return null;
1850            final int N = procs.size();
1851            for (int i = 0; i < N; i++) {
1852                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1853            }
1854        }
1855        ProcessRecord proc = mProcessNames.get(processName, uid);
1856        return proc;
1857    }
1858
1859    void ensurePackageDexOpt(String packageName) {
1860        IPackageManager pm = AppGlobals.getPackageManager();
1861        try {
1862            if (pm.performDexOpt(packageName)) {
1863                mDidDexOpt = true;
1864            }
1865        } catch (RemoteException e) {
1866        }
1867    }
1868
1869    boolean isNextTransitionForward() {
1870        int transit = mWindowManager.getPendingAppTransition();
1871        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1872                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1873                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1874    }
1875
1876    final ProcessRecord startProcessLocked(String processName,
1877            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1878            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1879            boolean isolated) {
1880        ProcessRecord app;
1881        if (!isolated) {
1882            app = getProcessRecordLocked(processName, info.uid);
1883        } else {
1884            // If this is an isolated process, it can't re-use an existing process.
1885            app = null;
1886        }
1887        // We don't have to do anything more if:
1888        // (1) There is an existing application record; and
1889        // (2) The caller doesn't think it is dead, OR there is no thread
1890        //     object attached to it so we know it couldn't have crashed; and
1891        // (3) There is a pid assigned to it, so it is either starting or
1892        //     already running.
1893        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1894                + " app=" + app + " knownToBeDead=" + knownToBeDead
1895                + " thread=" + (app != null ? app.thread : null)
1896                + " pid=" + (app != null ? app.pid : -1));
1897        if (app != null && app.pid > 0) {
1898            if (!knownToBeDead || app.thread == null) {
1899                // We already have the app running, or are waiting for it to
1900                // come up (we have a pid but not yet its thread), so keep it.
1901                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1902                // If this is a new package in the process, add the package to the list
1903                app.addPackage(info.packageName);
1904                return app;
1905            } else {
1906                // An application record is attached to a previous process,
1907                // clean it up now.
1908                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1909                handleAppDiedLocked(app, true, true);
1910            }
1911        }
1912
1913        String hostingNameStr = hostingName != null
1914                ? hostingName.flattenToShortString() : null;
1915
1916        if (!isolated) {
1917            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1918                // If we are in the background, then check to see if this process
1919                // is bad.  If so, we will just silently fail.
1920                if (mBadProcesses.get(info.processName, info.uid) != null) {
1921                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1922                            + "/" + info.processName);
1923                    return null;
1924                }
1925            } else {
1926                // When the user is explicitly starting a process, then clear its
1927                // crash count so that we won't make it bad until they see at
1928                // least one crash dialog again, and make the process good again
1929                // if it had been bad.
1930                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1931                        + "/" + info.processName);
1932                mProcessCrashTimes.remove(info.processName, info.uid);
1933                if (mBadProcesses.get(info.processName, info.uid) != null) {
1934                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1935                            info.processName);
1936                    mBadProcesses.remove(info.processName, info.uid);
1937                    if (app != null) {
1938                        app.bad = false;
1939                    }
1940                }
1941            }
1942        }
1943
1944        if (app == null) {
1945            app = newProcessRecordLocked(null, info, processName, isolated);
1946            if (app == null) {
1947                Slog.w(TAG, "Failed making new process record for "
1948                        + processName + "/" + info.uid + " isolated=" + isolated);
1949                return null;
1950            }
1951            mProcessNames.put(processName, app.uid, app);
1952            if (isolated) {
1953                mIsolatedProcesses.put(app.uid, app);
1954            }
1955        } else {
1956            // If this is a new package in the process, add the package to the list
1957            app.addPackage(info.packageName);
1958        }
1959
1960        // If the system is not ready yet, then hold off on starting this
1961        // process until it is.
1962        if (!mProcessesReady
1963                && !isAllowedWhileBooting(info)
1964                && !allowWhileBooting) {
1965            if (!mProcessesOnHold.contains(app)) {
1966                mProcessesOnHold.add(app);
1967            }
1968            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1969            return app;
1970        }
1971
1972        startProcessLocked(app, hostingType, hostingNameStr);
1973        return (app.pid != 0) ? app : null;
1974    }
1975
1976    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1977        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1978    }
1979
1980    private final void startProcessLocked(ProcessRecord app,
1981            String hostingType, String hostingNameStr) {
1982        if (app.pid > 0 && app.pid != MY_PID) {
1983            synchronized (mPidsSelfLocked) {
1984                mPidsSelfLocked.remove(app.pid);
1985                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1986            }
1987            app.setPid(0);
1988        }
1989
1990        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1991                "startProcessLocked removing on hold: " + app);
1992        mProcessesOnHold.remove(app);
1993
1994        updateCpuStats();
1995
1996        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1997        mProcDeaths[0] = 0;
1998
1999        try {
2000            int uid = app.uid;
2001
2002            int[] gids = null;
2003            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2004            if (!app.isolated) {
2005                try {
2006                    final PackageManager pm = mContext.getPackageManager();
2007                    gids = pm.getPackageGids(app.info.packageName);
2008
2009                    if (Environment.isExternalStorageEmulated()) {
2010                        if (pm.checkPermission(
2011                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2012                                app.info.packageName) == PERMISSION_GRANTED) {
2013                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2014                        } else {
2015                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2016                        }
2017                    }
2018                } catch (PackageManager.NameNotFoundException e) {
2019                    Slog.w(TAG, "Unable to retrieve gids", e);
2020                }
2021            }
2022            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2023                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2024                        && mTopComponent != null
2025                        && app.processName.equals(mTopComponent.getPackageName())) {
2026                    uid = 0;
2027                }
2028                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2029                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2030                    uid = 0;
2031                }
2032            }
2033            int debugFlags = 0;
2034            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2035                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2036                // Also turn on CheckJNI for debuggable apps. It's quite
2037                // awkward to turn on otherwise.
2038                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2039            }
2040            // Run the app in safe mode if its manifest requests so or the
2041            // system is booted in safe mode.
2042            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2043                Zygote.systemInSafeMode == true) {
2044                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2045            }
2046            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2047                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2048            }
2049            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2050                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2051            }
2052            if ("1".equals(SystemProperties.get("debug.assert"))) {
2053                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2054            }
2055
2056            // Start the process.  It will either succeed and return a result containing
2057            // the PID of the new process, or else throw a RuntimeException.
2058            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2059                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2060                    app.info.targetSdkVersion, null, null);
2061
2062            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2063            synchronized (bs) {
2064                if (bs.isOnBattery()) {
2065                    app.batteryStats.incStartsLocked();
2066                }
2067            }
2068
2069            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2070                    app.processName, hostingType,
2071                    hostingNameStr != null ? hostingNameStr : "");
2072
2073            if (app.persistent) {
2074                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2075            }
2076
2077            StringBuilder buf = mStringBuilder;
2078            buf.setLength(0);
2079            buf.append("Start proc ");
2080            buf.append(app.processName);
2081            buf.append(" for ");
2082            buf.append(hostingType);
2083            if (hostingNameStr != null) {
2084                buf.append(" ");
2085                buf.append(hostingNameStr);
2086            }
2087            buf.append(": pid=");
2088            buf.append(startResult.pid);
2089            buf.append(" uid=");
2090            buf.append(uid);
2091            buf.append(" gids={");
2092            if (gids != null) {
2093                for (int gi=0; gi<gids.length; gi++) {
2094                    if (gi != 0) buf.append(", ");
2095                    buf.append(gids[gi]);
2096
2097                }
2098            }
2099            buf.append("}");
2100            Slog.i(TAG, buf.toString());
2101            app.setPid(startResult.pid);
2102            app.usingWrapper = startResult.usingWrapper;
2103            app.removed = false;
2104            synchronized (mPidsSelfLocked) {
2105                this.mPidsSelfLocked.put(startResult.pid, app);
2106                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2107                msg.obj = app;
2108                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2109                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2110            }
2111        } catch (RuntimeException e) {
2112            // XXX do better error recovery.
2113            app.setPid(0);
2114            Slog.e(TAG, "Failure starting process " + app.processName, e);
2115        }
2116    }
2117
2118    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2119        if (resumed) {
2120            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2121        } else {
2122            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2123        }
2124    }
2125
2126    boolean startHomeActivityLocked(int userId, UserStartedState startingUser) {
2127        if (mHeadless) {
2128            // Added because none of the other calls to ensureBootCompleted seem to fire
2129            // when running headless.
2130            ensureBootCompleted();
2131            return false;
2132        }
2133
2134        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2135                && mTopAction == null) {
2136            // We are running in factory test mode, but unable to find
2137            // the factory test app, so just sit around displaying the
2138            // error message and don't try to start anything.
2139            return false;
2140        }
2141        Intent intent = new Intent(
2142            mTopAction,
2143            mTopData != null ? Uri.parse(mTopData) : null);
2144        intent.setComponent(mTopComponent);
2145        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2146            intent.addCategory(Intent.CATEGORY_HOME);
2147        }
2148        ActivityInfo aInfo =
2149            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2150        if (aInfo != null) {
2151            intent.setComponent(new ComponentName(
2152                    aInfo.applicationInfo.packageName, aInfo.name));
2153            // Don't do this if the home app is currently being
2154            // instrumented.
2155            aInfo = new ActivityInfo(aInfo);
2156            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2157            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2158                    aInfo.applicationInfo.uid);
2159            if (app == null || app.instrumentationClass == null) {
2160                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2161                mMainStack.startActivityLocked(null, intent, null, aInfo,
2162                        null, null, 0, 0, 0, 0, null, false, null);
2163            }
2164        }
2165        if (startingUser != null) {
2166            mMainStack.addStartingUserLocked(startingUser);
2167        }
2168
2169        return true;
2170    }
2171
2172    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2173        ActivityInfo ai = null;
2174        ComponentName comp = intent.getComponent();
2175        try {
2176            if (comp != null) {
2177                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2178            } else {
2179                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2180                        intent,
2181                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2182                            flags, userId);
2183
2184                if (info != null) {
2185                    ai = info.activityInfo;
2186                }
2187            }
2188        } catch (RemoteException e) {
2189            // ignore
2190        }
2191
2192        return ai;
2193    }
2194
2195    /**
2196     * Starts the "new version setup screen" if appropriate.
2197     */
2198    void startSetupActivityLocked() {
2199        // Only do this once per boot.
2200        if (mCheckedForSetup) {
2201            return;
2202        }
2203
2204        // We will show this screen if the current one is a different
2205        // version than the last one shown, and we are not running in
2206        // low-level factory test mode.
2207        final ContentResolver resolver = mContext.getContentResolver();
2208        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2209                Settings.Secure.getInt(resolver,
2210                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2211            mCheckedForSetup = true;
2212
2213            // See if we should be showing the platform update setup UI.
2214            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2215            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2216                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2217
2218            // We don't allow third party apps to replace this.
2219            ResolveInfo ri = null;
2220            for (int i=0; ris != null && i<ris.size(); i++) {
2221                if ((ris.get(i).activityInfo.applicationInfo.flags
2222                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2223                    ri = ris.get(i);
2224                    break;
2225                }
2226            }
2227
2228            if (ri != null) {
2229                String vers = ri.activityInfo.metaData != null
2230                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2231                        : null;
2232                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2233                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2234                            Intent.METADATA_SETUP_VERSION);
2235                }
2236                String lastVers = Settings.Secure.getString(
2237                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2238                if (vers != null && !vers.equals(lastVers)) {
2239                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2240                    intent.setComponent(new ComponentName(
2241                            ri.activityInfo.packageName, ri.activityInfo.name));
2242                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2243                            null, null, 0, 0, 0, 0, null, false, null);
2244                }
2245            }
2246        }
2247    }
2248
2249    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2250        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2251    }
2252
2253    void enforceNotIsolatedCaller(String caller) {
2254        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2255            throw new SecurityException("Isolated process not allowed to call " + caller);
2256        }
2257    }
2258
2259    public int getFrontActivityScreenCompatMode() {
2260        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2261        synchronized (this) {
2262            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2263        }
2264    }
2265
2266    public void setFrontActivityScreenCompatMode(int mode) {
2267        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2268                "setFrontActivityScreenCompatMode");
2269        synchronized (this) {
2270            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2271        }
2272    }
2273
2274    public int getPackageScreenCompatMode(String packageName) {
2275        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2276        synchronized (this) {
2277            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2278        }
2279    }
2280
2281    public void setPackageScreenCompatMode(String packageName, int mode) {
2282        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2283                "setPackageScreenCompatMode");
2284        synchronized (this) {
2285            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2286        }
2287    }
2288
2289    public boolean getPackageAskScreenCompat(String packageName) {
2290        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2291        synchronized (this) {
2292            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2293        }
2294    }
2295
2296    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2297        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2298                "setPackageAskScreenCompat");
2299        synchronized (this) {
2300            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2301        }
2302    }
2303
2304    void reportResumedActivityLocked(ActivityRecord r) {
2305        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2306        updateUsageStats(r, true);
2307    }
2308
2309    private void dispatchProcessesChanged() {
2310        int N;
2311        synchronized (this) {
2312            N = mPendingProcessChanges.size();
2313            if (mActiveProcessChanges.length < N) {
2314                mActiveProcessChanges = new ProcessChangeItem[N];
2315            }
2316            mPendingProcessChanges.toArray(mActiveProcessChanges);
2317            mAvailProcessChanges.addAll(mPendingProcessChanges);
2318            mPendingProcessChanges.clear();
2319            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2320        }
2321        int i = mProcessObservers.beginBroadcast();
2322        while (i > 0) {
2323            i--;
2324            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2325            if (observer != null) {
2326                try {
2327                    for (int j=0; j<N; j++) {
2328                        ProcessChangeItem item = mActiveProcessChanges[j];
2329                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2330                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2331                                    + item.pid + " uid=" + item.uid + ": "
2332                                    + item.foregroundActivities);
2333                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2334                                    item.foregroundActivities);
2335                        }
2336                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2337                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2338                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2339                            observer.onImportanceChanged(item.pid, item.uid,
2340                                    item.importance);
2341                        }
2342                    }
2343                } catch (RemoteException e) {
2344                }
2345            }
2346        }
2347        mProcessObservers.finishBroadcast();
2348    }
2349
2350    private void dispatchProcessDied(int pid, int uid) {
2351        int i = mProcessObservers.beginBroadcast();
2352        while (i > 0) {
2353            i--;
2354            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2355            if (observer != null) {
2356                try {
2357                    observer.onProcessDied(pid, uid);
2358                } catch (RemoteException e) {
2359                }
2360            }
2361        }
2362        mProcessObservers.finishBroadcast();
2363    }
2364
2365    final void doPendingActivityLaunchesLocked(boolean doResume) {
2366        final int N = mPendingActivityLaunches.size();
2367        if (N <= 0) {
2368            return;
2369        }
2370        for (int i=0; i<N; i++) {
2371            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2372            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2373                    pal.startFlags, doResume && i == (N-1), null);
2374        }
2375        mPendingActivityLaunches.clear();
2376    }
2377
2378    public final int startActivity(IApplicationThread caller,
2379            Intent intent, String resolvedType, IBinder resultTo,
2380            String resultWho, int requestCode, int startFlags,
2381            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2382        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2383                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2384    }
2385
2386    public final int startActivityAsUser(IApplicationThread caller,
2387            Intent intent, String resolvedType, IBinder resultTo,
2388            String resultWho, int requestCode, int startFlags,
2389            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2390        enforceNotIsolatedCaller("startActivity");
2391        if (userId != UserHandle.getCallingUserId()) {
2392            userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2393                    false, true, "startActivity", null);
2394        } else {
2395            if (intent.getCategories() != null
2396                    && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2397                // Requesting home, set the identity to the current user
2398                // HACK!
2399                userId = mCurrentUserId;
2400            }
2401        }
2402        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2403                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2404                null, null, options, userId);
2405    }
2406
2407    public final WaitResult startActivityAndWait(IApplicationThread caller,
2408            Intent intent, String resolvedType, IBinder resultTo,
2409            String resultWho, int requestCode, int startFlags, String profileFile,
2410            ParcelFileDescriptor profileFd, Bundle options) {
2411        enforceNotIsolatedCaller("startActivityAndWait");
2412        WaitResult res = new WaitResult();
2413        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2414                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2415                res, null, options, UserHandle.getCallingUserId());
2416        return res;
2417    }
2418
2419    public final int startActivityWithConfig(IApplicationThread caller,
2420            Intent intent, String resolvedType, IBinder resultTo,
2421            String resultWho, int requestCode, int startFlags, Configuration config,
2422            Bundle options, int userId) {
2423        enforceNotIsolatedCaller("startActivityWithConfig");
2424        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2425                false, true, "startActivityWithConfig", null);
2426        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2427                resultTo, resultWho, requestCode, startFlags,
2428                null, null, null, config, options, userId);
2429        return ret;
2430    }
2431
2432    public int startActivityIntentSender(IApplicationThread caller,
2433            IntentSender intent, Intent fillInIntent, String resolvedType,
2434            IBinder resultTo, String resultWho, int requestCode,
2435            int flagsMask, int flagsValues, Bundle options) {
2436        enforceNotIsolatedCaller("startActivityIntentSender");
2437        // Refuse possible leaked file descriptors
2438        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2439            throw new IllegalArgumentException("File descriptors passed in Intent");
2440        }
2441
2442        IIntentSender sender = intent.getTarget();
2443        if (!(sender instanceof PendingIntentRecord)) {
2444            throw new IllegalArgumentException("Bad PendingIntent object");
2445        }
2446
2447        PendingIntentRecord pir = (PendingIntentRecord)sender;
2448
2449        synchronized (this) {
2450            // If this is coming from the currently resumed activity, it is
2451            // effectively saying that app switches are allowed at this point.
2452            if (mMainStack.mResumedActivity != null
2453                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2454                            Binder.getCallingUid()) {
2455                mAppSwitchesAllowedTime = 0;
2456            }
2457        }
2458        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2459                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2460        return ret;
2461    }
2462
2463    public boolean startNextMatchingActivity(IBinder callingActivity,
2464            Intent intent, Bundle options) {
2465        // Refuse possible leaked file descriptors
2466        if (intent != null && intent.hasFileDescriptors() == true) {
2467            throw new IllegalArgumentException("File descriptors passed in Intent");
2468        }
2469
2470        synchronized (this) {
2471            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2472            if (r == null) {
2473                ActivityOptions.abort(options);
2474                return false;
2475            }
2476            if (r.app == null || r.app.thread == null) {
2477                // The caller is not running...  d'oh!
2478                ActivityOptions.abort(options);
2479                return false;
2480            }
2481            intent = new Intent(intent);
2482            // The caller is not allowed to change the data.
2483            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2484            // And we are resetting to find the next component...
2485            intent.setComponent(null);
2486
2487            ActivityInfo aInfo = null;
2488            try {
2489                List<ResolveInfo> resolves =
2490                    AppGlobals.getPackageManager().queryIntentActivities(
2491                            intent, r.resolvedType,
2492                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2493                            UserHandle.getCallingUserId());
2494
2495                // Look for the original activity in the list...
2496                final int N = resolves != null ? resolves.size() : 0;
2497                for (int i=0; i<N; i++) {
2498                    ResolveInfo rInfo = resolves.get(i);
2499                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2500                            && rInfo.activityInfo.name.equals(r.info.name)) {
2501                        // We found the current one...  the next matching is
2502                        // after it.
2503                        i++;
2504                        if (i<N) {
2505                            aInfo = resolves.get(i).activityInfo;
2506                        }
2507                        break;
2508                    }
2509                }
2510            } catch (RemoteException e) {
2511            }
2512
2513            if (aInfo == null) {
2514                // Nobody who is next!
2515                ActivityOptions.abort(options);
2516                return false;
2517            }
2518
2519            intent.setComponent(new ComponentName(
2520                    aInfo.applicationInfo.packageName, aInfo.name));
2521            intent.setFlags(intent.getFlags()&~(
2522                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2523                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2524                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2525                    Intent.FLAG_ACTIVITY_NEW_TASK));
2526
2527            // Okay now we need to start the new activity, replacing the
2528            // currently running activity.  This is a little tricky because
2529            // we want to start the new one as if the current one is finished,
2530            // but not finish the current one first so that there is no flicker.
2531            // And thus...
2532            final boolean wasFinishing = r.finishing;
2533            r.finishing = true;
2534
2535            // Propagate reply information over to the new activity.
2536            final ActivityRecord resultTo = r.resultTo;
2537            final String resultWho = r.resultWho;
2538            final int requestCode = r.requestCode;
2539            r.resultTo = null;
2540            if (resultTo != null) {
2541                resultTo.removeResultsLocked(r, resultWho, requestCode);
2542            }
2543
2544            final long origId = Binder.clearCallingIdentity();
2545            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2546                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2547                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2548                    options, false, null);
2549            Binder.restoreCallingIdentity(origId);
2550
2551            r.finishing = wasFinishing;
2552            if (res != ActivityManager.START_SUCCESS) {
2553                return false;
2554            }
2555            return true;
2556        }
2557    }
2558
2559    final int startActivityInPackage(int uid,
2560            Intent intent, String resolvedType, IBinder resultTo,
2561            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2562
2563        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2564                false, true, "startActivityInPackage", null);
2565
2566        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2567                resultTo, resultWho, requestCode, startFlags,
2568                null, null, null, null, options, userId);
2569        return ret;
2570    }
2571
2572    public final int startActivities(IApplicationThread caller,
2573            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2574        enforceNotIsolatedCaller("startActivities");
2575        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2576                options, UserHandle.getCallingUserId());
2577        return ret;
2578    }
2579
2580    final int startActivitiesInPackage(int uid,
2581            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2582            Bundle options, int userId) {
2583
2584        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2585                false, true, "startActivityInPackage", null);
2586        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2587                options, userId);
2588        return ret;
2589    }
2590
2591    final void addRecentTaskLocked(TaskRecord task) {
2592        int N = mRecentTasks.size();
2593        // Quick case: check if the top-most recent task is the same.
2594        if (N > 0 && mRecentTasks.get(0) == task) {
2595            return;
2596        }
2597        // Remove any existing entries that are the same kind of task.
2598        for (int i=0; i<N; i++) {
2599            TaskRecord tr = mRecentTasks.get(i);
2600            if (task.userId == tr.userId
2601                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2602                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2603                mRecentTasks.remove(i);
2604                i--;
2605                N--;
2606                if (task.intent == null) {
2607                    // If the new recent task we are adding is not fully
2608                    // specified, then replace it with the existing recent task.
2609                    task = tr;
2610                }
2611            }
2612        }
2613        if (N >= MAX_RECENT_TASKS) {
2614            mRecentTasks.remove(N-1);
2615        }
2616        mRecentTasks.add(0, task);
2617    }
2618
2619    public void setRequestedOrientation(IBinder token,
2620            int requestedOrientation) {
2621        synchronized (this) {
2622            ActivityRecord r = mMainStack.isInStackLocked(token);
2623            if (r == null) {
2624                return;
2625            }
2626            final long origId = Binder.clearCallingIdentity();
2627            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2628            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2629                    mConfiguration,
2630                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2631            if (config != null) {
2632                r.frozenBeforeDestroy = true;
2633                if (!updateConfigurationLocked(config, r, false, false)) {
2634                    mMainStack.resumeTopActivityLocked(null);
2635                }
2636            }
2637            Binder.restoreCallingIdentity(origId);
2638        }
2639    }
2640
2641    public int getRequestedOrientation(IBinder token) {
2642        synchronized (this) {
2643            ActivityRecord r = mMainStack.isInStackLocked(token);
2644            if (r == null) {
2645                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2646            }
2647            return mWindowManager.getAppOrientation(r.appToken);
2648        }
2649    }
2650
2651    /**
2652     * This is the internal entry point for handling Activity.finish().
2653     *
2654     * @param token The Binder token referencing the Activity we want to finish.
2655     * @param resultCode Result code, if any, from this Activity.
2656     * @param resultData Result data (Intent), if any, from this Activity.
2657     *
2658     * @return Returns true if the activity successfully finished, or false if it is still running.
2659     */
2660    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2661        // Refuse possible leaked file descriptors
2662        if (resultData != null && resultData.hasFileDescriptors() == true) {
2663            throw new IllegalArgumentException("File descriptors passed in Intent");
2664        }
2665
2666        synchronized(this) {
2667            if (mController != null) {
2668                // Find the first activity that is not finishing.
2669                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2670                if (next != null) {
2671                    // ask watcher if this is allowed
2672                    boolean resumeOK = true;
2673                    try {
2674                        resumeOK = mController.activityResuming(next.packageName);
2675                    } catch (RemoteException e) {
2676                        mController = null;
2677                    }
2678
2679                    if (!resumeOK) {
2680                        return false;
2681                    }
2682                }
2683            }
2684            final long origId = Binder.clearCallingIdentity();
2685            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2686                    resultData, "app-request");
2687            Binder.restoreCallingIdentity(origId);
2688            return res;
2689        }
2690    }
2691
2692    public final void finishHeavyWeightApp() {
2693        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2694                != PackageManager.PERMISSION_GRANTED) {
2695            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2696                    + Binder.getCallingPid()
2697                    + ", uid=" + Binder.getCallingUid()
2698                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2699            Slog.w(TAG, msg);
2700            throw new SecurityException(msg);
2701        }
2702
2703        synchronized(this) {
2704            if (mHeavyWeightProcess == null) {
2705                return;
2706            }
2707
2708            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2709                    mHeavyWeightProcess.activities);
2710            for (int i=0; i<activities.size(); i++) {
2711                ActivityRecord r = activities.get(i);
2712                if (!r.finishing) {
2713                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2714                    if (index >= 0) {
2715                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2716                                null, "finish-heavy");
2717                    }
2718                }
2719            }
2720
2721            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2722                    mHeavyWeightProcess.userId, 0));
2723            mHeavyWeightProcess = null;
2724        }
2725    }
2726
2727    public void crashApplication(int uid, int initialPid, String packageName,
2728            String message) {
2729        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2730                != PackageManager.PERMISSION_GRANTED) {
2731            String msg = "Permission Denial: crashApplication() from pid="
2732                    + Binder.getCallingPid()
2733                    + ", uid=" + Binder.getCallingUid()
2734                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2735            Slog.w(TAG, msg);
2736            throw new SecurityException(msg);
2737        }
2738
2739        synchronized(this) {
2740            ProcessRecord proc = null;
2741
2742            // Figure out which process to kill.  We don't trust that initialPid
2743            // still has any relation to current pids, so must scan through the
2744            // list.
2745            synchronized (mPidsSelfLocked) {
2746                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2747                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2748                    if (p.uid != uid) {
2749                        continue;
2750                    }
2751                    if (p.pid == initialPid) {
2752                        proc = p;
2753                        break;
2754                    }
2755                    for (String str : p.pkgList) {
2756                        if (str.equals(packageName)) {
2757                            proc = p;
2758                        }
2759                    }
2760                }
2761            }
2762
2763            if (proc == null) {
2764                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2765                        + " initialPid=" + initialPid
2766                        + " packageName=" + packageName);
2767                return;
2768            }
2769
2770            if (proc.thread != null) {
2771                if (proc.pid == Process.myPid()) {
2772                    Log.w(TAG, "crashApplication: trying to crash self!");
2773                    return;
2774                }
2775                long ident = Binder.clearCallingIdentity();
2776                try {
2777                    proc.thread.scheduleCrash(message);
2778                } catch (RemoteException e) {
2779                }
2780                Binder.restoreCallingIdentity(ident);
2781            }
2782        }
2783    }
2784
2785    public final void finishSubActivity(IBinder token, String resultWho,
2786            int requestCode) {
2787        synchronized(this) {
2788            final long origId = Binder.clearCallingIdentity();
2789            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2790            Binder.restoreCallingIdentity(origId);
2791        }
2792    }
2793
2794    public boolean finishActivityAffinity(IBinder token) {
2795        synchronized(this) {
2796            final long origId = Binder.clearCallingIdentity();
2797            boolean res = mMainStack.finishActivityAffinityLocked(token);
2798            Binder.restoreCallingIdentity(origId);
2799            return res;
2800        }
2801    }
2802
2803    public boolean willActivityBeVisible(IBinder token) {
2804        synchronized(this) {
2805            int i;
2806            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2807                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2808                if (r.appToken == token) {
2809                    return true;
2810                }
2811                if (r.fullscreen && !r.finishing) {
2812                    return false;
2813                }
2814            }
2815            return true;
2816        }
2817    }
2818
2819    public void overridePendingTransition(IBinder token, String packageName,
2820            int enterAnim, int exitAnim) {
2821        synchronized(this) {
2822            ActivityRecord self = mMainStack.isInStackLocked(token);
2823            if (self == null) {
2824                return;
2825            }
2826
2827            final long origId = Binder.clearCallingIdentity();
2828
2829            if (self.state == ActivityState.RESUMED
2830                    || self.state == ActivityState.PAUSING) {
2831                mWindowManager.overridePendingAppTransition(packageName,
2832                        enterAnim, exitAnim, null);
2833            }
2834
2835            Binder.restoreCallingIdentity(origId);
2836        }
2837    }
2838
2839    /**
2840     * Main function for removing an existing process from the activity manager
2841     * as a result of that process going away.  Clears out all connections
2842     * to the process.
2843     */
2844    private final void handleAppDiedLocked(ProcessRecord app,
2845            boolean restarting, boolean allowRestart) {
2846        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2847        if (!restarting) {
2848            mLruProcesses.remove(app);
2849        }
2850
2851        if (mProfileProc == app) {
2852            clearProfilerLocked();
2853        }
2854
2855        // Just in case...
2856        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2857            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2858            mMainStack.mPausingActivity = null;
2859        }
2860        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2861            mMainStack.mLastPausedActivity = null;
2862        }
2863
2864        // Remove this application's activities from active lists.
2865        mMainStack.removeHistoryRecordsForAppLocked(app);
2866
2867        boolean atTop = true;
2868        boolean hasVisibleActivities = false;
2869
2870        // Clean out the history list.
2871        int i = mMainStack.mHistory.size();
2872        if (localLOGV) Slog.v(
2873            TAG, "Removing app " + app + " from history with " + i + " entries");
2874        while (i > 0) {
2875            i--;
2876            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2877            if (localLOGV) Slog.v(
2878                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2879            if (r.app == app) {
2880                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2881                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2882                        RuntimeException here = new RuntimeException("here");
2883                        here.fillInStackTrace();
2884                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2885                                + ": haveState=" + r.haveState
2886                                + " stateNotNeeded=" + r.stateNotNeeded
2887                                + " finishing=" + r.finishing
2888                                + " state=" + r.state, here);
2889                    }
2890                    if (!r.finishing) {
2891                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2892                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2893                                System.identityHashCode(r),
2894                                r.task.taskId, r.shortComponentName,
2895                                "proc died without state saved");
2896                    }
2897                    mMainStack.removeActivityFromHistoryLocked(r);
2898
2899                } else {
2900                    // We have the current state for this activity, so
2901                    // it can be restarted later when needed.
2902                    if (localLOGV) Slog.v(
2903                        TAG, "Keeping entry, setting app to null");
2904                    if (r.visible) {
2905                        hasVisibleActivities = true;
2906                    }
2907                    r.app = null;
2908                    r.nowVisible = false;
2909                    if (!r.haveState) {
2910                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2911                                "App died, clearing saved state of " + r);
2912                        r.icicle = null;
2913                    }
2914                }
2915
2916                r.stack.cleanUpActivityLocked(r, true, true);
2917            }
2918            atTop = false;
2919        }
2920
2921        app.activities.clear();
2922
2923        if (app.instrumentationClass != null) {
2924            Slog.w(TAG, "Crash of app " + app.processName
2925                  + " running instrumentation " + app.instrumentationClass);
2926            Bundle info = new Bundle();
2927            info.putString("shortMsg", "Process crashed.");
2928            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2929        }
2930
2931        if (!restarting) {
2932            if (!mMainStack.resumeTopActivityLocked(null)) {
2933                // If there was nothing to resume, and we are not already
2934                // restarting this process, but there is a visible activity that
2935                // is hosted by the process...  then make sure all visible
2936                // activities are running, taking care of restarting this
2937                // process.
2938                if (hasVisibleActivities) {
2939                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2940                }
2941            }
2942        }
2943    }
2944
2945    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2946        IBinder threadBinder = thread.asBinder();
2947        // Find the application record.
2948        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2949            ProcessRecord rec = mLruProcesses.get(i);
2950            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2951                return i;
2952            }
2953        }
2954        return -1;
2955    }
2956
2957    final ProcessRecord getRecordForAppLocked(
2958            IApplicationThread thread) {
2959        if (thread == null) {
2960            return null;
2961        }
2962
2963        int appIndex = getLRURecordIndexForAppLocked(thread);
2964        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2965    }
2966
2967    final void appDiedLocked(ProcessRecord app, int pid,
2968            IApplicationThread thread) {
2969
2970        mProcDeaths[0]++;
2971
2972        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2973        synchronized (stats) {
2974            stats.noteProcessDiedLocked(app.info.uid, pid);
2975        }
2976
2977        // Clean up already done if the process has been re-started.
2978        if (app.pid == pid && app.thread != null &&
2979                app.thread.asBinder() == thread.asBinder()) {
2980            if (!app.killedBackground) {
2981                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2982                        + ") has died.");
2983            }
2984            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2985            if (localLOGV) Slog.v(
2986                TAG, "Dying app: " + app + ", pid: " + pid
2987                + ", thread: " + thread.asBinder());
2988            boolean doLowMem = app.instrumentationClass == null;
2989            handleAppDiedLocked(app, false, true);
2990
2991            if (doLowMem) {
2992                // If there are no longer any background processes running,
2993                // and the app that died was not running instrumentation,
2994                // then tell everyone we are now low on memory.
2995                boolean haveBg = false;
2996                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2997                    ProcessRecord rec = mLruProcesses.get(i);
2998                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2999                        haveBg = true;
3000                        break;
3001                    }
3002                }
3003
3004                if (!haveBg) {
3005                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3006                    long now = SystemClock.uptimeMillis();
3007                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
3008                        ProcessRecord rec = mLruProcesses.get(i);
3009                        if (rec != app && rec.thread != null &&
3010                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3011                            // The low memory report is overriding any current
3012                            // state for a GC request.  Make sure to do
3013                            // heavy/important/visible/foreground processes first.
3014                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3015                                rec.lastRequestedGc = 0;
3016                            } else {
3017                                rec.lastRequestedGc = rec.lastLowMemory;
3018                            }
3019                            rec.reportLowMemory = true;
3020                            rec.lastLowMemory = now;
3021                            mProcessesToGc.remove(rec);
3022                            addProcessToGcListLocked(rec);
3023                        }
3024                    }
3025                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3026                    scheduleAppGcsLocked();
3027                }
3028            }
3029        } else if (app.pid != pid) {
3030            // A new process has already been started.
3031            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3032                    + ") has died and restarted (pid " + app.pid + ").");
3033            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3034        } else if (DEBUG_PROCESSES) {
3035            Slog.d(TAG, "Received spurious death notification for thread "
3036                    + thread.asBinder());
3037        }
3038    }
3039
3040    /**
3041     * If a stack trace dump file is configured, dump process stack traces.
3042     * @param clearTraces causes the dump file to be erased prior to the new
3043     *    traces being written, if true; when false, the new traces will be
3044     *    appended to any existing file content.
3045     * @param firstPids of dalvik VM processes to dump stack traces for first
3046     * @param lastPids of dalvik VM processes to dump stack traces for last
3047     * @param nativeProcs optional list of native process names to dump stack crawls
3048     * @return file containing stack traces, or null if no dump file is configured
3049     */
3050    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3051            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3052        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3053        if (tracesPath == null || tracesPath.length() == 0) {
3054            return null;
3055        }
3056
3057        File tracesFile = new File(tracesPath);
3058        try {
3059            File tracesDir = tracesFile.getParentFile();
3060            if (!tracesDir.exists()) {
3061                tracesFile.mkdirs();
3062                if (!SELinux.restorecon(tracesDir)) {
3063                    return null;
3064                }
3065            }
3066            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3067
3068            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3069            tracesFile.createNewFile();
3070            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3071        } catch (IOException e) {
3072            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3073            return null;
3074        }
3075
3076        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3077        return tracesFile;
3078    }
3079
3080    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3081            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3082        // Use a FileObserver to detect when traces finish writing.
3083        // The order of traces is considered important to maintain for legibility.
3084        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3085            public synchronized void onEvent(int event, String path) { notify(); }
3086        };
3087
3088        try {
3089            observer.startWatching();
3090
3091            // First collect all of the stacks of the most important pids.
3092            if (firstPids != null) {
3093                try {
3094                    int num = firstPids.size();
3095                    for (int i = 0; i < num; i++) {
3096                        synchronized (observer) {
3097                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3098                            observer.wait(200);  // Wait for write-close, give up after 200msec
3099                        }
3100                    }
3101                } catch (InterruptedException e) {
3102                    Log.wtf(TAG, e);
3103                }
3104            }
3105
3106            // Next measure CPU usage.
3107            if (processStats != null) {
3108                processStats.init();
3109                System.gc();
3110                processStats.update();
3111                try {
3112                    synchronized (processStats) {
3113                        processStats.wait(500); // measure over 1/2 second.
3114                    }
3115                } catch (InterruptedException e) {
3116                }
3117                processStats.update();
3118
3119                // We'll take the stack crawls of just the top apps using CPU.
3120                final int N = processStats.countWorkingStats();
3121                int numProcs = 0;
3122                for (int i=0; i<N && numProcs<5; i++) {
3123                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3124                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3125                        numProcs++;
3126                        try {
3127                            synchronized (observer) {
3128                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3129                                observer.wait(200);  // Wait for write-close, give up after 200msec
3130                            }
3131                        } catch (InterruptedException e) {
3132                            Log.wtf(TAG, e);
3133                        }
3134
3135                    }
3136                }
3137            }
3138
3139        } finally {
3140            observer.stopWatching();
3141        }
3142
3143        if (nativeProcs != null) {
3144            int[] pids = Process.getPidsForCommands(nativeProcs);
3145            if (pids != null) {
3146                for (int pid : pids) {
3147                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3148                }
3149            }
3150        }
3151    }
3152
3153    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3154        if (true || IS_USER_BUILD) {
3155            return;
3156        }
3157        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3158        if (tracesPath == null || tracesPath.length() == 0) {
3159            return;
3160        }
3161
3162        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3163        StrictMode.allowThreadDiskWrites();
3164        try {
3165            final File tracesFile = new File(tracesPath);
3166            final File tracesDir = tracesFile.getParentFile();
3167            final File tracesTmp = new File(tracesDir, "__tmp__");
3168            try {
3169                if (!tracesDir.exists()) {
3170                    tracesFile.mkdirs();
3171                    if (!SELinux.restorecon(tracesDir.getPath())) {
3172                        return;
3173                    }
3174                }
3175                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3176
3177                if (tracesFile.exists()) {
3178                    tracesTmp.delete();
3179                    tracesFile.renameTo(tracesTmp);
3180                }
3181                StringBuilder sb = new StringBuilder();
3182                Time tobj = new Time();
3183                tobj.set(System.currentTimeMillis());
3184                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3185                sb.append(": ");
3186                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3187                sb.append(" since ");
3188                sb.append(msg);
3189                FileOutputStream fos = new FileOutputStream(tracesFile);
3190                fos.write(sb.toString().getBytes());
3191                if (app == null) {
3192                    fos.write("\n*** No application process!".getBytes());
3193                }
3194                fos.close();
3195                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3196            } catch (IOException e) {
3197                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3198                return;
3199            }
3200
3201            if (app != null) {
3202                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3203                firstPids.add(app.pid);
3204                dumpStackTraces(tracesPath, firstPids, null, null, null);
3205            }
3206
3207            File lastTracesFile = null;
3208            File curTracesFile = null;
3209            for (int i=9; i>=0; i--) {
3210                String name = String.format("slow%02d.txt", i);
3211                curTracesFile = new File(tracesDir, name);
3212                if (curTracesFile.exists()) {
3213                    if (lastTracesFile != null) {
3214                        curTracesFile.renameTo(lastTracesFile);
3215                    } else {
3216                        curTracesFile.delete();
3217                    }
3218                }
3219                lastTracesFile = curTracesFile;
3220            }
3221            tracesFile.renameTo(curTracesFile);
3222            if (tracesTmp.exists()) {
3223                tracesTmp.renameTo(tracesFile);
3224            }
3225        } finally {
3226            StrictMode.setThreadPolicy(oldPolicy);
3227        }
3228    }
3229
3230    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3231            ActivityRecord parent, final String annotation) {
3232        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3233        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3234
3235        if (mController != null) {
3236            try {
3237                // 0 == continue, -1 = kill process immediately
3238                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3239                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3240            } catch (RemoteException e) {
3241                mController = null;
3242            }
3243        }
3244
3245        long anrTime = SystemClock.uptimeMillis();
3246        if (MONITOR_CPU_USAGE) {
3247            updateCpuStatsNow();
3248        }
3249
3250        synchronized (this) {
3251            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3252            if (mShuttingDown) {
3253                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3254                return;
3255            } else if (app.notResponding) {
3256                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3257                return;
3258            } else if (app.crashing) {
3259                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3260                return;
3261            }
3262
3263            // In case we come through here for the same app before completing
3264            // this one, mark as anring now so we will bail out.
3265            app.notResponding = true;
3266
3267            // Log the ANR to the event log.
3268            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3269                    annotation);
3270
3271            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3272            firstPids.add(app.pid);
3273
3274            int parentPid = app.pid;
3275            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3276            if (parentPid != app.pid) firstPids.add(parentPid);
3277
3278            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3279
3280            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3281                ProcessRecord r = mLruProcesses.get(i);
3282                if (r != null && r.thread != null) {
3283                    int pid = r.pid;
3284                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3285                        if (r.persistent) {
3286                            firstPids.add(pid);
3287                        } else {
3288                            lastPids.put(pid, Boolean.TRUE);
3289                        }
3290                    }
3291                }
3292            }
3293        }
3294
3295        // Log the ANR to the main log.
3296        StringBuilder info = new StringBuilder();
3297        info.setLength(0);
3298        info.append("ANR in ").append(app.processName);
3299        if (activity != null && activity.shortComponentName != null) {
3300            info.append(" (").append(activity.shortComponentName).append(")");
3301        }
3302        info.append("\n");
3303        if (annotation != null) {
3304            info.append("Reason: ").append(annotation).append("\n");
3305        }
3306        if (parent != null && parent != activity) {
3307            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3308        }
3309
3310        final ProcessStats processStats = new ProcessStats(true);
3311
3312        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3313
3314        String cpuInfo = null;
3315        if (MONITOR_CPU_USAGE) {
3316            updateCpuStatsNow();
3317            synchronized (mProcessStatsThread) {
3318                cpuInfo = mProcessStats.printCurrentState(anrTime);
3319            }
3320            info.append(processStats.printCurrentLoad());
3321            info.append(cpuInfo);
3322        }
3323
3324        info.append(processStats.printCurrentState(anrTime));
3325
3326        Slog.e(TAG, info.toString());
3327        if (tracesFile == null) {
3328            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3329            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3330        }
3331
3332        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3333                cpuInfo, tracesFile, null);
3334
3335        if (mController != null) {
3336            try {
3337                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3338                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3339                if (res != 0) {
3340                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3341                    return;
3342                }
3343            } catch (RemoteException e) {
3344                mController = null;
3345            }
3346        }
3347
3348        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3349        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3350                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3351
3352        synchronized (this) {
3353            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3354                Slog.w(TAG, "Killing " + app + ": background ANR");
3355                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3356                        app.processName, app.setAdj, "background ANR");
3357                Process.killProcessQuiet(app.pid);
3358                return;
3359            }
3360
3361            // Set the app's notResponding state, and look up the errorReportReceiver
3362            makeAppNotRespondingLocked(app,
3363                    activity != null ? activity.shortComponentName : null,
3364                    annotation != null ? "ANR " + annotation : "ANR",
3365                    info.toString());
3366
3367            // Bring up the infamous App Not Responding dialog
3368            Message msg = Message.obtain();
3369            HashMap map = new HashMap();
3370            msg.what = SHOW_NOT_RESPONDING_MSG;
3371            msg.obj = map;
3372            map.put("app", app);
3373            if (activity != null) {
3374                map.put("activity", activity);
3375            }
3376
3377            mHandler.sendMessage(msg);
3378        }
3379    }
3380
3381    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3382        if (!mLaunchWarningShown) {
3383            mLaunchWarningShown = true;
3384            mHandler.post(new Runnable() {
3385                @Override
3386                public void run() {
3387                    synchronized (ActivityManagerService.this) {
3388                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3389                        d.show();
3390                        mHandler.postDelayed(new Runnable() {
3391                            @Override
3392                            public void run() {
3393                                synchronized (ActivityManagerService.this) {
3394                                    d.dismiss();
3395                                    mLaunchWarningShown = false;
3396                                }
3397                            }
3398                        }, 4000);
3399                    }
3400                }
3401            });
3402        }
3403    }
3404
3405    public boolean clearApplicationUserData(final String packageName,
3406            final IPackageDataObserver observer, final int userId) {
3407        enforceNotIsolatedCaller("clearApplicationUserData");
3408        int uid = Binder.getCallingUid();
3409        int pid = Binder.getCallingPid();
3410        long callingId = Binder.clearCallingIdentity();
3411        try {
3412            IPackageManager pm = AppGlobals.getPackageManager();
3413            int pkgUid = -1;
3414            synchronized(this) {
3415                try {
3416                    pkgUid = pm.getPackageUid(packageName, userId);
3417                } catch (RemoteException e) {
3418                }
3419                if (pkgUid == -1) {
3420                    Slog.w(TAG, "Invalid packageName:" + packageName);
3421                    return false;
3422                }
3423                if (uid == pkgUid || checkComponentPermission(
3424                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3425                        pid, uid, -1, true)
3426                        == PackageManager.PERMISSION_GRANTED) {
3427                    forceStopPackageLocked(packageName, pkgUid);
3428                } else {
3429                    throw new SecurityException(pid+" does not have permission:"+
3430                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3431                                    "for process:"+packageName);
3432                }
3433            }
3434
3435            try {
3436                //clear application user data
3437                pm.clearApplicationUserData(packageName, observer, userId);
3438                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3439                        Uri.fromParts("package", packageName, null));
3440                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3441                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3442                        null, null, 0, null, null, null, false, false, userId);
3443            } catch (RemoteException e) {
3444            }
3445        } finally {
3446            Binder.restoreCallingIdentity(callingId);
3447        }
3448        return true;
3449    }
3450
3451    public void killBackgroundProcesses(final String packageName) {
3452        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3453                != PackageManager.PERMISSION_GRANTED &&
3454                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3455                        != PackageManager.PERMISSION_GRANTED) {
3456            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3457                    + Binder.getCallingPid()
3458                    + ", uid=" + Binder.getCallingUid()
3459                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3460            Slog.w(TAG, msg);
3461            throw new SecurityException(msg);
3462        }
3463
3464        int userId = UserHandle.getCallingUserId();
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;
3477                }
3478                killPackageProcessesLocked(packageName, pkgUid, -1,
3479                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3480            }
3481        } finally {
3482            Binder.restoreCallingIdentity(callingId);
3483        }
3484    }
3485
3486    public void killAllBackgroundProcesses() {
3487        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3488                != PackageManager.PERMISSION_GRANTED) {
3489            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3490                    + Binder.getCallingPid()
3491                    + ", uid=" + Binder.getCallingUid()
3492                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3493            Slog.w(TAG, msg);
3494            throw new SecurityException(msg);
3495        }
3496
3497        long callingId = Binder.clearCallingIdentity();
3498        try {
3499            synchronized(this) {
3500                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3501                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3502                    final int NA = apps.size();
3503                    for (int ia=0; ia<NA; ia++) {
3504                        ProcessRecord app = apps.valueAt(ia);
3505                        if (app.persistent) {
3506                            // we don't kill persistent processes
3507                            continue;
3508                        }
3509                        if (app.removed) {
3510                            procs.add(app);
3511                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3512                            app.removed = true;
3513                            procs.add(app);
3514                        }
3515                    }
3516                }
3517
3518                int N = procs.size();
3519                for (int i=0; i<N; i++) {
3520                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3521                }
3522            }
3523        } finally {
3524            Binder.restoreCallingIdentity(callingId);
3525        }
3526    }
3527
3528    public void forceStopPackage(final String packageName) {
3529        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3530                != PackageManager.PERMISSION_GRANTED) {
3531            String msg = "Permission Denial: forceStopPackage() from pid="
3532                    + Binder.getCallingPid()
3533                    + ", uid=" + Binder.getCallingUid()
3534                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3535            Slog.w(TAG, msg);
3536            throw new SecurityException(msg);
3537        }
3538        final int userId = UserHandle.getCallingUserId();
3539        long callingId = Binder.clearCallingIdentity();
3540        try {
3541            IPackageManager pm = AppGlobals.getPackageManager();
3542            int pkgUid = -1;
3543            synchronized(this) {
3544                try {
3545                    pkgUid = pm.getPackageUid(packageName, userId);
3546                } catch (RemoteException e) {
3547                }
3548                if (pkgUid == -1) {
3549                    Slog.w(TAG, "Invalid packageName: " + packageName);
3550                    return;
3551                }
3552                forceStopPackageLocked(packageName, pkgUid);
3553                try {
3554                    pm.setPackageStoppedState(packageName, true, userId);
3555                } catch (RemoteException e) {
3556                } catch (IllegalArgumentException e) {
3557                    Slog.w(TAG, "Failed trying to unstop package "
3558                            + packageName + ": " + e);
3559                }
3560            }
3561        } finally {
3562            Binder.restoreCallingIdentity(callingId);
3563        }
3564    }
3565
3566    /*
3567     * The pkg name and uid have to be specified.
3568     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3569     */
3570    public void killApplicationWithUid(String pkg, int uid) {
3571        if (pkg == null) {
3572            return;
3573        }
3574        // Make sure the uid is valid.
3575        if (uid < 0) {
3576            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3577            return;
3578        }
3579        int callerUid = Binder.getCallingUid();
3580        // Only the system server can kill an application
3581        if (callerUid == Process.SYSTEM_UID) {
3582            // Post an aysnc message to kill the application
3583            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3584            msg.arg1 = uid;
3585            msg.arg2 = 0;
3586            msg.obj = pkg;
3587            mHandler.sendMessage(msg);
3588        } else {
3589            throw new SecurityException(callerUid + " cannot kill pkg: " +
3590                    pkg);
3591        }
3592    }
3593
3594    public void closeSystemDialogs(String reason) {
3595        enforceNotIsolatedCaller("closeSystemDialogs");
3596
3597        final int pid = Binder.getCallingPid();
3598        final int uid = Binder.getCallingUid();
3599        final long origId = Binder.clearCallingIdentity();
3600        try {
3601            synchronized (this) {
3602                // Only allow this from foreground processes, so that background
3603                // applications can't abuse it to prevent system UI from being shown.
3604                if (uid >= Process.FIRST_APPLICATION_UID) {
3605                    ProcessRecord proc;
3606                    synchronized (mPidsSelfLocked) {
3607                        proc = mPidsSelfLocked.get(pid);
3608                    }
3609                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3610                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3611                                + " from background process " + proc);
3612                        return;
3613                    }
3614                }
3615                closeSystemDialogsLocked(reason);
3616            }
3617        } finally {
3618            Binder.restoreCallingIdentity(origId);
3619        }
3620    }
3621
3622    void closeSystemDialogsLocked(String reason) {
3623        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3624        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3625        if (reason != null) {
3626            intent.putExtra("reason", reason);
3627        }
3628        mWindowManager.closeSystemDialogs(reason);
3629
3630        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3631            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3632            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3633                r.stack.finishActivityLocked(r, i,
3634                        Activity.RESULT_CANCELED, null, "close-sys");
3635            }
3636        }
3637
3638        broadcastIntentLocked(null, null, intent, null,
3639                null, 0, null, null, null, false, false, -1,
3640                Process.SYSTEM_UID, UserHandle.USER_ALL);
3641    }
3642
3643    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3644            throws RemoteException {
3645        enforceNotIsolatedCaller("getProcessMemoryInfo");
3646        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3647        for (int i=pids.length-1; i>=0; i--) {
3648            infos[i] = new Debug.MemoryInfo();
3649            Debug.getMemoryInfo(pids[i], infos[i]);
3650        }
3651        return infos;
3652    }
3653
3654    public long[] getProcessPss(int[] pids) throws RemoteException {
3655        enforceNotIsolatedCaller("getProcessPss");
3656        long[] pss = new long[pids.length];
3657        for (int i=pids.length-1; i>=0; i--) {
3658            pss[i] = Debug.getPss(pids[i]);
3659        }
3660        return pss;
3661    }
3662
3663    public void killApplicationProcess(String processName, int uid) {
3664        if (processName == null) {
3665            return;
3666        }
3667
3668        int callerUid = Binder.getCallingUid();
3669        // Only the system server can kill an application
3670        if (callerUid == Process.SYSTEM_UID) {
3671            synchronized (this) {
3672                ProcessRecord app = getProcessRecordLocked(processName, uid);
3673                if (app != null && app.thread != null) {
3674                    try {
3675                        app.thread.scheduleSuicide();
3676                    } catch (RemoteException e) {
3677                        // If the other end already died, then our work here is done.
3678                    }
3679                } else {
3680                    Slog.w(TAG, "Process/uid not found attempting kill of "
3681                            + processName + " / " + uid);
3682                }
3683            }
3684        } else {
3685            throw new SecurityException(callerUid + " cannot kill app process: " +
3686                    processName);
3687        }
3688    }
3689
3690    private void forceStopPackageLocked(final String packageName, int uid) {
3691        forceStopPackageLocked(packageName, uid, false, false, true, false,
3692                UserHandle.getUserId(uid));
3693        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3694                Uri.fromParts("package", packageName, null));
3695        if (!mProcessesReady) {
3696            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3697        }
3698        intent.putExtra(Intent.EXTRA_UID, uid);
3699        broadcastIntentLocked(null, null, intent,
3700                null, null, 0, null, null, null,
3701                false, false,
3702                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3703    }
3704
3705    private void forceStopUserLocked(int userId) {
3706        forceStopPackageLocked(null, -1, false, false, true, false, userId);
3707        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3708        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3709        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3710        broadcastIntentLocked(null, null, intent,
3711                null, null, 0, null, null, null,
3712                false, false,
3713                MY_PID, Process.SYSTEM_UID, userId);
3714    }
3715
3716    private final boolean killPackageProcessesLocked(String packageName, int uid,
3717            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3718            boolean doit, boolean evenPersistent, String reason) {
3719        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3720
3721        // Remove all processes this package may have touched: all with the
3722        // same UID (except for the system or root user), and all whose name
3723        // matches the package name.
3724        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3725        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3726            final int NA = apps.size();
3727            for (int ia=0; ia<NA; ia++) {
3728                ProcessRecord app = apps.valueAt(ia);
3729                if (app.persistent && !evenPersistent) {
3730                    // we don't kill persistent processes
3731                    continue;
3732                }
3733                if (app.removed) {
3734                    if (doit) {
3735                        procs.add(app);
3736                    }
3737                // If no package is specified, we call all processes under the
3738                // give user id.
3739                } else if (packageName == null) {
3740                    if (app.userId == userId) {
3741                        if (app.setAdj >= minOomAdj) {
3742                            if (!doit) {
3743                                return true;
3744                            }
3745                            app.removed = true;
3746                            procs.add(app);
3747                        }
3748                    }
3749                // If uid is specified and the uid and process name match
3750                // Or, the uid is not specified and the process name matches
3751                } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3752                            || ((app.processName.equals(packageName)
3753                                 || app.processName.startsWith(procNamePrefix))
3754                                && uid < 0))) {
3755                    if (app.setAdj >= minOomAdj) {
3756                        if (!doit) {
3757                            return true;
3758                        }
3759                        app.removed = true;
3760                        procs.add(app);
3761                    }
3762                }
3763            }
3764        }
3765
3766        int N = procs.size();
3767        for (int i=0; i<N; i++) {
3768            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3769        }
3770        return N > 0;
3771    }
3772
3773    private final boolean forceStopPackageLocked(String name, int uid,
3774            boolean callerWillRestart, boolean purgeCache, boolean doit,
3775            boolean evenPersistent, int userId) {
3776        int i;
3777        int N;
3778
3779        if (uid < 0 && name != null) {
3780            try {
3781                uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
3782            } catch (RemoteException e) {
3783            }
3784        }
3785
3786        if (doit) {
3787            if (name != null) {
3788                Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3789            } else {
3790                Slog.i(TAG, "Force stopping user " + userId);
3791            }
3792
3793            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3794            while (badApps.hasNext()) {
3795                SparseArray<Long> ba = badApps.next();
3796                for (i=ba.size()-1; i>=0; i--) {
3797                    boolean remove = false;
3798                    final int entUid = ba.keyAt(i);
3799                    if (name != null) {
3800                        if (entUid == uid) {
3801                            remove = true;
3802                        }
3803                    } else if (UserHandle.getUserId(entUid) == userId) {
3804                        remove = true;
3805                    }
3806                    if (remove) {
3807                        ba.removeAt(i);
3808                    }
3809                }
3810                if (ba.size() == 0) {
3811                    badApps.remove();
3812                }
3813            }
3814        }
3815
3816        boolean didSomething = killPackageProcessesLocked(name, uid,
3817                name == null ? userId : -1 , -100, callerWillRestart, false,
3818                doit, evenPersistent,
3819                name == null ? ("force stop user " + userId) : ("force stop " + name));
3820
3821        TaskRecord lastTask = null;
3822        for (i=0; i<mMainStack.mHistory.size(); i++) {
3823            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3824            final boolean samePackage = r.packageName.equals(name)
3825                    || (name == null && r.userId == userId);
3826            if (r.userId == userId
3827                    && (samePackage || r.task == lastTask)
3828                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3829                if (!doit) {
3830                    if (r.finishing) {
3831                        // If this activity is just finishing, then it is not
3832                        // interesting as far as something to stop.
3833                        continue;
3834                    }
3835                    return true;
3836                }
3837                didSomething = true;
3838                Slog.i(TAG, "  Force finishing activity " + r);
3839                if (samePackage) {
3840                    if (r.app != null) {
3841                        r.app.removed = true;
3842                    }
3843                    r.app = null;
3844                }
3845                lastTask = r.task;
3846                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3847                        null, "force-stop", true)) {
3848                    i--;
3849                }
3850            }
3851        }
3852
3853        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3854            if (!doit) {
3855                return true;
3856            }
3857            didSomething = true;
3858        }
3859
3860        if (name == null) {
3861            // Remove all sticky broadcasts from this user.
3862            mStickyBroadcasts.remove(userId);
3863        }
3864
3865        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3866        for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
3867            if ((name == null || provider.info.packageName.equals(name))
3868                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3869                if (!doit) {
3870                    return true;
3871                }
3872                didSomething = true;
3873                providers.add(provider);
3874            }
3875        }
3876
3877        N = providers.size();
3878        for (i=0; i<N; i++) {
3879            removeDyingProviderLocked(null, providers.get(i), true);
3880        }
3881
3882        if (doit) {
3883            if (purgeCache && name != null) {
3884                AttributeCache ac = AttributeCache.instance();
3885                if (ac != null) {
3886                    ac.removePackage(name);
3887                }
3888            }
3889            if (mBooted) {
3890                mMainStack.resumeTopActivityLocked(null);
3891                mMainStack.scheduleIdleLocked();
3892            }
3893        }
3894
3895        return didSomething;
3896    }
3897
3898    private final boolean removeProcessLocked(ProcessRecord app,
3899            boolean callerWillRestart, boolean allowRestart, String reason) {
3900        final String name = app.processName;
3901        final int uid = app.uid;
3902        if (DEBUG_PROCESSES) Slog.d(
3903            TAG, "Force removing proc " + app.toShortString() + " (" + name
3904            + "/" + uid + ")");
3905
3906        mProcessNames.remove(name, uid);
3907        mIsolatedProcesses.remove(app.uid);
3908        if (mHeavyWeightProcess == app) {
3909            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3910                    mHeavyWeightProcess.userId, 0));
3911            mHeavyWeightProcess = null;
3912        }
3913        boolean needRestart = false;
3914        if (app.pid > 0 && app.pid != MY_PID) {
3915            int pid = app.pid;
3916            synchronized (mPidsSelfLocked) {
3917                mPidsSelfLocked.remove(pid);
3918                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3919            }
3920            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3921            handleAppDiedLocked(app, true, allowRestart);
3922            mLruProcesses.remove(app);
3923            Process.killProcessQuiet(pid);
3924
3925            if (app.persistent && !app.isolated) {
3926                if (!callerWillRestart) {
3927                    addAppLocked(app.info, false);
3928                } else {
3929                    needRestart = true;
3930                }
3931            }
3932        } else {
3933            mRemovedProcesses.add(app);
3934        }
3935
3936        return needRestart;
3937    }
3938
3939    private final void processStartTimedOutLocked(ProcessRecord app) {
3940        final int pid = app.pid;
3941        boolean gone = false;
3942        synchronized (mPidsSelfLocked) {
3943            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3944            if (knownApp != null && knownApp.thread == null) {
3945                mPidsSelfLocked.remove(pid);
3946                gone = true;
3947            }
3948        }
3949
3950        if (gone) {
3951            Slog.w(TAG, "Process " + app + " failed to attach");
3952            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
3953                    app.processName);
3954            mProcessNames.remove(app.processName, app.uid);
3955            mIsolatedProcesses.remove(app.uid);
3956            if (mHeavyWeightProcess == app) {
3957                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3958                        mHeavyWeightProcess.userId, 0));
3959                mHeavyWeightProcess = null;
3960            }
3961            // Take care of any launching providers waiting for this process.
3962            checkAppInLaunchingProvidersLocked(app, true);
3963            // Take care of any services that are waiting for the process.
3964            mServices.processStartTimedOutLocked(app);
3965            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3966                    app.processName, app.setAdj, "start timeout");
3967            Process.killProcessQuiet(pid);
3968            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3969                Slog.w(TAG, "Unattached app died before backup, skipping");
3970                try {
3971                    IBackupManager bm = IBackupManager.Stub.asInterface(
3972                            ServiceManager.getService(Context.BACKUP_SERVICE));
3973                    bm.agentDisconnected(app.info.packageName);
3974                } catch (RemoteException e) {
3975                    // Can't happen; the backup manager is local
3976                }
3977            }
3978            if (isPendingBroadcastProcessLocked(pid)) {
3979                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3980                skipPendingBroadcastLocked(pid);
3981            }
3982        } else {
3983            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3984        }
3985    }
3986
3987    private final boolean attachApplicationLocked(IApplicationThread thread,
3988            int pid) {
3989
3990        // Find the application record that is being attached...  either via
3991        // the pid if we are running in multiple processes, or just pull the
3992        // next app record if we are emulating process with anonymous threads.
3993        ProcessRecord app;
3994        if (pid != MY_PID && pid >= 0) {
3995            synchronized (mPidsSelfLocked) {
3996                app = mPidsSelfLocked.get(pid);
3997            }
3998        } else {
3999            app = null;
4000        }
4001
4002        if (app == null) {
4003            Slog.w(TAG, "No pending application record for pid " + pid
4004                    + " (IApplicationThread " + thread + "); dropping process");
4005            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4006            if (pid > 0 && pid != MY_PID) {
4007                Process.killProcessQuiet(pid);
4008            } else {
4009                try {
4010                    thread.scheduleExit();
4011                } catch (Exception e) {
4012                    // Ignore exceptions.
4013                }
4014            }
4015            return false;
4016        }
4017
4018        // If this application record is still attached to a previous
4019        // process, clean it up now.
4020        if (app.thread != null) {
4021            handleAppDiedLocked(app, true, true);
4022        }
4023
4024        // Tell the process all about itself.
4025
4026        if (localLOGV) Slog.v(
4027                TAG, "Binding process pid " + pid + " to record " + app);
4028
4029        String processName = app.processName;
4030        try {
4031            AppDeathRecipient adr = new AppDeathRecipient(
4032                    app, pid, thread);
4033            thread.asBinder().linkToDeath(adr, 0);
4034            app.deathRecipient = adr;
4035        } catch (RemoteException e) {
4036            app.resetPackageList();
4037            startProcessLocked(app, "link fail", processName);
4038            return false;
4039        }
4040
4041        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
4042
4043        app.thread = thread;
4044        app.curAdj = app.setAdj = -100;
4045        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4046        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4047        app.forcingToForeground = null;
4048        app.foregroundServices = false;
4049        app.hasShownUi = false;
4050        app.debugging = false;
4051
4052        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4053
4054        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4055        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4056
4057        if (!normalMode) {
4058            Slog.i(TAG, "Launching preboot mode app: " + app);
4059        }
4060
4061        if (localLOGV) Slog.v(
4062            TAG, "New app record " + app
4063            + " thread=" + thread.asBinder() + " pid=" + pid);
4064        try {
4065            int testMode = IApplicationThread.DEBUG_OFF;
4066            if (mDebugApp != null && mDebugApp.equals(processName)) {
4067                testMode = mWaitForDebugger
4068                    ? IApplicationThread.DEBUG_WAIT
4069                    : IApplicationThread.DEBUG_ON;
4070                app.debugging = true;
4071                if (mDebugTransient) {
4072                    mDebugApp = mOrigDebugApp;
4073                    mWaitForDebugger = mOrigWaitForDebugger;
4074                }
4075            }
4076            String profileFile = app.instrumentationProfileFile;
4077            ParcelFileDescriptor profileFd = null;
4078            boolean profileAutoStop = false;
4079            if (mProfileApp != null && mProfileApp.equals(processName)) {
4080                mProfileProc = app;
4081                profileFile = mProfileFile;
4082                profileFd = mProfileFd;
4083                profileAutoStop = mAutoStopProfiler;
4084            }
4085            boolean enableOpenGlTrace = false;
4086            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4087                enableOpenGlTrace = true;
4088                mOpenGlTraceApp = null;
4089            }
4090
4091            // If the app is being launched for restore or full backup, set it up specially
4092            boolean isRestrictedBackupMode = false;
4093            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4094                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4095                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4096                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4097            }
4098
4099            ensurePackageDexOpt(app.instrumentationInfo != null
4100                    ? app.instrumentationInfo.packageName
4101                    : app.info.packageName);
4102            if (app.instrumentationClass != null) {
4103                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4104            }
4105            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4106                    + processName + " with config " + mConfiguration);
4107            ApplicationInfo appInfo = app.instrumentationInfo != null
4108                    ? app.instrumentationInfo : app.info;
4109            app.compat = compatibilityInfoForPackageLocked(appInfo);
4110            if (profileFd != null) {
4111                profileFd = profileFd.dup();
4112            }
4113            thread.bindApplication(processName, appInfo, providers,
4114                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4115                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4116                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4117                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4118                    mCoreSettingsObserver.getCoreSettingsLocked());
4119            updateLruProcessLocked(app, false, true);
4120            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4121        } catch (Exception e) {
4122            // todo: Yikes!  What should we do?  For now we will try to
4123            // start another process, but that could easily get us in
4124            // an infinite loop of restarting processes...
4125            Slog.w(TAG, "Exception thrown during bind!", e);
4126
4127            app.resetPackageList();
4128            app.unlinkDeathRecipient();
4129            startProcessLocked(app, "bind fail", processName);
4130            return false;
4131        }
4132
4133        // Remove this record from the list of starting applications.
4134        mPersistentStartingProcesses.remove(app);
4135        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4136                "Attach application locked removing on hold: " + app);
4137        mProcessesOnHold.remove(app);
4138
4139        boolean badApp = false;
4140        boolean didSomething = false;
4141
4142        // See if the top visible activity is waiting to run in this process...
4143        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4144        if (hr != null && normalMode) {
4145            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4146                    && processName.equals(hr.processName)) {
4147                try {
4148                    if (mHeadless) {
4149                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4150                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4151                        didSomething = true;
4152                    }
4153                } catch (Exception e) {
4154                    Slog.w(TAG, "Exception in new application when starting activity "
4155                          + hr.intent.getComponent().flattenToShortString(), e);
4156                    badApp = true;
4157                }
4158            } else {
4159                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4160            }
4161        }
4162
4163        // Find any services that should be running in this process...
4164        if (!badApp) {
4165            try {
4166                didSomething |= mServices.attachApplicationLocked(app, processName);
4167            } catch (Exception e) {
4168                badApp = true;
4169            }
4170        }
4171
4172        // Check if a next-broadcast receiver is in this process...
4173        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4174            try {
4175                didSomething = sendPendingBroadcastsLocked(app);
4176            } catch (Exception e) {
4177                // If the app died trying to launch the receiver we declare it 'bad'
4178                badApp = true;
4179            }
4180        }
4181
4182        // Check whether the next backup agent is in this process...
4183        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4184            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4185            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4186            try {
4187                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4188                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4189                        mBackupTarget.backupMode);
4190            } catch (Exception e) {
4191                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4192                e.printStackTrace();
4193            }
4194        }
4195
4196        if (badApp) {
4197            // todo: Also need to kill application to deal with all
4198            // kinds of exceptions.
4199            handleAppDiedLocked(app, false, true);
4200            return false;
4201        }
4202
4203        if (!didSomething) {
4204            updateOomAdjLocked();
4205        }
4206
4207        return true;
4208    }
4209
4210    public final void attachApplication(IApplicationThread thread) {
4211        synchronized (this) {
4212            int callingPid = Binder.getCallingPid();
4213            final long origId = Binder.clearCallingIdentity();
4214            attachApplicationLocked(thread, callingPid);
4215            Binder.restoreCallingIdentity(origId);
4216        }
4217    }
4218
4219    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4220        final long origId = Binder.clearCallingIdentity();
4221        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4222        if (stopProfiling) {
4223            synchronized (this) {
4224                if (mProfileProc == r.app) {
4225                    if (mProfileFd != null) {
4226                        try {
4227                            mProfileFd.close();
4228                        } catch (IOException e) {
4229                        }
4230                        clearProfilerLocked();
4231                    }
4232                }
4233            }
4234        }
4235        Binder.restoreCallingIdentity(origId);
4236    }
4237
4238    void enableScreenAfterBoot() {
4239        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4240                SystemClock.uptimeMillis());
4241        mWindowManager.enableScreenAfterBoot();
4242
4243        synchronized (this) {
4244            updateEventDispatchingLocked();
4245        }
4246    }
4247
4248    public void showBootMessage(final CharSequence msg, final boolean always) {
4249        enforceNotIsolatedCaller("showBootMessage");
4250        mWindowManager.showBootMessage(msg, always);
4251    }
4252
4253    public void dismissKeyguardOnNextActivity() {
4254        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4255        final long token = Binder.clearCallingIdentity();
4256        try {
4257            synchronized (this) {
4258                if (mLockScreenShown) {
4259                    mLockScreenShown = false;
4260                    comeOutOfSleepIfNeededLocked();
4261                }
4262                mMainStack.dismissKeyguardOnNextActivityLocked();
4263            }
4264        } finally {
4265            Binder.restoreCallingIdentity(token);
4266        }
4267    }
4268
4269    final void finishBooting() {
4270        IntentFilter pkgFilter = new IntentFilter();
4271        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4272        pkgFilter.addDataScheme("package");
4273        mContext.registerReceiver(new BroadcastReceiver() {
4274            @Override
4275            public void onReceive(Context context, Intent intent) {
4276                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4277                if (pkgs != null) {
4278                    for (String pkg : pkgs) {
4279                        synchronized (ActivityManagerService.this) {
4280                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4281                                setResultCode(Activity.RESULT_OK);
4282                                return;
4283                            }
4284                        }
4285                    }
4286                }
4287            }
4288        }, pkgFilter);
4289
4290        synchronized (this) {
4291            // Ensure that any processes we had put on hold are now started
4292            // up.
4293            final int NP = mProcessesOnHold.size();
4294            if (NP > 0) {
4295                ArrayList<ProcessRecord> procs =
4296                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4297                for (int ip=0; ip<NP; ip++) {
4298                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4299                            + procs.get(ip));
4300                    startProcessLocked(procs.get(ip), "on-hold", null);
4301                }
4302            }
4303
4304            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4305                // Start looking for apps that are abusing wake locks.
4306                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4307                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4308                // Tell anyone interested that we are done booting!
4309                SystemProperties.set("sys.boot_completed", "1");
4310                SystemProperties.set("dev.bootcomplete", "1");
4311                for (int i=0; i<mStartedUsers.size(); i++) {
4312                    UserStartedState uss = mStartedUsers.valueAt(i);
4313                    if (uss.mState == UserStartedState.STATE_BOOTING) {
4314                        uss.mState = UserStartedState.STATE_RUNNING;
4315                        final int userId = mStartedUsers.keyAt(i);
4316                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4317                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4318                        broadcastIntentLocked(null, null, intent,
4319                                null, null, 0, null, null,
4320                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4321                                false, false, MY_PID, Process.SYSTEM_UID, userId);
4322                    }
4323                }
4324            }
4325        }
4326    }
4327
4328    final void ensureBootCompleted() {
4329        boolean booting;
4330        boolean enableScreen;
4331        synchronized (this) {
4332            booting = mBooting;
4333            mBooting = false;
4334            enableScreen = !mBooted;
4335            mBooted = true;
4336        }
4337
4338        if (booting) {
4339            finishBooting();
4340        }
4341
4342        if (enableScreen) {
4343            enableScreenAfterBoot();
4344        }
4345    }
4346
4347    public final void activityPaused(IBinder token) {
4348        final long origId = Binder.clearCallingIdentity();
4349        mMainStack.activityPaused(token, false);
4350        Binder.restoreCallingIdentity(origId);
4351    }
4352
4353    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4354            CharSequence description) {
4355        if (localLOGV) Slog.v(
4356            TAG, "Activity stopped: token=" + token);
4357
4358        // Refuse possible leaked file descriptors
4359        if (icicle != null && icicle.hasFileDescriptors()) {
4360            throw new IllegalArgumentException("File descriptors passed in Bundle");
4361        }
4362
4363        ActivityRecord r = null;
4364
4365        final long origId = Binder.clearCallingIdentity();
4366
4367        synchronized (this) {
4368            r = mMainStack.isInStackLocked(token);
4369            if (r != null) {
4370                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4371            }
4372        }
4373
4374        if (r != null) {
4375            sendPendingThumbnail(r, null, null, null, false);
4376        }
4377
4378        trimApplications();
4379
4380        Binder.restoreCallingIdentity(origId);
4381    }
4382
4383    public final void activityDestroyed(IBinder token) {
4384        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4385        mMainStack.activityDestroyed(token);
4386    }
4387
4388    public String getCallingPackage(IBinder token) {
4389        synchronized (this) {
4390            ActivityRecord r = getCallingRecordLocked(token);
4391            return r != null && r.app != null ? r.info.packageName : null;
4392        }
4393    }
4394
4395    public ComponentName getCallingActivity(IBinder token) {
4396        synchronized (this) {
4397            ActivityRecord r = getCallingRecordLocked(token);
4398            return r != null ? r.intent.getComponent() : null;
4399        }
4400    }
4401
4402    private ActivityRecord getCallingRecordLocked(IBinder token) {
4403        ActivityRecord r = mMainStack.isInStackLocked(token);
4404        if (r == null) {
4405            return null;
4406        }
4407        return r.resultTo;
4408    }
4409
4410    public ComponentName getActivityClassForToken(IBinder token) {
4411        synchronized(this) {
4412            ActivityRecord r = mMainStack.isInStackLocked(token);
4413            if (r == null) {
4414                return null;
4415            }
4416            return r.intent.getComponent();
4417        }
4418    }
4419
4420    public String getPackageForToken(IBinder token) {
4421        synchronized(this) {
4422            ActivityRecord r = mMainStack.isInStackLocked(token);
4423            if (r == null) {
4424                return null;
4425            }
4426            return r.packageName;
4427        }
4428    }
4429
4430    public IIntentSender getIntentSender(int type,
4431            String packageName, IBinder token, String resultWho,
4432            int requestCode, Intent[] intents, String[] resolvedTypes,
4433            int flags, Bundle options, int userId) {
4434        enforceNotIsolatedCaller("getIntentSender");
4435        // Refuse possible leaked file descriptors
4436        if (intents != null) {
4437            if (intents.length < 1) {
4438                throw new IllegalArgumentException("Intents array length must be >= 1");
4439            }
4440            for (int i=0; i<intents.length; i++) {
4441                Intent intent = intents[i];
4442                if (intent != null) {
4443                    if (intent.hasFileDescriptors()) {
4444                        throw new IllegalArgumentException("File descriptors passed in Intent");
4445                    }
4446                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4447                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4448                        throw new IllegalArgumentException(
4449                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4450                    }
4451                    intents[i] = new Intent(intent);
4452                }
4453            }
4454            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4455                throw new IllegalArgumentException(
4456                        "Intent array length does not match resolvedTypes length");
4457            }
4458        }
4459        if (options != null) {
4460            if (options.hasFileDescriptors()) {
4461                throw new IllegalArgumentException("File descriptors passed in options");
4462            }
4463        }
4464
4465        synchronized(this) {
4466            int callingUid = Binder.getCallingUid();
4467            userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId,
4468                    false, true, "getIntentSender", null);
4469            try {
4470                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4471                    int uid = AppGlobals.getPackageManager()
4472                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4473                    if (!UserHandle.isSameApp(callingUid, uid)) {
4474                        String msg = "Permission Denial: getIntentSender() from pid="
4475                            + Binder.getCallingPid()
4476                            + ", uid=" + Binder.getCallingUid()
4477                            + ", (need uid=" + uid + ")"
4478                            + " is not allowed to send as package " + packageName;
4479                        Slog.w(TAG, msg);
4480                        throw new SecurityException(msg);
4481                    }
4482                }
4483
4484                return getIntentSenderLocked(type, packageName, callingUid, userId,
4485                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4486
4487            } catch (RemoteException e) {
4488                throw new SecurityException(e);
4489            }
4490        }
4491    }
4492
4493    IIntentSender getIntentSenderLocked(int type, String packageName,
4494            int callingUid, int userId, IBinder token, String resultWho,
4495            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4496            Bundle options) {
4497        if (DEBUG_MU)
4498            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4499        ActivityRecord activity = null;
4500        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4501            activity = mMainStack.isInStackLocked(token);
4502            if (activity == null) {
4503                return null;
4504            }
4505            if (activity.finishing) {
4506                return null;
4507            }
4508        }
4509
4510        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4511        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4512        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4513        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4514                |PendingIntent.FLAG_UPDATE_CURRENT);
4515
4516        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4517                type, packageName, activity, resultWho,
4518                requestCode, intents, resolvedTypes, flags, options, userId);
4519        WeakReference<PendingIntentRecord> ref;
4520        ref = mIntentSenderRecords.get(key);
4521        PendingIntentRecord rec = ref != null ? ref.get() : null;
4522        if (rec != null) {
4523            if (!cancelCurrent) {
4524                if (updateCurrent) {
4525                    if (rec.key.requestIntent != null) {
4526                        rec.key.requestIntent.replaceExtras(intents != null ?
4527                                intents[intents.length - 1] : null);
4528                    }
4529                    if (intents != null) {
4530                        intents[intents.length-1] = rec.key.requestIntent;
4531                        rec.key.allIntents = intents;
4532                        rec.key.allResolvedTypes = resolvedTypes;
4533                    } else {
4534                        rec.key.allIntents = null;
4535                        rec.key.allResolvedTypes = null;
4536                    }
4537                }
4538                return rec;
4539            }
4540            rec.canceled = true;
4541            mIntentSenderRecords.remove(key);
4542        }
4543        if (noCreate) {
4544            return rec;
4545        }
4546        rec = new PendingIntentRecord(this, key, callingUid);
4547        mIntentSenderRecords.put(key, rec.ref);
4548        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4549            if (activity.pendingResults == null) {
4550                activity.pendingResults
4551                        = new HashSet<WeakReference<PendingIntentRecord>>();
4552            }
4553            activity.pendingResults.add(rec.ref);
4554        }
4555        return rec;
4556    }
4557
4558    public void cancelIntentSender(IIntentSender sender) {
4559        if (!(sender instanceof PendingIntentRecord)) {
4560            return;
4561        }
4562        synchronized(this) {
4563            PendingIntentRecord rec = (PendingIntentRecord)sender;
4564            try {
4565                int uid = AppGlobals.getPackageManager()
4566                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4567                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4568                    String msg = "Permission Denial: cancelIntentSender() from pid="
4569                        + Binder.getCallingPid()
4570                        + ", uid=" + Binder.getCallingUid()
4571                        + " is not allowed to cancel packges "
4572                        + rec.key.packageName;
4573                    Slog.w(TAG, msg);
4574                    throw new SecurityException(msg);
4575                }
4576            } catch (RemoteException e) {
4577                throw new SecurityException(e);
4578            }
4579            cancelIntentSenderLocked(rec, true);
4580        }
4581    }
4582
4583    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4584        rec.canceled = true;
4585        mIntentSenderRecords.remove(rec.key);
4586        if (cleanActivity && rec.key.activity != null) {
4587            rec.key.activity.pendingResults.remove(rec.ref);
4588        }
4589    }
4590
4591    public String getPackageForIntentSender(IIntentSender pendingResult) {
4592        if (!(pendingResult instanceof PendingIntentRecord)) {
4593            return null;
4594        }
4595        try {
4596            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4597            return res.key.packageName;
4598        } catch (ClassCastException e) {
4599        }
4600        return null;
4601    }
4602
4603    public int getUidForIntentSender(IIntentSender sender) {
4604        if (sender instanceof PendingIntentRecord) {
4605            try {
4606                PendingIntentRecord res = (PendingIntentRecord)sender;
4607                return res.uid;
4608            } catch (ClassCastException e) {
4609            }
4610        }
4611        return -1;
4612    }
4613
4614    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4615        if (!(pendingResult instanceof PendingIntentRecord)) {
4616            return false;
4617        }
4618        try {
4619            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4620            if (res.key.allIntents == null) {
4621                return false;
4622            }
4623            for (int i=0; i<res.key.allIntents.length; i++) {
4624                Intent intent = res.key.allIntents[i];
4625                if (intent.getPackage() != null && intent.getComponent() != null) {
4626                    return false;
4627                }
4628            }
4629            return true;
4630        } catch (ClassCastException e) {
4631        }
4632        return false;
4633    }
4634
4635    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4636        if (!(pendingResult instanceof PendingIntentRecord)) {
4637            return false;
4638        }
4639        try {
4640            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4641            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4642                return true;
4643            }
4644            return false;
4645        } catch (ClassCastException e) {
4646        }
4647        return false;
4648    }
4649
4650    public void setProcessLimit(int max) {
4651        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4652                "setProcessLimit()");
4653        synchronized (this) {
4654            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4655            mProcessLimitOverride = max;
4656        }
4657        trimApplications();
4658    }
4659
4660    public int getProcessLimit() {
4661        synchronized (this) {
4662            return mProcessLimitOverride;
4663        }
4664    }
4665
4666    void foregroundTokenDied(ForegroundToken token) {
4667        synchronized (ActivityManagerService.this) {
4668            synchronized (mPidsSelfLocked) {
4669                ForegroundToken cur
4670                    = mForegroundProcesses.get(token.pid);
4671                if (cur != token) {
4672                    return;
4673                }
4674                mForegroundProcesses.remove(token.pid);
4675                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4676                if (pr == null) {
4677                    return;
4678                }
4679                pr.forcingToForeground = null;
4680                pr.foregroundServices = false;
4681            }
4682            updateOomAdjLocked();
4683        }
4684    }
4685
4686    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4687        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4688                "setProcessForeground()");
4689        synchronized(this) {
4690            boolean changed = false;
4691
4692            synchronized (mPidsSelfLocked) {
4693                ProcessRecord pr = mPidsSelfLocked.get(pid);
4694                if (pr == null && isForeground) {
4695                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4696                    return;
4697                }
4698                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4699                if (oldToken != null) {
4700                    oldToken.token.unlinkToDeath(oldToken, 0);
4701                    mForegroundProcesses.remove(pid);
4702                    if (pr != null) {
4703                        pr.forcingToForeground = null;
4704                    }
4705                    changed = true;
4706                }
4707                if (isForeground && token != null) {
4708                    ForegroundToken newToken = new ForegroundToken() {
4709                        public void binderDied() {
4710                            foregroundTokenDied(this);
4711                        }
4712                    };
4713                    newToken.pid = pid;
4714                    newToken.token = token;
4715                    try {
4716                        token.linkToDeath(newToken, 0);
4717                        mForegroundProcesses.put(pid, newToken);
4718                        pr.forcingToForeground = token;
4719                        changed = true;
4720                    } catch (RemoteException e) {
4721                        // If the process died while doing this, we will later
4722                        // do the cleanup with the process death link.
4723                    }
4724                }
4725            }
4726
4727            if (changed) {
4728                updateOomAdjLocked();
4729            }
4730        }
4731    }
4732
4733    // =========================================================
4734    // PERMISSIONS
4735    // =========================================================
4736
4737    static class PermissionController extends IPermissionController.Stub {
4738        ActivityManagerService mActivityManagerService;
4739        PermissionController(ActivityManagerService activityManagerService) {
4740            mActivityManagerService = activityManagerService;
4741        }
4742
4743        public boolean checkPermission(String permission, int pid, int uid) {
4744            return mActivityManagerService.checkPermission(permission, pid,
4745                    uid) == PackageManager.PERMISSION_GRANTED;
4746        }
4747    }
4748
4749    /**
4750     * This can be called with or without the global lock held.
4751     */
4752    int checkComponentPermission(String permission, int pid, int uid,
4753            int owningUid, boolean exported) {
4754        // We might be performing an operation on behalf of an indirect binder
4755        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4756        // client identity accordingly before proceeding.
4757        Identity tlsIdentity = sCallerIdentity.get();
4758        if (tlsIdentity != null) {
4759            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4760                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4761            uid = tlsIdentity.uid;
4762            pid = tlsIdentity.pid;
4763        }
4764
4765        if (pid == MY_PID) {
4766            return PackageManager.PERMISSION_GRANTED;
4767        }
4768
4769        return ActivityManager.checkComponentPermission(permission, uid,
4770                owningUid, exported);
4771    }
4772
4773    /**
4774     * As the only public entry point for permissions checking, this method
4775     * can enforce the semantic that requesting a check on a null global
4776     * permission is automatically denied.  (Internally a null permission
4777     * string is used when calling {@link #checkComponentPermission} in cases
4778     * when only uid-based security is needed.)
4779     *
4780     * This can be called with or without the global lock held.
4781     */
4782    public int checkPermission(String permission, int pid, int uid) {
4783        if (permission == null) {
4784            return PackageManager.PERMISSION_DENIED;
4785        }
4786        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4787    }
4788
4789    /**
4790     * Binder IPC calls go through the public entry point.
4791     * This can be called with or without the global lock held.
4792     */
4793    int checkCallingPermission(String permission) {
4794        return checkPermission(permission,
4795                Binder.getCallingPid(),
4796                UserHandle.getAppId(Binder.getCallingUid()));
4797    }
4798
4799    /**
4800     * This can be called with or without the global lock held.
4801     */
4802    void enforceCallingPermission(String permission, String func) {
4803        if (checkCallingPermission(permission)
4804                == PackageManager.PERMISSION_GRANTED) {
4805            return;
4806        }
4807
4808        String msg = "Permission Denial: " + func + " from pid="
4809                + Binder.getCallingPid()
4810                + ", uid=" + Binder.getCallingUid()
4811                + " requires " + permission;
4812        Slog.w(TAG, msg);
4813        throw new SecurityException(msg);
4814    }
4815
4816    /**
4817     * Determine if UID is holding permissions required to access {@link Uri} in
4818     * the given {@link ProviderInfo}. Final permission checking is always done
4819     * in {@link ContentProvider}.
4820     */
4821    private final boolean checkHoldingPermissionsLocked(
4822            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4823        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4824                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4825
4826        if (pi.applicationInfo.uid == uid) {
4827            return true;
4828        } else if (!pi.exported) {
4829            return false;
4830        }
4831
4832        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4833        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4834        try {
4835            // check if target holds top-level <provider> permissions
4836            if (!readMet && pi.readPermission != null
4837                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4838                readMet = true;
4839            }
4840            if (!writeMet && pi.writePermission != null
4841                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4842                writeMet = true;
4843            }
4844
4845            // track if unprotected read/write is allowed; any denied
4846            // <path-permission> below removes this ability
4847            boolean allowDefaultRead = pi.readPermission == null;
4848            boolean allowDefaultWrite = pi.writePermission == null;
4849
4850            // check if target holds any <path-permission> that match uri
4851            final PathPermission[] pps = pi.pathPermissions;
4852            if (pps != null) {
4853                final String path = uri.getPath();
4854                int i = pps.length;
4855                while (i > 0 && (!readMet || !writeMet)) {
4856                    i--;
4857                    PathPermission pp = pps[i];
4858                    if (pp.match(path)) {
4859                        if (!readMet) {
4860                            final String pprperm = pp.getReadPermission();
4861                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4862                                    + pprperm + " for " + pp.getPath()
4863                                    + ": match=" + pp.match(path)
4864                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4865                            if (pprperm != null) {
4866                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4867                                    readMet = true;
4868                                } else {
4869                                    allowDefaultRead = false;
4870                                }
4871                            }
4872                        }
4873                        if (!writeMet) {
4874                            final String ppwperm = pp.getWritePermission();
4875                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4876                                    + ppwperm + " for " + pp.getPath()
4877                                    + ": match=" + pp.match(path)
4878                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4879                            if (ppwperm != null) {
4880                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4881                                    writeMet = true;
4882                                } else {
4883                                    allowDefaultWrite = false;
4884                                }
4885                            }
4886                        }
4887                    }
4888                }
4889            }
4890
4891            // grant unprotected <provider> read/write, if not blocked by
4892            // <path-permission> above
4893            if (allowDefaultRead) readMet = true;
4894            if (allowDefaultWrite) writeMet = true;
4895
4896        } catch (RemoteException e) {
4897            return false;
4898        }
4899
4900        return readMet && writeMet;
4901    }
4902
4903    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4904            int modeFlags) {
4905        // Root gets to do everything.
4906        if (uid == 0) {
4907            return true;
4908        }
4909        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4910        if (perms == null) return false;
4911        UriPermission perm = perms.get(uri);
4912        if (perm == null) return false;
4913        return (modeFlags&perm.modeFlags) == modeFlags;
4914    }
4915
4916    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4917        enforceNotIsolatedCaller("checkUriPermission");
4918
4919        // Another redirected-binder-call permissions check as in
4920        // {@link checkComponentPermission}.
4921        Identity tlsIdentity = sCallerIdentity.get();
4922        if (tlsIdentity != null) {
4923            uid = tlsIdentity.uid;
4924            pid = tlsIdentity.pid;
4925        }
4926
4927        uid = UserHandle.getAppId(uid);
4928        // Our own process gets to do everything.
4929        if (pid == MY_PID) {
4930            return PackageManager.PERMISSION_GRANTED;
4931        }
4932        synchronized(this) {
4933            return checkUriPermissionLocked(uri, uid, modeFlags)
4934                    ? PackageManager.PERMISSION_GRANTED
4935                    : PackageManager.PERMISSION_DENIED;
4936        }
4937    }
4938
4939    /**
4940     * Check if the targetPkg can be granted permission to access uri by
4941     * the callingUid using the given modeFlags.  Throws a security exception
4942     * if callingUid is not allowed to do this.  Returns the uid of the target
4943     * if the URI permission grant should be performed; returns -1 if it is not
4944     * needed (for example targetPkg already has permission to access the URI).
4945     * If you already know the uid of the target, you can supply it in
4946     * lastTargetUid else set that to -1.
4947     */
4948    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4949            Uri uri, int modeFlags, int lastTargetUid) {
4950        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4951                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4952        if (modeFlags == 0) {
4953            return -1;
4954        }
4955
4956        if (targetPkg != null) {
4957            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4958                    "Checking grant " + targetPkg + " permission to " + uri);
4959        }
4960
4961        final IPackageManager pm = AppGlobals.getPackageManager();
4962
4963        // If this is not a content: uri, we can't do anything with it.
4964        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4965            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4966                    "Can't grant URI permission for non-content URI: " + uri);
4967            return -1;
4968        }
4969
4970        String name = uri.getAuthority();
4971        ProviderInfo pi = null;
4972        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4973                UserHandle.getUserId(callingUid));
4974        if (cpr != null) {
4975            pi = cpr.info;
4976        } else {
4977            try {
4978                pi = pm.resolveContentProvider(name,
4979                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid));
4980            } catch (RemoteException ex) {
4981            }
4982        }
4983        if (pi == null) {
4984            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4985            return -1;
4986        }
4987
4988        int targetUid = lastTargetUid;
4989        if (targetUid < 0 && targetPkg != null) {
4990            try {
4991                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
4992                if (targetUid < 0) {
4993                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4994                            "Can't grant URI permission no uid for: " + targetPkg);
4995                    return -1;
4996                }
4997            } catch (RemoteException ex) {
4998                return -1;
4999            }
5000        }
5001
5002        if (targetUid >= 0) {
5003            // First...  does the target actually need this permission?
5004            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5005                // No need to grant the target this permission.
5006                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5007                        "Target " + targetPkg + " already has full permission to " + uri);
5008                return -1;
5009            }
5010        } else {
5011            // First...  there is no target package, so can anyone access it?
5012            boolean allowed = pi.exported;
5013            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5014                if (pi.readPermission != null) {
5015                    allowed = false;
5016                }
5017            }
5018            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5019                if (pi.writePermission != null) {
5020                    allowed = false;
5021                }
5022            }
5023            if (allowed) {
5024                return -1;
5025            }
5026        }
5027
5028        // Second...  is the provider allowing granting of URI permissions?
5029        if (!pi.grantUriPermissions) {
5030            throw new SecurityException("Provider " + pi.packageName
5031                    + "/" + pi.name
5032                    + " does not allow granting of Uri permissions (uri "
5033                    + uri + ")");
5034        }
5035        if (pi.uriPermissionPatterns != null) {
5036            final int N = pi.uriPermissionPatterns.length;
5037            boolean allowed = false;
5038            for (int i=0; i<N; i++) {
5039                if (pi.uriPermissionPatterns[i] != null
5040                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5041                    allowed = true;
5042                    break;
5043                }
5044            }
5045            if (!allowed) {
5046                throw new SecurityException("Provider " + pi.packageName
5047                        + "/" + pi.name
5048                        + " does not allow granting of permission to path of Uri "
5049                        + uri);
5050            }
5051        }
5052
5053        // Third...  does the caller itself have permission to access
5054        // this uri?
5055        if (callingUid != Process.myUid()) {
5056            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5057                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5058                    throw new SecurityException("Uid " + callingUid
5059                            + " does not have permission to uri " + uri);
5060                }
5061            }
5062        }
5063
5064        return targetUid;
5065    }
5066
5067    public int checkGrantUriPermission(int callingUid, String targetPkg,
5068            Uri uri, int modeFlags) {
5069        enforceNotIsolatedCaller("checkGrantUriPermission");
5070        synchronized(this) {
5071            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5072        }
5073    }
5074
5075    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5076            Uri uri, int modeFlags, UriPermissionOwner owner) {
5077        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5078                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5079        if (modeFlags == 0) {
5080            return;
5081        }
5082
5083        // So here we are: the caller has the assumed permission
5084        // to the uri, and the target doesn't.  Let's now give this to
5085        // the target.
5086
5087        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5088                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5089
5090        HashMap<Uri, UriPermission> targetUris
5091                = mGrantedUriPermissions.get(targetUid);
5092        if (targetUris == null) {
5093            targetUris = new HashMap<Uri, UriPermission>();
5094            mGrantedUriPermissions.put(targetUid, targetUris);
5095        }
5096
5097        UriPermission perm = targetUris.get(uri);
5098        if (perm == null) {
5099            perm = new UriPermission(targetUid, uri);
5100            targetUris.put(uri, perm);
5101        }
5102
5103        perm.modeFlags |= modeFlags;
5104        if (owner == null) {
5105            perm.globalModeFlags |= modeFlags;
5106        } else {
5107            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5108                 perm.readOwners.add(owner);
5109                 owner.addReadPermission(perm);
5110            }
5111            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5112                 perm.writeOwners.add(owner);
5113                 owner.addWritePermission(perm);
5114            }
5115        }
5116    }
5117
5118    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5119            int modeFlags, UriPermissionOwner owner) {
5120        if (targetPkg == null) {
5121            throw new NullPointerException("targetPkg");
5122        }
5123
5124        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5125        if (targetUid < 0) {
5126            return;
5127        }
5128
5129        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5130    }
5131
5132    static class NeededUriGrants extends ArrayList<Uri> {
5133        final String targetPkg;
5134        final int targetUid;
5135        final int flags;
5136
5137        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5138            targetPkg = _targetPkg;
5139            targetUid = _targetUid;
5140            flags = _flags;
5141        }
5142    }
5143
5144    /**
5145     * Like checkGrantUriPermissionLocked, but takes an Intent.
5146     */
5147    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5148            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5149        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5150                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5151                + " clip=" + (intent != null ? intent.getClipData() : null)
5152                + " from " + intent + "; flags=0x"
5153                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5154
5155        if (targetPkg == null) {
5156            throw new NullPointerException("targetPkg");
5157        }
5158
5159        if (intent == null) {
5160            return null;
5161        }
5162        Uri data = intent.getData();
5163        ClipData clip = intent.getClipData();
5164        if (data == null && clip == null) {
5165            return null;
5166        }
5167        if (data != null) {
5168            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5169                mode, needed != null ? needed.targetUid : -1);
5170            if (target > 0) {
5171                if (needed == null) {
5172                    needed = new NeededUriGrants(targetPkg, target, mode);
5173                }
5174                needed.add(data);
5175            }
5176        }
5177        if (clip != null) {
5178            for (int i=0; i<clip.getItemCount(); i++) {
5179                Uri uri = clip.getItemAt(i).getUri();
5180                if (uri != null) {
5181                    int target = -1;
5182                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5183                            mode, needed != null ? needed.targetUid : -1);
5184                    if (target > 0) {
5185                        if (needed == null) {
5186                            needed = new NeededUriGrants(targetPkg, target, mode);
5187                        }
5188                        needed.add(uri);
5189                    }
5190                } else {
5191                    Intent clipIntent = clip.getItemAt(i).getIntent();
5192                    if (clipIntent != null) {
5193                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5194                                callingUid, targetPkg, clipIntent, mode, needed);
5195                        if (newNeeded != null) {
5196                            needed = newNeeded;
5197                        }
5198                    }
5199                }
5200            }
5201        }
5202
5203        return needed;
5204    }
5205
5206    /**
5207     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5208     */
5209    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5210            UriPermissionOwner owner) {
5211        if (needed != null) {
5212            for (int i=0; i<needed.size(); i++) {
5213                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5214                        needed.get(i), needed.flags, owner);
5215            }
5216        }
5217    }
5218
5219    void grantUriPermissionFromIntentLocked(int callingUid,
5220            String targetPkg, Intent intent, UriPermissionOwner owner) {
5221        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5222                intent, intent != null ? intent.getFlags() : 0, null);
5223        if (needed == null) {
5224            return;
5225        }
5226
5227        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5228    }
5229
5230    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5231            Uri uri, int modeFlags) {
5232        enforceNotIsolatedCaller("grantUriPermission");
5233        synchronized(this) {
5234            final ProcessRecord r = getRecordForAppLocked(caller);
5235            if (r == null) {
5236                throw new SecurityException("Unable to find app for caller "
5237                        + caller
5238                        + " when granting permission to uri " + uri);
5239            }
5240            if (targetPkg == null) {
5241                throw new IllegalArgumentException("null target");
5242            }
5243            if (uri == null) {
5244                throw new IllegalArgumentException("null uri");
5245            }
5246
5247            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5248                    null);
5249        }
5250    }
5251
5252    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5253        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5254                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5255            HashMap<Uri, UriPermission> perms
5256                    = mGrantedUriPermissions.get(perm.uid);
5257            if (perms != null) {
5258                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5259                        "Removing " + perm.uid + " permission to " + perm.uri);
5260                perms.remove(perm.uri);
5261                if (perms.size() == 0) {
5262                    mGrantedUriPermissions.remove(perm.uid);
5263                }
5264            }
5265        }
5266    }
5267
5268    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5269            int modeFlags) {
5270        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5271                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5272        if (modeFlags == 0) {
5273            return;
5274        }
5275
5276        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5277                "Revoking all granted permissions to " + uri);
5278
5279        final IPackageManager pm = AppGlobals.getPackageManager();
5280
5281        final String authority = uri.getAuthority();
5282        ProviderInfo pi = null;
5283        int userId = UserHandle.getUserId(callingUid);
5284        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5285        if (cpr != null) {
5286            pi = cpr.info;
5287        } else {
5288            try {
5289                pi = pm.resolveContentProvider(authority,
5290                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5291            } catch (RemoteException ex) {
5292            }
5293        }
5294        if (pi == null) {
5295            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5296            return;
5297        }
5298
5299        // Does the caller have this permission on the URI?
5300        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5301            // Right now, if you are not the original owner of the permission,
5302            // you are not allowed to revoke it.
5303            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5304                throw new SecurityException("Uid " + callingUid
5305                        + " does not have permission to uri " + uri);
5306            //}
5307        }
5308
5309        // Go through all of the permissions and remove any that match.
5310        final List<String> SEGMENTS = uri.getPathSegments();
5311        if (SEGMENTS != null) {
5312            final int NS = SEGMENTS.size();
5313            int N = mGrantedUriPermissions.size();
5314            for (int i=0; i<N; i++) {
5315                HashMap<Uri, UriPermission> perms
5316                        = mGrantedUriPermissions.valueAt(i);
5317                Iterator<UriPermission> it = perms.values().iterator();
5318            toploop:
5319                while (it.hasNext()) {
5320                    UriPermission perm = it.next();
5321                    Uri targetUri = perm.uri;
5322                    if (!authority.equals(targetUri.getAuthority())) {
5323                        continue;
5324                    }
5325                    List<String> targetSegments = targetUri.getPathSegments();
5326                    if (targetSegments == null) {
5327                        continue;
5328                    }
5329                    if (targetSegments.size() < NS) {
5330                        continue;
5331                    }
5332                    for (int j=0; j<NS; j++) {
5333                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5334                            continue toploop;
5335                        }
5336                    }
5337                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5338                            "Revoking " + perm.uid + " permission to " + perm.uri);
5339                    perm.clearModes(modeFlags);
5340                    if (perm.modeFlags == 0) {
5341                        it.remove();
5342                    }
5343                }
5344                if (perms.size() == 0) {
5345                    mGrantedUriPermissions.remove(
5346                            mGrantedUriPermissions.keyAt(i));
5347                    N--;
5348                    i--;
5349                }
5350            }
5351        }
5352    }
5353
5354    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5355            int modeFlags) {
5356        enforceNotIsolatedCaller("revokeUriPermission");
5357        synchronized(this) {
5358            final ProcessRecord r = getRecordForAppLocked(caller);
5359            if (r == null) {
5360                throw new SecurityException("Unable to find app for caller "
5361                        + caller
5362                        + " when revoking permission to uri " + uri);
5363            }
5364            if (uri == null) {
5365                Slog.w(TAG, "revokeUriPermission: null uri");
5366                return;
5367            }
5368
5369            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5370                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5371            if (modeFlags == 0) {
5372                return;
5373            }
5374
5375            final IPackageManager pm = AppGlobals.getPackageManager();
5376
5377            final String authority = uri.getAuthority();
5378            ProviderInfo pi = null;
5379            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5380            if (cpr != null) {
5381                pi = cpr.info;
5382            } else {
5383                try {
5384                    pi = pm.resolveContentProvider(authority,
5385                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5386                } catch (RemoteException ex) {
5387                }
5388            }
5389            if (pi == null) {
5390                Slog.w(TAG, "No content provider found for permission revoke: "
5391                        + uri.toSafeString());
5392                return;
5393            }
5394
5395            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5396        }
5397    }
5398
5399    @Override
5400    public IBinder newUriPermissionOwner(String name) {
5401        enforceNotIsolatedCaller("newUriPermissionOwner");
5402        synchronized(this) {
5403            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5404            return owner.getExternalTokenLocked();
5405        }
5406    }
5407
5408    @Override
5409    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5410            Uri uri, int modeFlags) {
5411        synchronized(this) {
5412            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5413            if (owner == null) {
5414                throw new IllegalArgumentException("Unknown owner: " + token);
5415            }
5416            if (fromUid != Binder.getCallingUid()) {
5417                if (Binder.getCallingUid() != Process.myUid()) {
5418                    // Only system code can grant URI permissions on behalf
5419                    // of other users.
5420                    throw new SecurityException("nice try");
5421                }
5422            }
5423            if (targetPkg == null) {
5424                throw new IllegalArgumentException("null target");
5425            }
5426            if (uri == null) {
5427                throw new IllegalArgumentException("null uri");
5428            }
5429
5430            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5431        }
5432    }
5433
5434    @Override
5435    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5436        synchronized(this) {
5437            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5438            if (owner == null) {
5439                throw new IllegalArgumentException("Unknown owner: " + token);
5440            }
5441
5442            if (uri == null) {
5443                owner.removeUriPermissionsLocked(mode);
5444            } else {
5445                owner.removeUriPermissionLocked(uri, mode);
5446            }
5447        }
5448    }
5449
5450    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5451        synchronized (this) {
5452            ProcessRecord app =
5453                who != null ? getRecordForAppLocked(who) : null;
5454            if (app == null) return;
5455
5456            Message msg = Message.obtain();
5457            msg.what = WAIT_FOR_DEBUGGER_MSG;
5458            msg.obj = app;
5459            msg.arg1 = waiting ? 1 : 0;
5460            mHandler.sendMessage(msg);
5461        }
5462    }
5463
5464    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5465        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5466        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5467        outInfo.availMem = Process.getFreeMemory();
5468        outInfo.totalMem = Process.getTotalMemory();
5469        outInfo.threshold = homeAppMem;
5470        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5471        outInfo.hiddenAppThreshold = hiddenAppMem;
5472        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5473                ProcessList.SERVICE_ADJ);
5474        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5475                ProcessList.VISIBLE_APP_ADJ);
5476        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5477                ProcessList.FOREGROUND_APP_ADJ);
5478    }
5479
5480    // =========================================================
5481    // TASK MANAGEMENT
5482    // =========================================================
5483
5484    public List getTasks(int maxNum, int flags,
5485                         IThumbnailReceiver receiver) {
5486        ArrayList list = new ArrayList();
5487
5488        PendingThumbnailsRecord pending = null;
5489        IApplicationThread topThumbnail = null;
5490        ActivityRecord topRecord = null;
5491
5492        synchronized(this) {
5493            if (localLOGV) Slog.v(
5494                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5495                + ", receiver=" + receiver);
5496
5497            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5498                    != PackageManager.PERMISSION_GRANTED) {
5499                if (receiver != null) {
5500                    // If the caller wants to wait for pending thumbnails,
5501                    // it ain't gonna get them.
5502                    try {
5503                        receiver.finished();
5504                    } catch (RemoteException ex) {
5505                    }
5506                }
5507                String msg = "Permission Denial: getTasks() from pid="
5508                        + Binder.getCallingPid()
5509                        + ", uid=" + Binder.getCallingUid()
5510                        + " requires " + android.Manifest.permission.GET_TASKS;
5511                Slog.w(TAG, msg);
5512                throw new SecurityException(msg);
5513            }
5514
5515            int pos = mMainStack.mHistory.size()-1;
5516            ActivityRecord next =
5517                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5518            ActivityRecord top = null;
5519            TaskRecord curTask = null;
5520            int numActivities = 0;
5521            int numRunning = 0;
5522            while (pos >= 0 && maxNum > 0) {
5523                final ActivityRecord r = next;
5524                pos--;
5525                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5526
5527                // Initialize state for next task if needed.
5528                if (top == null ||
5529                        (top.state == ActivityState.INITIALIZING
5530                            && top.task == r.task)) {
5531                    top = r;
5532                    curTask = r.task;
5533                    numActivities = numRunning = 0;
5534                }
5535
5536                // Add 'r' into the current task.
5537                numActivities++;
5538                if (r.app != null && r.app.thread != null) {
5539                    numRunning++;
5540                }
5541
5542                if (localLOGV) Slog.v(
5543                    TAG, r.intent.getComponent().flattenToShortString()
5544                    + ": task=" + r.task);
5545
5546                // If the next one is a different task, generate a new
5547                // TaskInfo entry for what we have.
5548                if (next == null || next.task != curTask) {
5549                    ActivityManager.RunningTaskInfo ci
5550                            = new ActivityManager.RunningTaskInfo();
5551                    ci.id = curTask.taskId;
5552                    ci.baseActivity = r.intent.getComponent();
5553                    ci.topActivity = top.intent.getComponent();
5554                    if (top.thumbHolder != null) {
5555                        ci.description = top.thumbHolder.lastDescription;
5556                    }
5557                    ci.numActivities = numActivities;
5558                    ci.numRunning = numRunning;
5559                    //System.out.println(
5560                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5561                    if (ci.thumbnail == null && receiver != null) {
5562                        if (localLOGV) Slog.v(
5563                            TAG, "State=" + top.state + "Idle=" + top.idle
5564                            + " app=" + top.app
5565                            + " thr=" + (top.app != null ? top.app.thread : null));
5566                        if (top.state == ActivityState.RESUMED
5567                                || top.state == ActivityState.PAUSING) {
5568                            if (top.idle && top.app != null
5569                                && top.app.thread != null) {
5570                                topRecord = top;
5571                                topThumbnail = top.app.thread;
5572                            } else {
5573                                top.thumbnailNeeded = true;
5574                            }
5575                        }
5576                        if (pending == null) {
5577                            pending = new PendingThumbnailsRecord(receiver);
5578                        }
5579                        pending.pendingRecords.add(top);
5580                    }
5581                    list.add(ci);
5582                    maxNum--;
5583                    top = null;
5584                }
5585            }
5586
5587            if (pending != null) {
5588                mPendingThumbnails.add(pending);
5589            }
5590        }
5591
5592        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5593
5594        if (topThumbnail != null) {
5595            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5596            try {
5597                topThumbnail.requestThumbnail(topRecord.appToken);
5598            } catch (Exception e) {
5599                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5600                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5601            }
5602        }
5603
5604        if (pending == null && receiver != null) {
5605            // In this case all thumbnails were available and the client
5606            // is being asked to be told when the remaining ones come in...
5607            // which is unusually, since the top-most currently running
5608            // activity should never have a canned thumbnail!  Oh well.
5609            try {
5610                receiver.finished();
5611            } catch (RemoteException ex) {
5612            }
5613        }
5614
5615        return list;
5616    }
5617
5618    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5619            int flags, int userId) {
5620        final int callingUid = Binder.getCallingUid();
5621        if (userId != UserHandle.getCallingUserId()) {
5622            // Check if the caller is holding permissions for cross-user requests.
5623            if (checkComponentPermission(
5624                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5625                    Binder.getCallingPid(), callingUid, -1, true)
5626                    != PackageManager.PERMISSION_GRANTED) {
5627                String msg = "Permission Denial: "
5628                        + "Request to get recent tasks for user " + userId
5629                        + " but is calling from user " + UserHandle.getUserId(callingUid)
5630                        + "; this requires "
5631                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5632                Slog.w(TAG, msg);
5633                throw new SecurityException(msg);
5634            } else {
5635                if (userId == UserHandle.USER_CURRENT) {
5636                    userId = mCurrentUserId;
5637                }
5638            }
5639        }
5640
5641        synchronized (this) {
5642            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5643                    "getRecentTasks()");
5644            final boolean detailed = checkCallingPermission(
5645                    android.Manifest.permission.GET_DETAILED_TASKS)
5646                    == PackageManager.PERMISSION_GRANTED;
5647
5648            IPackageManager pm = AppGlobals.getPackageManager();
5649
5650            final int N = mRecentTasks.size();
5651            ArrayList<ActivityManager.RecentTaskInfo> res
5652                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5653                            maxNum < N ? maxNum : N);
5654            for (int i=0; i<N && maxNum > 0; i++) {
5655                TaskRecord tr = mRecentTasks.get(i);
5656                // Only add calling user's recent tasks
5657                if (tr.userId != userId) continue;
5658                // Return the entry if desired by the caller.  We always return
5659                // the first entry, because callers always expect this to be the
5660                // foreground app.  We may filter others if the caller has
5661                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5662                // we should exclude the entry.
5663
5664                if (i == 0
5665                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5666                        || (tr.intent == null)
5667                        || ((tr.intent.getFlags()
5668                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5669                    ActivityManager.RecentTaskInfo rti
5670                            = new ActivityManager.RecentTaskInfo();
5671                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5672                    rti.persistentId = tr.taskId;
5673                    rti.baseIntent = new Intent(
5674                            tr.intent != null ? tr.intent : tr.affinityIntent);
5675                    if (!detailed) {
5676                        rti.baseIntent.replaceExtras((Bundle)null);
5677                    }
5678                    rti.origActivity = tr.origActivity;
5679                    rti.description = tr.lastDescription;
5680
5681                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5682                        // Check whether this activity is currently available.
5683                        try {
5684                            if (rti.origActivity != null) {
5685                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5686                                        == null) {
5687                                    continue;
5688                                }
5689                            } else if (rti.baseIntent != null) {
5690                                if (pm.queryIntentActivities(rti.baseIntent,
5691                                        null, 0, userId) == null) {
5692                                    continue;
5693                                }
5694                            }
5695                        } catch (RemoteException e) {
5696                            // Will never happen.
5697                        }
5698                    }
5699
5700                    res.add(rti);
5701                    maxNum--;
5702                }
5703            }
5704            return res;
5705        }
5706    }
5707
5708    private TaskRecord taskForIdLocked(int id) {
5709        final int N = mRecentTasks.size();
5710        for (int i=0; i<N; i++) {
5711            TaskRecord tr = mRecentTasks.get(i);
5712            if (tr.taskId == id) {
5713                return tr;
5714            }
5715        }
5716        return null;
5717    }
5718
5719    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5720        synchronized (this) {
5721            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5722                    "getTaskThumbnails()");
5723            TaskRecord tr = taskForIdLocked(id);
5724            if (tr != null) {
5725                return mMainStack.getTaskThumbnailsLocked(tr);
5726            }
5727        }
5728        return null;
5729    }
5730
5731    public boolean removeSubTask(int taskId, int subTaskIndex) {
5732        synchronized (this) {
5733            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5734                    "removeSubTask()");
5735            long ident = Binder.clearCallingIdentity();
5736            try {
5737                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5738                        true) != null;
5739            } finally {
5740                Binder.restoreCallingIdentity(ident);
5741            }
5742        }
5743    }
5744
5745    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5746        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5747        Intent baseIntent = new Intent(
5748                tr.intent != null ? tr.intent : tr.affinityIntent);
5749        ComponentName component = baseIntent.getComponent();
5750        if (component == null) {
5751            Slog.w(TAG, "Now component for base intent of task: " + tr);
5752            return;
5753        }
5754
5755        // Find any running services associated with this app.
5756        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5757
5758        if (killProcesses) {
5759            // Find any running processes associated with this app.
5760            final String pkg = component.getPackageName();
5761            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5762            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5763            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5764                for (int i=0; i<uids.size(); i++) {
5765                    ProcessRecord proc = uids.valueAt(i);
5766                    if (proc.userId != tr.userId) {
5767                        continue;
5768                    }
5769                    if (!proc.pkgList.contains(pkg)) {
5770                        continue;
5771                    }
5772                    procs.add(proc);
5773                }
5774            }
5775
5776            // Kill the running processes.
5777            for (int i=0; i<procs.size(); i++) {
5778                ProcessRecord pr = procs.get(i);
5779                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5780                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5781                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5782                            pr.processName, pr.setAdj, "remove task");
5783                    pr.killedBackground = true;
5784                    Process.killProcessQuiet(pr.pid);
5785                } else {
5786                    pr.waitingToKill = "remove task";
5787                }
5788            }
5789        }
5790    }
5791
5792    public boolean removeTask(int taskId, int flags) {
5793        synchronized (this) {
5794            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5795                    "removeTask()");
5796            long ident = Binder.clearCallingIdentity();
5797            try {
5798                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5799                        false);
5800                if (r != null) {
5801                    mRecentTasks.remove(r.task);
5802                    cleanUpRemovedTaskLocked(r.task, flags);
5803                    return true;
5804                } else {
5805                    TaskRecord tr = null;
5806                    int i=0;
5807                    while (i < mRecentTasks.size()) {
5808                        TaskRecord t = mRecentTasks.get(i);
5809                        if (t.taskId == taskId) {
5810                            tr = t;
5811                            break;
5812                        }
5813                        i++;
5814                    }
5815                    if (tr != null) {
5816                        if (tr.numActivities <= 0) {
5817                            // Caller is just removing a recent task that is
5818                            // not actively running.  That is easy!
5819                            mRecentTasks.remove(i);
5820                            cleanUpRemovedTaskLocked(tr, flags);
5821                            return true;
5822                        } else {
5823                            Slog.w(TAG, "removeTask: task " + taskId
5824                                    + " does not have activities to remove, "
5825                                    + " but numActivities=" + tr.numActivities
5826                                    + ": " + tr);
5827                        }
5828                    }
5829                }
5830            } finally {
5831                Binder.restoreCallingIdentity(ident);
5832            }
5833        }
5834        return false;
5835    }
5836
5837    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5838        int j;
5839        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5840        TaskRecord jt = startTask;
5841
5842        // First look backwards
5843        for (j=startIndex-1; j>=0; j--) {
5844            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5845            if (r.task != jt) {
5846                jt = r.task;
5847                if (affinity.equals(jt.affinity)) {
5848                    return j;
5849                }
5850            }
5851        }
5852
5853        // Now look forwards
5854        final int N = mMainStack.mHistory.size();
5855        jt = startTask;
5856        for (j=startIndex+1; j<N; j++) {
5857            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5858            if (r.task != jt) {
5859                if (affinity.equals(jt.affinity)) {
5860                    return j;
5861                }
5862                jt = r.task;
5863            }
5864        }
5865
5866        // Might it be at the top?
5867        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5868            return N-1;
5869        }
5870
5871        return -1;
5872    }
5873
5874    /**
5875     * TODO: Add mController hook
5876     */
5877    public void moveTaskToFront(int task, int flags, Bundle options) {
5878        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5879                "moveTaskToFront()");
5880
5881        synchronized(this) {
5882            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5883                    Binder.getCallingUid(), "Task to front")) {
5884                ActivityOptions.abort(options);
5885                return;
5886            }
5887            final long origId = Binder.clearCallingIdentity();
5888            try {
5889                TaskRecord tr = taskForIdLocked(task);
5890                if (tr != null) {
5891                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5892                        mMainStack.mUserLeaving = true;
5893                    }
5894                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5895                        // Caller wants the home activity moved with it.  To accomplish this,
5896                        // we'll just move the home task to the top first.
5897                        mMainStack.moveHomeToFrontLocked();
5898                    }
5899                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5900                    return;
5901                }
5902                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5903                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5904                    if (hr.task.taskId == task) {
5905                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5906                            mMainStack.mUserLeaving = true;
5907                        }
5908                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5909                            // Caller wants the home activity moved with it.  To accomplish this,
5910                            // we'll just move the home task to the top first.
5911                            mMainStack.moveHomeToFrontLocked();
5912                        }
5913                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5914                        return;
5915                    }
5916                }
5917            } finally {
5918                Binder.restoreCallingIdentity(origId);
5919            }
5920            ActivityOptions.abort(options);
5921        }
5922    }
5923
5924    public void moveTaskToBack(int task) {
5925        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5926                "moveTaskToBack()");
5927
5928        synchronized(this) {
5929            if (mMainStack.mResumedActivity != null
5930                    && mMainStack.mResumedActivity.task.taskId == task) {
5931                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5932                        Binder.getCallingUid(), "Task to back")) {
5933                    return;
5934                }
5935            }
5936            final long origId = Binder.clearCallingIdentity();
5937            mMainStack.moveTaskToBackLocked(task, null);
5938            Binder.restoreCallingIdentity(origId);
5939        }
5940    }
5941
5942    /**
5943     * Moves an activity, and all of the other activities within the same task, to the bottom
5944     * of the history stack.  The activity's order within the task is unchanged.
5945     *
5946     * @param token A reference to the activity we wish to move
5947     * @param nonRoot If false then this only works if the activity is the root
5948     *                of a task; if true it will work for any activity in a task.
5949     * @return Returns true if the move completed, false if not.
5950     */
5951    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5952        enforceNotIsolatedCaller("moveActivityTaskToBack");
5953        synchronized(this) {
5954            final long origId = Binder.clearCallingIdentity();
5955            int taskId = getTaskForActivityLocked(token, !nonRoot);
5956            if (taskId >= 0) {
5957                return mMainStack.moveTaskToBackLocked(taskId, null);
5958            }
5959            Binder.restoreCallingIdentity(origId);
5960        }
5961        return false;
5962    }
5963
5964    public void moveTaskBackwards(int task) {
5965        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5966                "moveTaskBackwards()");
5967
5968        synchronized(this) {
5969            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5970                    Binder.getCallingUid(), "Task backwards")) {
5971                return;
5972            }
5973            final long origId = Binder.clearCallingIdentity();
5974            moveTaskBackwardsLocked(task);
5975            Binder.restoreCallingIdentity(origId);
5976        }
5977    }
5978
5979    private final void moveTaskBackwardsLocked(int task) {
5980        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5981    }
5982
5983    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5984        synchronized(this) {
5985            return getTaskForActivityLocked(token, onlyRoot);
5986        }
5987    }
5988
5989    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5990        final int N = mMainStack.mHistory.size();
5991        TaskRecord lastTask = null;
5992        for (int i=0; i<N; i++) {
5993            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5994            if (r.appToken == token) {
5995                if (!onlyRoot || lastTask != r.task) {
5996                    return r.task.taskId;
5997                }
5998                return -1;
5999            }
6000            lastTask = r.task;
6001        }
6002
6003        return -1;
6004    }
6005
6006    // =========================================================
6007    // THUMBNAILS
6008    // =========================================================
6009
6010    public void reportThumbnail(IBinder token,
6011            Bitmap thumbnail, CharSequence description) {
6012        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6013        final long origId = Binder.clearCallingIdentity();
6014        sendPendingThumbnail(null, token, thumbnail, description, true);
6015        Binder.restoreCallingIdentity(origId);
6016    }
6017
6018    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6019            Bitmap thumbnail, CharSequence description, boolean always) {
6020        TaskRecord task = null;
6021        ArrayList receivers = null;
6022
6023        //System.out.println("Send pending thumbnail: " + r);
6024
6025        synchronized(this) {
6026            if (r == null) {
6027                r = mMainStack.isInStackLocked(token);
6028                if (r == null) {
6029                    return;
6030                }
6031            }
6032            if (thumbnail == null && r.thumbHolder != null) {
6033                thumbnail = r.thumbHolder.lastThumbnail;
6034                description = r.thumbHolder.lastDescription;
6035            }
6036            if (thumbnail == null && !always) {
6037                // If there is no thumbnail, and this entry is not actually
6038                // going away, then abort for now and pick up the next
6039                // thumbnail we get.
6040                return;
6041            }
6042            task = r.task;
6043
6044            int N = mPendingThumbnails.size();
6045            int i=0;
6046            while (i<N) {
6047                PendingThumbnailsRecord pr =
6048                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6049                //System.out.println("Looking in " + pr.pendingRecords);
6050                if (pr.pendingRecords.remove(r)) {
6051                    if (receivers == null) {
6052                        receivers = new ArrayList();
6053                    }
6054                    receivers.add(pr);
6055                    if (pr.pendingRecords.size() == 0) {
6056                        pr.finished = true;
6057                        mPendingThumbnails.remove(i);
6058                        N--;
6059                        continue;
6060                    }
6061                }
6062                i++;
6063            }
6064        }
6065
6066        if (receivers != null) {
6067            final int N = receivers.size();
6068            for (int i=0; i<N; i++) {
6069                try {
6070                    PendingThumbnailsRecord pr =
6071                        (PendingThumbnailsRecord)receivers.get(i);
6072                    pr.receiver.newThumbnail(
6073                        task != null ? task.taskId : -1, thumbnail, description);
6074                    if (pr.finished) {
6075                        pr.receiver.finished();
6076                    }
6077                } catch (Exception e) {
6078                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6079                }
6080            }
6081        }
6082    }
6083
6084    // =========================================================
6085    // CONTENT PROVIDERS
6086    // =========================================================
6087
6088    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6089        List<ProviderInfo> providers = null;
6090        try {
6091            providers = AppGlobals.getPackageManager().
6092                queryContentProviders(app.processName, app.uid,
6093                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6094        } catch (RemoteException ex) {
6095        }
6096        if (DEBUG_MU)
6097            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6098        int userId = app.userId;
6099        if (providers != null) {
6100            int N = providers.size();
6101            for (int i=0; i<N; i++) {
6102                ProviderInfo cpi =
6103                    (ProviderInfo)providers.get(i);
6104                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6105                        cpi.name, cpi.flags);
6106                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6107                    // This is a singleton provider, but a user besides the
6108                    // default user is asking to initialize a process it runs
6109                    // in...  well, no, it doesn't actually run in this process,
6110                    // it runs in the process of the default user.  Get rid of it.
6111                    providers.remove(i);
6112                    N--;
6113                    continue;
6114                }
6115
6116                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6117                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6118                if (cpr == null) {
6119                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6120                    mProviderMap.putProviderByClass(comp, cpr);
6121                }
6122                if (DEBUG_MU)
6123                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6124                app.pubProviders.put(cpi.name, cpr);
6125                app.addPackage(cpi.applicationInfo.packageName);
6126                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6127            }
6128        }
6129        return providers;
6130    }
6131
6132    /**
6133     * Check if {@link ProcessRecord} has a possible chance at accessing the
6134     * given {@link ProviderInfo}. Final permission checking is always done
6135     * in {@link ContentProvider}.
6136     */
6137    private final String checkContentProviderPermissionLocked(
6138            ProviderInfo cpi, ProcessRecord r) {
6139        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6140        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6141        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6142                cpi.applicationInfo.uid, cpi.exported)
6143                == PackageManager.PERMISSION_GRANTED) {
6144            return null;
6145        }
6146        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6147                cpi.applicationInfo.uid, cpi.exported)
6148                == PackageManager.PERMISSION_GRANTED) {
6149            return null;
6150        }
6151
6152        PathPermission[] pps = cpi.pathPermissions;
6153        if (pps != null) {
6154            int i = pps.length;
6155            while (i > 0) {
6156                i--;
6157                PathPermission pp = pps[i];
6158                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6159                        cpi.applicationInfo.uid, cpi.exported)
6160                        == PackageManager.PERMISSION_GRANTED) {
6161                    return null;
6162                }
6163                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6164                        cpi.applicationInfo.uid, cpi.exported)
6165                        == PackageManager.PERMISSION_GRANTED) {
6166                    return null;
6167                }
6168            }
6169        }
6170
6171        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6172        if (perms != null) {
6173            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6174                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6175                    return null;
6176                }
6177            }
6178        }
6179
6180        String msg;
6181        if (!cpi.exported) {
6182            msg = "Permission Denial: opening provider " + cpi.name
6183                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6184                    + ", uid=" + callingUid + ") that is not exported from uid "
6185                    + cpi.applicationInfo.uid;
6186        } else {
6187            msg = "Permission Denial: opening provider " + cpi.name
6188                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6189                    + ", uid=" + callingUid + ") requires "
6190                    + cpi.readPermission + " or " + cpi.writePermission;
6191        }
6192        Slog.w(TAG, msg);
6193        return msg;
6194    }
6195
6196    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6197            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6198        if (r != null) {
6199            for (int i=0; i<r.conProviders.size(); i++) {
6200                ContentProviderConnection conn = r.conProviders.get(i);
6201                if (conn.provider == cpr) {
6202                    if (DEBUG_PROVIDER) Slog.v(TAG,
6203                            "Adding provider requested by "
6204                            + r.processName + " from process "
6205                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6206                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6207                    if (stable) {
6208                        conn.stableCount++;
6209                        conn.numStableIncs++;
6210                    } else {
6211                        conn.unstableCount++;
6212                        conn.numUnstableIncs++;
6213                    }
6214                    return conn;
6215                }
6216            }
6217            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6218            if (stable) {
6219                conn.stableCount = 1;
6220                conn.numStableIncs = 1;
6221            } else {
6222                conn.unstableCount = 1;
6223                conn.numUnstableIncs = 1;
6224            }
6225            cpr.connections.add(conn);
6226            r.conProviders.add(conn);
6227            return conn;
6228        }
6229        cpr.addExternalProcessHandleLocked(externalProcessToken);
6230        return null;
6231    }
6232
6233    boolean decProviderCountLocked(ContentProviderConnection conn,
6234            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6235        if (conn != null) {
6236            cpr = conn.provider;
6237            if (DEBUG_PROVIDER) Slog.v(TAG,
6238                    "Removing provider requested by "
6239                    + conn.client.processName + " from process "
6240                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6241                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6242            if (stable) {
6243                conn.stableCount--;
6244            } else {
6245                conn.unstableCount--;
6246            }
6247            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6248                cpr.connections.remove(conn);
6249                conn.client.conProviders.remove(conn);
6250                return true;
6251            }
6252            return false;
6253        }
6254        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6255        return false;
6256    }
6257
6258    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6259            String name, IBinder token, boolean stable, int userId) {
6260        ContentProviderRecord cpr;
6261        ContentProviderConnection conn = null;
6262        ProviderInfo cpi = null;
6263
6264        synchronized(this) {
6265            ProcessRecord r = null;
6266            if (caller != null) {
6267                r = getRecordForAppLocked(caller);
6268                if (r == null) {
6269                    throw new SecurityException(
6270                            "Unable to find app for caller " + caller
6271                          + " (pid=" + Binder.getCallingPid()
6272                          + ") when getting content provider " + name);
6273                }
6274                if (r.userId != userId) {
6275                    throw new SecurityException("Calling requested user " + userId
6276                            + " but app is user " + r.userId);
6277                }
6278            }
6279
6280            // First check if this content provider has been published...
6281            cpr = mProviderMap.getProviderByName(name, userId);
6282            boolean providerRunning = cpr != null;
6283            if (providerRunning) {
6284                cpi = cpr.info;
6285                String msg;
6286                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6287                    throw new SecurityException(msg);
6288                }
6289
6290                if (r != null && cpr.canRunHere(r)) {
6291                    // This provider has been published or is in the process
6292                    // of being published...  but it is also allowed to run
6293                    // in the caller's process, so don't make a connection
6294                    // and just let the caller instantiate its own instance.
6295                    ContentProviderHolder holder = cpr.newHolder(null);
6296                    // don't give caller the provider object, it needs
6297                    // to make its own.
6298                    holder.provider = null;
6299                    return holder;
6300                }
6301
6302                final long origId = Binder.clearCallingIdentity();
6303
6304                // In this case the provider instance already exists, so we can
6305                // return it right away.
6306                conn = incProviderCountLocked(r, cpr, token, stable);
6307                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6308                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6309                        // If this is a perceptible app accessing the provider,
6310                        // make sure to count it as being accessed and thus
6311                        // back up on the LRU list.  This is good because
6312                        // content providers are often expensive to start.
6313                        updateLruProcessLocked(cpr.proc, false, true);
6314                    }
6315                }
6316
6317                if (cpr.proc != null) {
6318                    if (false) {
6319                        if (cpr.name.flattenToShortString().equals(
6320                                "com.android.providers.calendar/.CalendarProvider2")) {
6321                            Slog.v(TAG, "****************** KILLING "
6322                                + cpr.name.flattenToShortString());
6323                            Process.killProcess(cpr.proc.pid);
6324                        }
6325                    }
6326                    boolean success = updateOomAdjLocked(cpr.proc);
6327                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6328                    // NOTE: there is still a race here where a signal could be
6329                    // pending on the process even though we managed to update its
6330                    // adj level.  Not sure what to do about this, but at least
6331                    // the race is now smaller.
6332                    if (!success) {
6333                        // Uh oh...  it looks like the provider's process
6334                        // has been killed on us.  We need to wait for a new
6335                        // process to be started, and make sure its death
6336                        // doesn't kill our process.
6337                        Slog.i(TAG,
6338                                "Existing provider " + cpr.name.flattenToShortString()
6339                                + " is crashing; detaching " + r);
6340                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6341                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6342                        if (!lastRef) {
6343                            // This wasn't the last ref our process had on
6344                            // the provider...  we have now been killed, bail.
6345                            return null;
6346                        }
6347                        providerRunning = false;
6348                        conn = null;
6349                    }
6350                }
6351
6352                Binder.restoreCallingIdentity(origId);
6353            }
6354
6355            boolean singleton;
6356            if (!providerRunning) {
6357                try {
6358                    cpi = AppGlobals.getPackageManager().
6359                        resolveContentProvider(name,
6360                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6361                } catch (RemoteException ex) {
6362                }
6363                if (cpi == null) {
6364                    return null;
6365                }
6366                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6367                        cpi.name, cpi.flags);
6368                if (singleton) {
6369                    userId = 0;
6370                }
6371                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6372
6373                String msg;
6374                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6375                    throw new SecurityException(msg);
6376                }
6377
6378                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6379                        && !cpi.processName.equals("system")) {
6380                    // If this content provider does not run in the system
6381                    // process, and the system is not yet ready to run other
6382                    // processes, then fail fast instead of hanging.
6383                    throw new IllegalArgumentException(
6384                            "Attempt to launch content provider before system ready");
6385                }
6386
6387                // Make sure that the user who owns this provider is started.  If not,
6388                // we don't want to allow it to run.
6389                if (mStartedUsers.get(userId) == null) {
6390                    Slog.w(TAG, "Unable to launch app "
6391                            + cpi.applicationInfo.packageName + "/"
6392                            + cpi.applicationInfo.uid + " for provider "
6393                            + name + ": user " + userId + " is stopped");
6394                    return null;
6395                }
6396
6397                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6398                cpr = mProviderMap.getProviderByClass(comp, userId);
6399                final boolean firstClass = cpr == null;
6400                if (firstClass) {
6401                    try {
6402                        ApplicationInfo ai =
6403                            AppGlobals.getPackageManager().
6404                                getApplicationInfo(
6405                                        cpi.applicationInfo.packageName,
6406                                        STOCK_PM_FLAGS, userId);
6407                        if (ai == null) {
6408                            Slog.w(TAG, "No package info for content provider "
6409                                    + cpi.name);
6410                            return null;
6411                        }
6412                        ai = getAppInfoForUser(ai, userId);
6413                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6414                    } catch (RemoteException ex) {
6415                        // pm is in same process, this will never happen.
6416                    }
6417                }
6418
6419                if (r != null && cpr.canRunHere(r)) {
6420                    // If this is a multiprocess provider, then just return its
6421                    // info and allow the caller to instantiate it.  Only do
6422                    // this if the provider is the same user as the caller's
6423                    // process, or can run as root (so can be in any process).
6424                    return cpr.newHolder(null);
6425                }
6426
6427                if (DEBUG_PROVIDER) {
6428                    RuntimeException e = new RuntimeException("here");
6429                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6430                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6431                }
6432
6433                // This is single process, and our app is now connecting to it.
6434                // See if we are already in the process of launching this
6435                // provider.
6436                final int N = mLaunchingProviders.size();
6437                int i;
6438                for (i=0; i<N; i++) {
6439                    if (mLaunchingProviders.get(i) == cpr) {
6440                        break;
6441                    }
6442                }
6443
6444                // If the provider is not already being launched, then get it
6445                // started.
6446                if (i >= N) {
6447                    final long origId = Binder.clearCallingIdentity();
6448
6449                    try {
6450                        // Content provider is now in use, its package can't be stopped.
6451                        try {
6452                            AppGlobals.getPackageManager().setPackageStoppedState(
6453                                    cpr.appInfo.packageName, false, userId);
6454                        } catch (RemoteException e) {
6455                        } catch (IllegalArgumentException e) {
6456                            Slog.w(TAG, "Failed trying to unstop package "
6457                                    + cpr.appInfo.packageName + ": " + e);
6458                        }
6459
6460                        ProcessRecord proc = startProcessLocked(cpi.processName,
6461                                cpr.appInfo, false, 0, "content provider",
6462                                new ComponentName(cpi.applicationInfo.packageName,
6463                                        cpi.name), false, false);
6464                        if (proc == null) {
6465                            Slog.w(TAG, "Unable to launch app "
6466                                    + cpi.applicationInfo.packageName + "/"
6467                                    + cpi.applicationInfo.uid + " for provider "
6468                                    + name + ": process is bad");
6469                            return null;
6470                        }
6471                        cpr.launchingApp = proc;
6472                        mLaunchingProviders.add(cpr);
6473                    } finally {
6474                        Binder.restoreCallingIdentity(origId);
6475                    }
6476                }
6477
6478                // Make sure the provider is published (the same provider class
6479                // may be published under multiple names).
6480                if (firstClass) {
6481                    mProviderMap.putProviderByClass(comp, cpr);
6482                }
6483
6484                mProviderMap.putProviderByName(name, cpr);
6485                conn = incProviderCountLocked(r, cpr, token, stable);
6486                if (conn != null) {
6487                    conn.waiting = true;
6488                }
6489            }
6490        }
6491
6492        // Wait for the provider to be published...
6493        synchronized (cpr) {
6494            while (cpr.provider == null) {
6495                if (cpr.launchingApp == null) {
6496                    Slog.w(TAG, "Unable to launch app "
6497                            + cpi.applicationInfo.packageName + "/"
6498                            + cpi.applicationInfo.uid + " for provider "
6499                            + name + ": launching app became null");
6500                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6501                            cpi.applicationInfo.packageName,
6502                            cpi.applicationInfo.uid, name);
6503                    return null;
6504                }
6505                try {
6506                    if (DEBUG_MU) {
6507                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6508                                + cpr.launchingApp);
6509                    }
6510                    if (conn != null) {
6511                        conn.waiting = true;
6512                    }
6513                    cpr.wait();
6514                } catch (InterruptedException ex) {
6515                } finally {
6516                    if (conn != null) {
6517                        conn.waiting = false;
6518                    }
6519                }
6520            }
6521        }
6522        return cpr != null ? cpr.newHolder(conn) : null;
6523    }
6524
6525    public final ContentProviderHolder getContentProvider(
6526            IApplicationThread caller, String name, boolean stable) {
6527        enforceNotIsolatedCaller("getContentProvider");
6528        if (caller == null) {
6529            String msg = "null IApplicationThread when getting content provider "
6530                    + name;
6531            Slog.w(TAG, msg);
6532            throw new SecurityException(msg);
6533        }
6534
6535        return getContentProviderImpl(caller, name, null, stable,
6536                UserHandle.getCallingUserId());
6537    }
6538
6539    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6540        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6541            "Do not have permission in call getContentProviderExternal()");
6542        return getContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6543    }
6544
6545    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6546            IBinder token, int userId) {
6547        return getContentProviderImpl(null, name, token, true, userId);
6548    }
6549
6550    /**
6551     * Drop a content provider from a ProcessRecord's bookkeeping
6552     * @param cpr
6553     */
6554    public void removeContentProvider(IBinder connection, boolean stable) {
6555        enforceNotIsolatedCaller("removeContentProvider");
6556        synchronized (this) {
6557            ContentProviderConnection conn;
6558            try {
6559                conn = (ContentProviderConnection)connection;
6560            } catch (ClassCastException e) {
6561                String msg ="removeContentProvider: " + connection
6562                        + " not a ContentProviderConnection";
6563                Slog.w(TAG, msg);
6564                throw new IllegalArgumentException(msg);
6565            }
6566            if (conn == null) {
6567                throw new NullPointerException("connection is null");
6568            }
6569            if (decProviderCountLocked(conn, null, null, stable)) {
6570                updateOomAdjLocked();
6571            }
6572        }
6573    }
6574
6575    public void removeContentProviderExternal(String name, IBinder token) {
6576        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6577            "Do not have permission in call removeContentProviderExternal()");
6578        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6579    }
6580
6581    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6582        synchronized (this) {
6583            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6584            if(cpr == null) {
6585                //remove from mProvidersByClass
6586                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6587                return;
6588            }
6589
6590            //update content provider record entry info
6591            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6592            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6593            if (localCpr.hasExternalProcessHandles()) {
6594                if (localCpr.removeExternalProcessHandleLocked(token)) {
6595                    updateOomAdjLocked();
6596                } else {
6597                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6598                            + " with no external reference for token: "
6599                            + token + ".");
6600                }
6601            } else {
6602                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6603                        + " with no external references.");
6604            }
6605        }
6606    }
6607
6608    public final void publishContentProviders(IApplicationThread caller,
6609            List<ContentProviderHolder> providers) {
6610        if (providers == null) {
6611            return;
6612        }
6613
6614        enforceNotIsolatedCaller("publishContentProviders");
6615        synchronized (this) {
6616            final ProcessRecord r = getRecordForAppLocked(caller);
6617            if (DEBUG_MU)
6618                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6619            if (r == null) {
6620                throw new SecurityException(
6621                        "Unable to find app for caller " + caller
6622                      + " (pid=" + Binder.getCallingPid()
6623                      + ") when publishing content providers");
6624            }
6625
6626            final long origId = Binder.clearCallingIdentity();
6627
6628            final int N = providers.size();
6629            for (int i=0; i<N; i++) {
6630                ContentProviderHolder src = providers.get(i);
6631                if (src == null || src.info == null || src.provider == null) {
6632                    continue;
6633                }
6634                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6635                if (DEBUG_MU)
6636                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6637                if (dst != null) {
6638                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6639                    mProviderMap.putProviderByClass(comp, dst);
6640                    String names[] = dst.info.authority.split(";");
6641                    for (int j = 0; j < names.length; j++) {
6642                        mProviderMap.putProviderByName(names[j], dst);
6643                    }
6644
6645                    int NL = mLaunchingProviders.size();
6646                    int j;
6647                    for (j=0; j<NL; j++) {
6648                        if (mLaunchingProviders.get(j) == dst) {
6649                            mLaunchingProviders.remove(j);
6650                            j--;
6651                            NL--;
6652                        }
6653                    }
6654                    synchronized (dst) {
6655                        dst.provider = src.provider;
6656                        dst.proc = r;
6657                        dst.notifyAll();
6658                    }
6659                    updateOomAdjLocked(r);
6660                }
6661            }
6662
6663            Binder.restoreCallingIdentity(origId);
6664        }
6665    }
6666
6667    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6668        ContentProviderConnection conn;
6669        try {
6670            conn = (ContentProviderConnection)connection;
6671        } catch (ClassCastException e) {
6672            String msg ="refContentProvider: " + connection
6673                    + " not a ContentProviderConnection";
6674            Slog.w(TAG, msg);
6675            throw new IllegalArgumentException(msg);
6676        }
6677        if (conn == null) {
6678            throw new NullPointerException("connection is null");
6679        }
6680
6681        synchronized (this) {
6682            if (stable > 0) {
6683                conn.numStableIncs += stable;
6684            }
6685            stable = conn.stableCount + stable;
6686            if (stable < 0) {
6687                throw new IllegalStateException("stableCount < 0: " + stable);
6688            }
6689
6690            if (unstable > 0) {
6691                conn.numUnstableIncs += unstable;
6692            }
6693            unstable = conn.unstableCount + unstable;
6694            if (unstable < 0) {
6695                throw new IllegalStateException("unstableCount < 0: " + unstable);
6696            }
6697
6698            if ((stable+unstable) <= 0) {
6699                throw new IllegalStateException("ref counts can't go to zero here: stable="
6700                        + stable + " unstable=" + unstable);
6701            }
6702            conn.stableCount = stable;
6703            conn.unstableCount = unstable;
6704            return !conn.dead;
6705        }
6706    }
6707
6708    public void unstableProviderDied(IBinder connection) {
6709        ContentProviderConnection conn;
6710        try {
6711            conn = (ContentProviderConnection)connection;
6712        } catch (ClassCastException e) {
6713            String msg ="refContentProvider: " + connection
6714                    + " not a ContentProviderConnection";
6715            Slog.w(TAG, msg);
6716            throw new IllegalArgumentException(msg);
6717        }
6718        if (conn == null) {
6719            throw new NullPointerException("connection is null");
6720        }
6721
6722        // Safely retrieve the content provider associated with the connection.
6723        IContentProvider provider;
6724        synchronized (this) {
6725            provider = conn.provider.provider;
6726        }
6727
6728        if (provider == null) {
6729            // Um, yeah, we're way ahead of you.
6730            return;
6731        }
6732
6733        // Make sure the caller is being honest with us.
6734        if (provider.asBinder().pingBinder()) {
6735            // Er, no, still looks good to us.
6736            synchronized (this) {
6737                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6738                        + " says " + conn + " died, but we don't agree");
6739                return;
6740            }
6741        }
6742
6743        // Well look at that!  It's dead!
6744        synchronized (this) {
6745            if (conn.provider.provider != provider) {
6746                // But something changed...  good enough.
6747                return;
6748            }
6749
6750            ProcessRecord proc = conn.provider.proc;
6751            if (proc == null || proc.thread == null) {
6752                // Seems like the process is already cleaned up.
6753                return;
6754            }
6755
6756            // As far as we're concerned, this is just like receiving a
6757            // death notification...  just a bit prematurely.
6758            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6759                    + ") early provider death");
6760            final long ident = Binder.clearCallingIdentity();
6761            try {
6762                appDiedLocked(proc, proc.pid, proc.thread);
6763            } finally {
6764                Binder.restoreCallingIdentity(ident);
6765            }
6766        }
6767    }
6768
6769    public static final void installSystemProviders() {
6770        List<ProviderInfo> providers;
6771        synchronized (mSelf) {
6772            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6773            providers = mSelf.generateApplicationProvidersLocked(app);
6774            if (providers != null) {
6775                for (int i=providers.size()-1; i>=0; i--) {
6776                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6777                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6778                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6779                                + ": not system .apk");
6780                        providers.remove(i);
6781                    }
6782                }
6783            }
6784        }
6785        if (providers != null) {
6786            mSystemThread.installSystemProviders(providers);
6787        }
6788
6789        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6790
6791        mSelf.mUsageStatsService.monitorPackages();
6792    }
6793
6794    /**
6795     * Allows app to retrieve the MIME type of a URI without having permission
6796     * to access its content provider.
6797     *
6798     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6799     *
6800     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6801     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6802     */
6803    public String getProviderMimeType(Uri uri) {
6804        enforceNotIsolatedCaller("getProviderMimeType");
6805        final String name = uri.getAuthority();
6806        final int userId = UserHandle.getCallingUserId();
6807        final long ident = Binder.clearCallingIdentity();
6808        ContentProviderHolder holder = null;
6809
6810        try {
6811            holder = getContentProviderExternalUnchecked(name, null, userId);
6812            if (holder != null) {
6813                return holder.provider.getType(uri);
6814            }
6815        } catch (RemoteException e) {
6816            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6817            return null;
6818        } finally {
6819            if (holder != null) {
6820                removeContentProviderExternalUnchecked(name, null, userId);
6821            }
6822            Binder.restoreCallingIdentity(ident);
6823        }
6824
6825        return null;
6826    }
6827
6828    // =========================================================
6829    // GLOBAL MANAGEMENT
6830    // =========================================================
6831
6832    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6833            ApplicationInfo info, String customProcess, boolean isolated) {
6834        String proc = customProcess != null ? customProcess : info.processName;
6835        BatteryStatsImpl.Uid.Proc ps = null;
6836        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6837        int uid = info.uid;
6838        if (isolated) {
6839            int userId = UserHandle.getUserId(uid);
6840            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6841            uid = 0;
6842            while (true) {
6843                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6844                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6845                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6846                }
6847                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6848                mNextIsolatedProcessUid++;
6849                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6850                    // No process for this uid, use it.
6851                    break;
6852                }
6853                stepsLeft--;
6854                if (stepsLeft <= 0) {
6855                    return null;
6856                }
6857            }
6858        }
6859        synchronized (stats) {
6860            ps = stats.getProcessStatsLocked(info.uid, proc);
6861        }
6862        return new ProcessRecord(ps, thread, info, proc, uid);
6863    }
6864
6865    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6866        ProcessRecord app;
6867        if (!isolated) {
6868            app = getProcessRecordLocked(info.processName, info.uid);
6869        } else {
6870            app = null;
6871        }
6872
6873        if (app == null) {
6874            app = newProcessRecordLocked(null, info, null, isolated);
6875            mProcessNames.put(info.processName, app.uid, app);
6876            if (isolated) {
6877                mIsolatedProcesses.put(app.uid, app);
6878            }
6879            updateLruProcessLocked(app, true, true);
6880        }
6881
6882        // This package really, really can not be stopped.
6883        try {
6884            AppGlobals.getPackageManager().setPackageStoppedState(
6885                    info.packageName, false, UserHandle.getUserId(app.uid));
6886        } catch (RemoteException e) {
6887        } catch (IllegalArgumentException e) {
6888            Slog.w(TAG, "Failed trying to unstop package "
6889                    + info.packageName + ": " + e);
6890        }
6891
6892        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6893                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6894            app.persistent = true;
6895            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6896        }
6897        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6898            mPersistentStartingProcesses.add(app);
6899            startProcessLocked(app, "added application", app.processName);
6900        }
6901
6902        return app;
6903    }
6904
6905    public void unhandledBack() {
6906        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6907                "unhandledBack()");
6908
6909        synchronized(this) {
6910            int count = mMainStack.mHistory.size();
6911            if (DEBUG_SWITCH) Slog.d(
6912                TAG, "Performing unhandledBack(): stack size = " + count);
6913            if (count > 1) {
6914                final long origId = Binder.clearCallingIdentity();
6915                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6916                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6917                Binder.restoreCallingIdentity(origId);
6918            }
6919        }
6920    }
6921
6922    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6923        enforceNotIsolatedCaller("openContentUri");
6924        final int userId = UserHandle.getCallingUserId();
6925        String name = uri.getAuthority();
6926        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
6927        ParcelFileDescriptor pfd = null;
6928        if (cph != null) {
6929            // We record the binder invoker's uid in thread-local storage before
6930            // going to the content provider to open the file.  Later, in the code
6931            // that handles all permissions checks, we look for this uid and use
6932            // that rather than the Activity Manager's own uid.  The effect is that
6933            // we do the check against the caller's permissions even though it looks
6934            // to the content provider like the Activity Manager itself is making
6935            // the request.
6936            sCallerIdentity.set(new Identity(
6937                    Binder.getCallingPid(), Binder.getCallingUid()));
6938            try {
6939                pfd = cph.provider.openFile(uri, "r");
6940            } catch (FileNotFoundException e) {
6941                // do nothing; pfd will be returned null
6942            } finally {
6943                // Ensure that whatever happens, we clean up the identity state
6944                sCallerIdentity.remove();
6945            }
6946
6947            // We've got the fd now, so we're done with the provider.
6948            removeContentProviderExternalUnchecked(name, null, userId);
6949        } else {
6950            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6951        }
6952        return pfd;
6953    }
6954
6955    // Actually is sleeping or shutting down or whatever else in the future
6956    // is an inactive state.
6957    public boolean isSleeping() {
6958        return mSleeping || mShuttingDown;
6959    }
6960
6961    public void goingToSleep() {
6962        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6963                != PackageManager.PERMISSION_GRANTED) {
6964            throw new SecurityException("Requires permission "
6965                    + android.Manifest.permission.DEVICE_POWER);
6966        }
6967
6968        synchronized(this) {
6969            mWentToSleep = true;
6970            updateEventDispatchingLocked();
6971
6972            if (!mSleeping) {
6973                mSleeping = true;
6974                mMainStack.stopIfSleepingLocked();
6975
6976                // Initialize the wake times of all processes.
6977                checkExcessivePowerUsageLocked(false);
6978                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6979                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6980                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6981            }
6982        }
6983    }
6984
6985    public boolean shutdown(int timeout) {
6986        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6987                != PackageManager.PERMISSION_GRANTED) {
6988            throw new SecurityException("Requires permission "
6989                    + android.Manifest.permission.SHUTDOWN);
6990        }
6991
6992        boolean timedout = false;
6993
6994        synchronized(this) {
6995            mShuttingDown = true;
6996            updateEventDispatchingLocked();
6997
6998            if (mMainStack.mResumedActivity != null) {
6999                mMainStack.stopIfSleepingLocked();
7000                final long endTime = System.currentTimeMillis() + timeout;
7001                while (mMainStack.mResumedActivity != null
7002                        || mMainStack.mPausingActivity != null) {
7003                    long delay = endTime - System.currentTimeMillis();
7004                    if (delay <= 0) {
7005                        Slog.w(TAG, "Activity manager shutdown timed out");
7006                        timedout = true;
7007                        break;
7008                    }
7009                    try {
7010                        this.wait();
7011                    } catch (InterruptedException e) {
7012                    }
7013                }
7014            }
7015        }
7016
7017        mUsageStatsService.shutdown();
7018        mBatteryStatsService.shutdown();
7019
7020        return timedout;
7021    }
7022
7023    public final void activitySlept(IBinder token) {
7024        if (localLOGV) Slog.v(
7025            TAG, "Activity slept: token=" + token);
7026
7027        ActivityRecord r = null;
7028
7029        final long origId = Binder.clearCallingIdentity();
7030
7031        synchronized (this) {
7032            r = mMainStack.isInStackLocked(token);
7033            if (r != null) {
7034                mMainStack.activitySleptLocked(r);
7035            }
7036        }
7037
7038        Binder.restoreCallingIdentity(origId);
7039    }
7040
7041    private void comeOutOfSleepIfNeededLocked() {
7042        if (!mWentToSleep && !mLockScreenShown) {
7043            if (mSleeping) {
7044                mSleeping = false;
7045                mMainStack.awakeFromSleepingLocked();
7046                mMainStack.resumeTopActivityLocked(null);
7047            }
7048        }
7049    }
7050
7051    public void wakingUp() {
7052        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7053                != PackageManager.PERMISSION_GRANTED) {
7054            throw new SecurityException("Requires permission "
7055                    + android.Manifest.permission.DEVICE_POWER);
7056        }
7057
7058        synchronized(this) {
7059            mWentToSleep = false;
7060            updateEventDispatchingLocked();
7061            comeOutOfSleepIfNeededLocked();
7062        }
7063    }
7064
7065    private void updateEventDispatchingLocked() {
7066        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7067    }
7068
7069    public void setLockScreenShown(boolean shown) {
7070        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7071                != PackageManager.PERMISSION_GRANTED) {
7072            throw new SecurityException("Requires permission "
7073                    + android.Manifest.permission.DEVICE_POWER);
7074        }
7075
7076        synchronized(this) {
7077            mLockScreenShown = shown;
7078            comeOutOfSleepIfNeededLocked();
7079        }
7080    }
7081
7082    public void stopAppSwitches() {
7083        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7084                != PackageManager.PERMISSION_GRANTED) {
7085            throw new SecurityException("Requires permission "
7086                    + android.Manifest.permission.STOP_APP_SWITCHES);
7087        }
7088
7089        synchronized(this) {
7090            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7091                    + APP_SWITCH_DELAY_TIME;
7092            mDidAppSwitch = false;
7093            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7094            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7095            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7096        }
7097    }
7098
7099    public void resumeAppSwitches() {
7100        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7101                != PackageManager.PERMISSION_GRANTED) {
7102            throw new SecurityException("Requires permission "
7103                    + android.Manifest.permission.STOP_APP_SWITCHES);
7104        }
7105
7106        synchronized(this) {
7107            // Note that we don't execute any pending app switches... we will
7108            // let those wait until either the timeout, or the next start
7109            // activity request.
7110            mAppSwitchesAllowedTime = 0;
7111        }
7112    }
7113
7114    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7115            String name) {
7116        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7117            return true;
7118        }
7119
7120        final int perm = checkComponentPermission(
7121                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7122                callingUid, -1, true);
7123        if (perm == PackageManager.PERMISSION_GRANTED) {
7124            return true;
7125        }
7126
7127        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7128        return false;
7129    }
7130
7131    public void setDebugApp(String packageName, boolean waitForDebugger,
7132            boolean persistent) {
7133        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7134                "setDebugApp()");
7135
7136        // Note that this is not really thread safe if there are multiple
7137        // callers into it at the same time, but that's not a situation we
7138        // care about.
7139        if (persistent) {
7140            final ContentResolver resolver = mContext.getContentResolver();
7141            Settings.System.putString(
7142                resolver, Settings.System.DEBUG_APP,
7143                packageName);
7144            Settings.System.putInt(
7145                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7146                waitForDebugger ? 1 : 0);
7147        }
7148
7149        synchronized (this) {
7150            if (!persistent) {
7151                mOrigDebugApp = mDebugApp;
7152                mOrigWaitForDebugger = mWaitForDebugger;
7153            }
7154            mDebugApp = packageName;
7155            mWaitForDebugger = waitForDebugger;
7156            mDebugTransient = !persistent;
7157            if (packageName != null) {
7158                final long origId = Binder.clearCallingIdentity();
7159                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
7160                Binder.restoreCallingIdentity(origId);
7161            }
7162        }
7163    }
7164
7165    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7166        synchronized (this) {
7167            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7168            if (!isDebuggable) {
7169                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7170                    throw new SecurityException("Process not debuggable: " + app.packageName);
7171                }
7172            }
7173
7174            mOpenGlTraceApp = processName;
7175        }
7176    }
7177
7178    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7179            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7180        synchronized (this) {
7181            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7182            if (!isDebuggable) {
7183                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7184                    throw new SecurityException("Process not debuggable: " + app.packageName);
7185                }
7186            }
7187            mProfileApp = processName;
7188            mProfileFile = profileFile;
7189            if (mProfileFd != null) {
7190                try {
7191                    mProfileFd.close();
7192                } catch (IOException e) {
7193                }
7194                mProfileFd = null;
7195            }
7196            mProfileFd = profileFd;
7197            mProfileType = 0;
7198            mAutoStopProfiler = autoStopProfiler;
7199        }
7200    }
7201
7202    public void setAlwaysFinish(boolean enabled) {
7203        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7204                "setAlwaysFinish()");
7205
7206        Settings.System.putInt(
7207                mContext.getContentResolver(),
7208                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7209
7210        synchronized (this) {
7211            mAlwaysFinishActivities = enabled;
7212        }
7213    }
7214
7215    public void setActivityController(IActivityController controller) {
7216        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7217                "setActivityController()");
7218        synchronized (this) {
7219            mController = controller;
7220        }
7221    }
7222
7223    public boolean isUserAMonkey() {
7224        // For now the fact that there is a controller implies
7225        // we have a monkey.
7226        synchronized (this) {
7227            return mController != null;
7228        }
7229    }
7230
7231    public void registerProcessObserver(IProcessObserver observer) {
7232        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7233                "registerProcessObserver()");
7234        synchronized (this) {
7235            mProcessObservers.register(observer);
7236        }
7237    }
7238
7239    public void unregisterProcessObserver(IProcessObserver observer) {
7240        synchronized (this) {
7241            mProcessObservers.unregister(observer);
7242        }
7243    }
7244
7245    public void setImmersive(IBinder token, boolean immersive) {
7246        synchronized(this) {
7247            ActivityRecord r = mMainStack.isInStackLocked(token);
7248            if (r == null) {
7249                throw new IllegalArgumentException();
7250            }
7251            r.immersive = immersive;
7252        }
7253    }
7254
7255    public boolean isImmersive(IBinder token) {
7256        synchronized (this) {
7257            ActivityRecord r = mMainStack.isInStackLocked(token);
7258            if (r == null) {
7259                throw new IllegalArgumentException();
7260            }
7261            return r.immersive;
7262        }
7263    }
7264
7265    public boolean isTopActivityImmersive() {
7266        enforceNotIsolatedCaller("startActivity");
7267        synchronized (this) {
7268            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7269            return (r != null) ? r.immersive : false;
7270        }
7271    }
7272
7273    public final void enterSafeMode() {
7274        synchronized(this) {
7275            // It only makes sense to do this before the system is ready
7276            // and started launching other packages.
7277            if (!mSystemReady) {
7278                try {
7279                    AppGlobals.getPackageManager().enterSafeMode();
7280                } catch (RemoteException e) {
7281                }
7282            }
7283        }
7284    }
7285
7286    public final void showSafeModeOverlay() {
7287        View v = LayoutInflater.from(mContext).inflate(
7288                com.android.internal.R.layout.safe_mode, null);
7289        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7290        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7291        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7292        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7293        lp.gravity = Gravity.BOTTOM | Gravity.START;
7294        lp.format = v.getBackground().getOpacity();
7295        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7296                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7297        ((WindowManager)mContext.getSystemService(
7298                Context.WINDOW_SERVICE)).addView(v, lp);
7299    }
7300
7301    public void noteWakeupAlarm(IIntentSender sender) {
7302        if (!(sender instanceof PendingIntentRecord)) {
7303            return;
7304        }
7305        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7306        synchronized (stats) {
7307            if (mBatteryStatsService.isOnBattery()) {
7308                mBatteryStatsService.enforceCallingPermission();
7309                PendingIntentRecord rec = (PendingIntentRecord)sender;
7310                int MY_UID = Binder.getCallingUid();
7311                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7312                BatteryStatsImpl.Uid.Pkg pkg =
7313                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7314                pkg.incWakeupsLocked();
7315            }
7316        }
7317    }
7318
7319    public boolean killPids(int[] pids, String pReason, boolean secure) {
7320        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7321            throw new SecurityException("killPids only available to the system");
7322        }
7323        String reason = (pReason == null) ? "Unknown" : pReason;
7324        // XXX Note: don't acquire main activity lock here, because the window
7325        // manager calls in with its locks held.
7326
7327        boolean killed = false;
7328        synchronized (mPidsSelfLocked) {
7329            int[] types = new int[pids.length];
7330            int worstType = 0;
7331            for (int i=0; i<pids.length; i++) {
7332                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7333                if (proc != null) {
7334                    int type = proc.setAdj;
7335                    types[i] = type;
7336                    if (type > worstType) {
7337                        worstType = type;
7338                    }
7339                }
7340            }
7341
7342            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7343            // then constrain it so we will kill all hidden procs.
7344            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7345                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7346                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7347            }
7348
7349            // If this is not a secure call, don't let it kill processes that
7350            // are important.
7351            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7352                worstType = ProcessList.SERVICE_ADJ;
7353            }
7354
7355            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7356            for (int i=0; i<pids.length; i++) {
7357                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7358                if (proc == null) {
7359                    continue;
7360                }
7361                int adj = proc.setAdj;
7362                if (adj >= worstType && !proc.killedBackground) {
7363                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7364                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7365                            proc.processName, adj, reason);
7366                    killed = true;
7367                    proc.killedBackground = true;
7368                    Process.killProcessQuiet(pids[i]);
7369                }
7370            }
7371        }
7372        return killed;
7373    }
7374
7375    @Override
7376    public boolean killProcessesBelowForeground(String reason) {
7377        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7378            throw new SecurityException("killProcessesBelowForeground() only available to system");
7379        }
7380
7381        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7382    }
7383
7384    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7385        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7386            throw new SecurityException("killProcessesBelowAdj() only available to system");
7387        }
7388
7389        boolean killed = false;
7390        synchronized (mPidsSelfLocked) {
7391            final int size = mPidsSelfLocked.size();
7392            for (int i = 0; i < size; i++) {
7393                final int pid = mPidsSelfLocked.keyAt(i);
7394                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7395                if (proc == null) continue;
7396
7397                final int adj = proc.setAdj;
7398                if (adj > belowAdj && !proc.killedBackground) {
7399                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7400                    EventLog.writeEvent(
7401                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7402                    killed = true;
7403                    proc.killedBackground = true;
7404                    Process.killProcessQuiet(pid);
7405                }
7406            }
7407        }
7408        return killed;
7409    }
7410
7411    public final void startRunning(String pkg, String cls, String action,
7412            String data) {
7413        synchronized(this) {
7414            if (mStartRunning) {
7415                return;
7416            }
7417            mStartRunning = true;
7418            mTopComponent = pkg != null && cls != null
7419                    ? new ComponentName(pkg, cls) : null;
7420            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7421            mTopData = data;
7422            if (!mSystemReady) {
7423                return;
7424            }
7425        }
7426
7427        systemReady(null);
7428    }
7429
7430    private void retrieveSettings() {
7431        final ContentResolver resolver = mContext.getContentResolver();
7432        String debugApp = Settings.System.getString(
7433            resolver, Settings.System.DEBUG_APP);
7434        boolean waitForDebugger = Settings.System.getInt(
7435            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7436        boolean alwaysFinishActivities = Settings.System.getInt(
7437            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7438
7439        Configuration configuration = new Configuration();
7440        Settings.System.getConfiguration(resolver, configuration);
7441
7442        synchronized (this) {
7443            mDebugApp = mOrigDebugApp = debugApp;
7444            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7445            mAlwaysFinishActivities = alwaysFinishActivities;
7446            // This happens before any activities are started, so we can
7447            // change mConfiguration in-place.
7448            updateConfigurationLocked(configuration, null, false, true);
7449            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7450        }
7451    }
7452
7453    public boolean testIsSystemReady() {
7454        // no need to synchronize(this) just to read & return the value
7455        return mSystemReady;
7456    }
7457
7458    private static File getCalledPreBootReceiversFile() {
7459        File dataDir = Environment.getDataDirectory();
7460        File systemDir = new File(dataDir, "system");
7461        File fname = new File(systemDir, "called_pre_boots.dat");
7462        return fname;
7463    }
7464
7465    static final int LAST_DONE_VERSION = 10000;
7466
7467    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7468        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7469        File file = getCalledPreBootReceiversFile();
7470        FileInputStream fis = null;
7471        try {
7472            fis = new FileInputStream(file);
7473            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7474            int fvers = dis.readInt();
7475            if (fvers == LAST_DONE_VERSION) {
7476                String vers = dis.readUTF();
7477                String codename = dis.readUTF();
7478                String build = dis.readUTF();
7479                if (android.os.Build.VERSION.RELEASE.equals(vers)
7480                        && android.os.Build.VERSION.CODENAME.equals(codename)
7481                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7482                    int num = dis.readInt();
7483                    while (num > 0) {
7484                        num--;
7485                        String pkg = dis.readUTF();
7486                        String cls = dis.readUTF();
7487                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7488                    }
7489                }
7490            }
7491        } catch (FileNotFoundException e) {
7492        } catch (IOException e) {
7493            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7494        } finally {
7495            if (fis != null) {
7496                try {
7497                    fis.close();
7498                } catch (IOException e) {
7499                }
7500            }
7501        }
7502        return lastDoneReceivers;
7503    }
7504
7505    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7506        File file = getCalledPreBootReceiversFile();
7507        FileOutputStream fos = null;
7508        DataOutputStream dos = null;
7509        try {
7510            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7511            fos = new FileOutputStream(file);
7512            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7513            dos.writeInt(LAST_DONE_VERSION);
7514            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7515            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7516            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7517            dos.writeInt(list.size());
7518            for (int i=0; i<list.size(); i++) {
7519                dos.writeUTF(list.get(i).getPackageName());
7520                dos.writeUTF(list.get(i).getClassName());
7521            }
7522        } catch (IOException e) {
7523            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7524            file.delete();
7525        } finally {
7526            FileUtils.sync(fos);
7527            if (dos != null) {
7528                try {
7529                    dos.close();
7530                } catch (IOException e) {
7531                    // TODO Auto-generated catch block
7532                    e.printStackTrace();
7533                }
7534            }
7535        }
7536    }
7537
7538    public void systemReady(final Runnable goingCallback) {
7539        synchronized(this) {
7540            if (mSystemReady) {
7541                if (goingCallback != null) goingCallback.run();
7542                return;
7543            }
7544
7545            // Check to see if there are any update receivers to run.
7546            if (!mDidUpdate) {
7547                if (mWaitingUpdate) {
7548                    return;
7549                }
7550                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7551                List<ResolveInfo> ris = null;
7552                try {
7553                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7554                            intent, null, 0, 0);
7555                } catch (RemoteException e) {
7556                }
7557                if (ris != null) {
7558                    for (int i=ris.size()-1; i>=0; i--) {
7559                        if ((ris.get(i).activityInfo.applicationInfo.flags
7560                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7561                            ris.remove(i);
7562                        }
7563                    }
7564                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7565
7566                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7567
7568                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7569                    for (int i=0; i<ris.size(); i++) {
7570                        ActivityInfo ai = ris.get(i).activityInfo;
7571                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7572                        if (lastDoneReceivers.contains(comp)) {
7573                            ris.remove(i);
7574                            i--;
7575                        }
7576                    }
7577
7578                    for (int i=0; i<ris.size(); i++) {
7579                        ActivityInfo ai = ris.get(i).activityInfo;
7580                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7581                        doneReceivers.add(comp);
7582                        intent.setComponent(comp);
7583                        IIntentReceiver finisher = null;
7584                        if (i == ris.size()-1) {
7585                            finisher = new IIntentReceiver.Stub() {
7586                                public void performReceive(Intent intent, int resultCode,
7587                                        String data, Bundle extras, boolean ordered,
7588                                        boolean sticky, int sendingUser) {
7589                                    // The raw IIntentReceiver interface is called
7590                                    // with the AM lock held, so redispatch to
7591                                    // execute our code without the lock.
7592                                    mHandler.post(new Runnable() {
7593                                        public void run() {
7594                                            synchronized (ActivityManagerService.this) {
7595                                                mDidUpdate = true;
7596                                            }
7597                                            writeLastDonePreBootReceivers(doneReceivers);
7598                                            showBootMessage(mContext.getText(
7599                                                    R.string.android_upgrading_complete),
7600                                                    false);
7601                                            systemReady(goingCallback);
7602                                        }
7603                                    });
7604                                }
7605                            };
7606                        }
7607                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7608                        // XXX also need to send this to stopped users(!!!)
7609                        broadcastIntentLocked(null, null, intent, null, finisher,
7610                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7611                                UserHandle.USER_ALL);
7612                        if (finisher != null) {
7613                            mWaitingUpdate = true;
7614                        }
7615                    }
7616                }
7617                if (mWaitingUpdate) {
7618                    return;
7619                }
7620                mDidUpdate = true;
7621            }
7622
7623            mSystemReady = true;
7624            if (!mStartRunning) {
7625                return;
7626            }
7627        }
7628
7629        ArrayList<ProcessRecord> procsToKill = null;
7630        synchronized(mPidsSelfLocked) {
7631            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7632                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7633                if (!isAllowedWhileBooting(proc.info)){
7634                    if (procsToKill == null) {
7635                        procsToKill = new ArrayList<ProcessRecord>();
7636                    }
7637                    procsToKill.add(proc);
7638                }
7639            }
7640        }
7641
7642        synchronized(this) {
7643            if (procsToKill != null) {
7644                for (int i=procsToKill.size()-1; i>=0; i--) {
7645                    ProcessRecord proc = procsToKill.get(i);
7646                    Slog.i(TAG, "Removing system update proc: " + proc);
7647                    removeProcessLocked(proc, true, false, "system update done");
7648                }
7649            }
7650
7651            // Now that we have cleaned up any update processes, we
7652            // are ready to start launching real processes and know that
7653            // we won't trample on them any more.
7654            mProcessesReady = true;
7655        }
7656
7657        Slog.i(TAG, "System now ready");
7658        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7659            SystemClock.uptimeMillis());
7660
7661        synchronized(this) {
7662            // Make sure we have no pre-ready processes sitting around.
7663
7664            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7665                ResolveInfo ri = mContext.getPackageManager()
7666                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7667                                STOCK_PM_FLAGS);
7668                CharSequence errorMsg = null;
7669                if (ri != null) {
7670                    ActivityInfo ai = ri.activityInfo;
7671                    ApplicationInfo app = ai.applicationInfo;
7672                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7673                        mTopAction = Intent.ACTION_FACTORY_TEST;
7674                        mTopData = null;
7675                        mTopComponent = new ComponentName(app.packageName,
7676                                ai.name);
7677                    } else {
7678                        errorMsg = mContext.getResources().getText(
7679                                com.android.internal.R.string.factorytest_not_system);
7680                    }
7681                } else {
7682                    errorMsg = mContext.getResources().getText(
7683                            com.android.internal.R.string.factorytest_no_action);
7684                }
7685                if (errorMsg != null) {
7686                    mTopAction = null;
7687                    mTopData = null;
7688                    mTopComponent = null;
7689                    Message msg = Message.obtain();
7690                    msg.what = SHOW_FACTORY_ERROR_MSG;
7691                    msg.getData().putCharSequence("msg", errorMsg);
7692                    mHandler.sendMessage(msg);
7693                }
7694            }
7695        }
7696
7697        retrieveSettings();
7698
7699        if (goingCallback != null) goingCallback.run();
7700
7701        synchronized (this) {
7702            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7703                try {
7704                    List apps = AppGlobals.getPackageManager().
7705                        getPersistentApplications(STOCK_PM_FLAGS);
7706                    if (apps != null) {
7707                        int N = apps.size();
7708                        int i;
7709                        for (i=0; i<N; i++) {
7710                            ApplicationInfo info
7711                                = (ApplicationInfo)apps.get(i);
7712                            if (info != null &&
7713                                    !info.packageName.equals("android")) {
7714                                addAppLocked(info, false);
7715                            }
7716                        }
7717                    }
7718                } catch (RemoteException ex) {
7719                    // pm is in same process, this will never happen.
7720                }
7721            }
7722
7723            // Start up initial activity.
7724            mBooting = true;
7725
7726            try {
7727                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7728                    Message msg = Message.obtain();
7729                    msg.what = SHOW_UID_ERROR_MSG;
7730                    mHandler.sendMessage(msg);
7731                }
7732            } catch (RemoteException e) {
7733            }
7734
7735            mMainStack.resumeTopActivityLocked(null);
7736        }
7737    }
7738
7739    private boolean makeAppCrashingLocked(ProcessRecord app,
7740            String shortMsg, String longMsg, String stackTrace) {
7741        app.crashing = true;
7742        app.crashingReport = generateProcessError(app,
7743                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7744        startAppProblemLocked(app);
7745        app.stopFreezingAllLocked();
7746        return handleAppCrashLocked(app);
7747    }
7748
7749    private void makeAppNotRespondingLocked(ProcessRecord app,
7750            String activity, String shortMsg, String longMsg) {
7751        app.notResponding = true;
7752        app.notRespondingReport = generateProcessError(app,
7753                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7754                activity, shortMsg, longMsg, null);
7755        startAppProblemLocked(app);
7756        app.stopFreezingAllLocked();
7757    }
7758
7759    /**
7760     * Generate a process error record, suitable for attachment to a ProcessRecord.
7761     *
7762     * @param app The ProcessRecord in which the error occurred.
7763     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7764     *                      ActivityManager.AppErrorStateInfo
7765     * @param activity The activity associated with the crash, if known.
7766     * @param shortMsg Short message describing the crash.
7767     * @param longMsg Long message describing the crash.
7768     * @param stackTrace Full crash stack trace, may be null.
7769     *
7770     * @return Returns a fully-formed AppErrorStateInfo record.
7771     */
7772    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7773            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7774        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7775
7776        report.condition = condition;
7777        report.processName = app.processName;
7778        report.pid = app.pid;
7779        report.uid = app.info.uid;
7780        report.tag = activity;
7781        report.shortMsg = shortMsg;
7782        report.longMsg = longMsg;
7783        report.stackTrace = stackTrace;
7784
7785        return report;
7786    }
7787
7788    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7789        synchronized (this) {
7790            app.crashing = false;
7791            app.crashingReport = null;
7792            app.notResponding = false;
7793            app.notRespondingReport = null;
7794            if (app.anrDialog == fromDialog) {
7795                app.anrDialog = null;
7796            }
7797            if (app.waitDialog == fromDialog) {
7798                app.waitDialog = null;
7799            }
7800            if (app.pid > 0 && app.pid != MY_PID) {
7801                handleAppCrashLocked(app);
7802                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7803                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7804                        app.processName, app.setAdj, "user's request after error");
7805                Process.killProcessQuiet(app.pid);
7806            }
7807        }
7808    }
7809
7810    private boolean handleAppCrashLocked(ProcessRecord app) {
7811        if (mHeadless) {
7812            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7813            return false;
7814        }
7815        long now = SystemClock.uptimeMillis();
7816
7817        Long crashTime;
7818        if (!app.isolated) {
7819            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7820        } else {
7821            crashTime = null;
7822        }
7823        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7824            // This process loses!
7825            Slog.w(TAG, "Process " + app.info.processName
7826                    + " has crashed too many times: killing!");
7827            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7828                    app.info.processName, app.uid);
7829            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7830                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7831                if (r.app == app) {
7832                    Slog.w(TAG, "  Force finishing activity "
7833                        + r.intent.getComponent().flattenToShortString());
7834                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7835                }
7836            }
7837            if (!app.persistent) {
7838                // We don't want to start this process again until the user
7839                // explicitly does so...  but for persistent process, we really
7840                // need to keep it running.  If a persistent process is actually
7841                // repeatedly crashing, then badness for everyone.
7842                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7843                        app.info.processName);
7844                if (!app.isolated) {
7845                    // XXX We don't have a way to mark isolated processes
7846                    // as bad, since they don't have a peristent identity.
7847                    mBadProcesses.put(app.info.processName, app.uid, now);
7848                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7849                }
7850                app.bad = true;
7851                app.removed = true;
7852                // Don't let services in this process be restarted and potentially
7853                // annoy the user repeatedly.  Unless it is persistent, since those
7854                // processes run critical code.
7855                removeProcessLocked(app, false, false, "crash");
7856                mMainStack.resumeTopActivityLocked(null);
7857                return false;
7858            }
7859            mMainStack.resumeTopActivityLocked(null);
7860        } else {
7861            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7862            if (r != null && r.app == app) {
7863                // If the top running activity is from this crashing
7864                // process, then terminate it to avoid getting in a loop.
7865                Slog.w(TAG, "  Force finishing activity "
7866                        + r.intent.getComponent().flattenToShortString());
7867                int index = mMainStack.indexOfActivityLocked(r);
7868                r.stack.finishActivityLocked(r, index,
7869                        Activity.RESULT_CANCELED, null, "crashed");
7870                // Also terminate any activities below it that aren't yet
7871                // stopped, to avoid a situation where one will get
7872                // re-start our crashing activity once it gets resumed again.
7873                index--;
7874                if (index >= 0) {
7875                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7876                    if (r.state == ActivityState.RESUMED
7877                            || r.state == ActivityState.PAUSING
7878                            || r.state == ActivityState.PAUSED) {
7879                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7880                            Slog.w(TAG, "  Force finishing activity "
7881                                    + r.intent.getComponent().flattenToShortString());
7882                            r.stack.finishActivityLocked(r, index,
7883                                    Activity.RESULT_CANCELED, null, "crashed");
7884                        }
7885                    }
7886                }
7887            }
7888        }
7889
7890        // Bump up the crash count of any services currently running in the proc.
7891        if (app.services.size() != 0) {
7892            // Any services running in the application need to be placed
7893            // back in the pending list.
7894            Iterator<ServiceRecord> it = app.services.iterator();
7895            while (it.hasNext()) {
7896                ServiceRecord sr = it.next();
7897                sr.crashCount++;
7898            }
7899        }
7900
7901        // If the crashing process is what we consider to be the "home process" and it has been
7902        // replaced by a third-party app, clear the package preferred activities from packages
7903        // with a home activity running in the process to prevent a repeatedly crashing app
7904        // from blocking the user to manually clear the list.
7905        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7906                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7907            Iterator it = mHomeProcess.activities.iterator();
7908            while (it.hasNext()) {
7909                ActivityRecord r = (ActivityRecord)it.next();
7910                if (r.isHomeActivity) {
7911                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7912                    try {
7913                        ActivityThread.getPackageManager()
7914                                .clearPackagePreferredActivities(r.packageName);
7915                    } catch (RemoteException c) {
7916                        // pm is in same process, this will never happen.
7917                    }
7918                }
7919            }
7920        }
7921
7922        if (!app.isolated) {
7923            // XXX Can't keep track of crash times for isolated processes,
7924            // because they don't have a perisistent identity.
7925            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7926        }
7927
7928        return true;
7929    }
7930
7931    void startAppProblemLocked(ProcessRecord app) {
7932        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7933                mContext, app.info.packageName, app.info.flags);
7934        skipCurrentReceiverLocked(app);
7935    }
7936
7937    void skipCurrentReceiverLocked(ProcessRecord app) {
7938        for (BroadcastQueue queue : mBroadcastQueues) {
7939            queue.skipCurrentReceiverLocked(app);
7940        }
7941    }
7942
7943    /**
7944     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7945     * The application process will exit immediately after this call returns.
7946     * @param app object of the crashing app, null for the system server
7947     * @param crashInfo describing the exception
7948     */
7949    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7950        ProcessRecord r = findAppProcess(app, "Crash");
7951        final String processName = app == null ? "system_server"
7952                : (r == null ? "unknown" : r.processName);
7953
7954        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7955                processName,
7956                r == null ? -1 : r.info.flags,
7957                crashInfo.exceptionClassName,
7958                crashInfo.exceptionMessage,
7959                crashInfo.throwFileName,
7960                crashInfo.throwLineNumber);
7961
7962        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7963
7964        crashApplication(r, crashInfo);
7965    }
7966
7967    public void handleApplicationStrictModeViolation(
7968            IBinder app,
7969            int violationMask,
7970            StrictMode.ViolationInfo info) {
7971        ProcessRecord r = findAppProcess(app, "StrictMode");
7972        if (r == null) {
7973            return;
7974        }
7975
7976        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7977            Integer stackFingerprint = info.hashCode();
7978            boolean logIt = true;
7979            synchronized (mAlreadyLoggedViolatedStacks) {
7980                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7981                    logIt = false;
7982                    // TODO: sub-sample into EventLog for these, with
7983                    // the info.durationMillis?  Then we'd get
7984                    // the relative pain numbers, without logging all
7985                    // the stack traces repeatedly.  We'd want to do
7986                    // likewise in the client code, which also does
7987                    // dup suppression, before the Binder call.
7988                } else {
7989                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7990                        mAlreadyLoggedViolatedStacks.clear();
7991                    }
7992                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7993                }
7994            }
7995            if (logIt) {
7996                logStrictModeViolationToDropBox(r, info);
7997            }
7998        }
7999
8000        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8001            AppErrorResult result = new AppErrorResult();
8002            synchronized (this) {
8003                final long origId = Binder.clearCallingIdentity();
8004
8005                Message msg = Message.obtain();
8006                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8007                HashMap<String, Object> data = new HashMap<String, Object>();
8008                data.put("result", result);
8009                data.put("app", r);
8010                data.put("violationMask", violationMask);
8011                data.put("info", info);
8012                msg.obj = data;
8013                mHandler.sendMessage(msg);
8014
8015                Binder.restoreCallingIdentity(origId);
8016            }
8017            int res = result.get();
8018            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8019        }
8020    }
8021
8022    // Depending on the policy in effect, there could be a bunch of
8023    // these in quick succession so we try to batch these together to
8024    // minimize disk writes, number of dropbox entries, and maximize
8025    // compression, by having more fewer, larger records.
8026    private void logStrictModeViolationToDropBox(
8027            ProcessRecord process,
8028            StrictMode.ViolationInfo info) {
8029        if (info == null) {
8030            return;
8031        }
8032        final boolean isSystemApp = process == null ||
8033                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8034                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8035        final String processName = process == null ? "unknown" : process.processName;
8036        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8037        final DropBoxManager dbox = (DropBoxManager)
8038                mContext.getSystemService(Context.DROPBOX_SERVICE);
8039
8040        // Exit early if the dropbox isn't configured to accept this report type.
8041        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8042
8043        boolean bufferWasEmpty;
8044        boolean needsFlush;
8045        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8046        synchronized (sb) {
8047            bufferWasEmpty = sb.length() == 0;
8048            appendDropBoxProcessHeaders(process, processName, sb);
8049            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8050            sb.append("System-App: ").append(isSystemApp).append("\n");
8051            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8052            if (info.violationNumThisLoop != 0) {
8053                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8054            }
8055            if (info.numAnimationsRunning != 0) {
8056                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8057            }
8058            if (info.broadcastIntentAction != null) {
8059                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8060            }
8061            if (info.durationMillis != -1) {
8062                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8063            }
8064            if (info.numInstances != -1) {
8065                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8066            }
8067            if (info.tags != null) {
8068                for (String tag : info.tags) {
8069                    sb.append("Span-Tag: ").append(tag).append("\n");
8070                }
8071            }
8072            sb.append("\n");
8073            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8074                sb.append(info.crashInfo.stackTrace);
8075            }
8076            sb.append("\n");
8077
8078            // Only buffer up to ~64k.  Various logging bits truncate
8079            // things at 128k.
8080            needsFlush = (sb.length() > 64 * 1024);
8081        }
8082
8083        // Flush immediately if the buffer's grown too large, or this
8084        // is a non-system app.  Non-system apps are isolated with a
8085        // different tag & policy and not batched.
8086        //
8087        // Batching is useful during internal testing with
8088        // StrictMode settings turned up high.  Without batching,
8089        // thousands of separate files could be created on boot.
8090        if (!isSystemApp || needsFlush) {
8091            new Thread("Error dump: " + dropboxTag) {
8092                @Override
8093                public void run() {
8094                    String report;
8095                    synchronized (sb) {
8096                        report = sb.toString();
8097                        sb.delete(0, sb.length());
8098                        sb.trimToSize();
8099                    }
8100                    if (report.length() != 0) {
8101                        dbox.addText(dropboxTag, report);
8102                    }
8103                }
8104            }.start();
8105            return;
8106        }
8107
8108        // System app batching:
8109        if (!bufferWasEmpty) {
8110            // An existing dropbox-writing thread is outstanding, so
8111            // we don't need to start it up.  The existing thread will
8112            // catch the buffer appends we just did.
8113            return;
8114        }
8115
8116        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8117        // (After this point, we shouldn't access AMS internal data structures.)
8118        new Thread("Error dump: " + dropboxTag) {
8119            @Override
8120            public void run() {
8121                // 5 second sleep to let stacks arrive and be batched together
8122                try {
8123                    Thread.sleep(5000);  // 5 seconds
8124                } catch (InterruptedException e) {}
8125
8126                String errorReport;
8127                synchronized (mStrictModeBuffer) {
8128                    errorReport = mStrictModeBuffer.toString();
8129                    if (errorReport.length() == 0) {
8130                        return;
8131                    }
8132                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8133                    mStrictModeBuffer.trimToSize();
8134                }
8135                dbox.addText(dropboxTag, errorReport);
8136            }
8137        }.start();
8138    }
8139
8140    /**
8141     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8142     * @param app object of the crashing app, null for the system server
8143     * @param tag reported by the caller
8144     * @param crashInfo describing the context of the error
8145     * @return true if the process should exit immediately (WTF is fatal)
8146     */
8147    public boolean handleApplicationWtf(IBinder app, String tag,
8148            ApplicationErrorReport.CrashInfo crashInfo) {
8149        ProcessRecord r = findAppProcess(app, "WTF");
8150        final String processName = app == null ? "system_server"
8151                : (r == null ? "unknown" : r.processName);
8152
8153        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8154                processName,
8155                r == null ? -1 : r.info.flags,
8156                tag, crashInfo.exceptionMessage);
8157
8158        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8159
8160        if (r != null && r.pid != Process.myPid() &&
8161                Settings.Secure.getInt(mContext.getContentResolver(),
8162                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8163            crashApplication(r, crashInfo);
8164            return true;
8165        } else {
8166            return false;
8167        }
8168    }
8169
8170    /**
8171     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8172     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8173     */
8174    private ProcessRecord findAppProcess(IBinder app, String reason) {
8175        if (app == null) {
8176            return null;
8177        }
8178
8179        synchronized (this) {
8180            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8181                final int NA = apps.size();
8182                for (int ia=0; ia<NA; ia++) {
8183                    ProcessRecord p = apps.valueAt(ia);
8184                    if (p.thread != null && p.thread.asBinder() == app) {
8185                        return p;
8186                    }
8187                }
8188            }
8189
8190            Slog.w(TAG, "Can't find mystery application for " + reason
8191                    + " from pid=" + Binder.getCallingPid()
8192                    + " uid=" + Binder.getCallingUid() + ": " + app);
8193            return null;
8194        }
8195    }
8196
8197    /**
8198     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8199     * to append various headers to the dropbox log text.
8200     */
8201    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8202            StringBuilder sb) {
8203        // Watchdog thread ends up invoking this function (with
8204        // a null ProcessRecord) to add the stack file to dropbox.
8205        // Do not acquire a lock on this (am) in such cases, as it
8206        // could cause a potential deadlock, if and when watchdog
8207        // is invoked due to unavailability of lock on am and it
8208        // would prevent watchdog from killing system_server.
8209        if (process == null) {
8210            sb.append("Process: ").append(processName).append("\n");
8211            return;
8212        }
8213        // Note: ProcessRecord 'process' is guarded by the service
8214        // instance.  (notably process.pkgList, which could otherwise change
8215        // concurrently during execution of this method)
8216        synchronized (this) {
8217            sb.append("Process: ").append(processName).append("\n");
8218            int flags = process.info.flags;
8219            IPackageManager pm = AppGlobals.getPackageManager();
8220            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8221            for (String pkg : process.pkgList) {
8222                sb.append("Package: ").append(pkg);
8223                try {
8224                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8225                    if (pi != null) {
8226                        sb.append(" v").append(pi.versionCode);
8227                        if (pi.versionName != null) {
8228                            sb.append(" (").append(pi.versionName).append(")");
8229                        }
8230                    }
8231                } catch (RemoteException e) {
8232                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8233                }
8234                sb.append("\n");
8235            }
8236        }
8237    }
8238
8239    private static String processClass(ProcessRecord process) {
8240        if (process == null || process.pid == MY_PID) {
8241            return "system_server";
8242        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8243            return "system_app";
8244        } else {
8245            return "data_app";
8246        }
8247    }
8248
8249    /**
8250     * Write a description of an error (crash, WTF, ANR) to the drop box.
8251     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8252     * @param process which caused the error, null means the system server
8253     * @param activity which triggered the error, null if unknown
8254     * @param parent activity related to the error, null if unknown
8255     * @param subject line related to the error, null if absent
8256     * @param report in long form describing the error, null if absent
8257     * @param logFile to include in the report, null if none
8258     * @param crashInfo giving an application stack trace, null if absent
8259     */
8260    public void addErrorToDropBox(String eventType,
8261            ProcessRecord process, String processName, ActivityRecord activity,
8262            ActivityRecord parent, String subject,
8263            final String report, final File logFile,
8264            final ApplicationErrorReport.CrashInfo crashInfo) {
8265        // NOTE -- this must never acquire the ActivityManagerService lock,
8266        // otherwise the watchdog may be prevented from resetting the system.
8267
8268        final String dropboxTag = processClass(process) + "_" + eventType;
8269        final DropBoxManager dbox = (DropBoxManager)
8270                mContext.getSystemService(Context.DROPBOX_SERVICE);
8271
8272        // Exit early if the dropbox isn't configured to accept this report type.
8273        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8274
8275        final StringBuilder sb = new StringBuilder(1024);
8276        appendDropBoxProcessHeaders(process, processName, sb);
8277        if (activity != null) {
8278            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8279        }
8280        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8281            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8282        }
8283        if (parent != null && parent != activity) {
8284            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8285        }
8286        if (subject != null) {
8287            sb.append("Subject: ").append(subject).append("\n");
8288        }
8289        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8290        if (Debug.isDebuggerConnected()) {
8291            sb.append("Debugger: Connected\n");
8292        }
8293        sb.append("\n");
8294
8295        // Do the rest in a worker thread to avoid blocking the caller on I/O
8296        // (After this point, we shouldn't access AMS internal data structures.)
8297        Thread worker = new Thread("Error dump: " + dropboxTag) {
8298            @Override
8299            public void run() {
8300                if (report != null) {
8301                    sb.append(report);
8302                }
8303                if (logFile != null) {
8304                    try {
8305                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8306                    } catch (IOException e) {
8307                        Slog.e(TAG, "Error reading " + logFile, e);
8308                    }
8309                }
8310                if (crashInfo != null && crashInfo.stackTrace != null) {
8311                    sb.append(crashInfo.stackTrace);
8312                }
8313
8314                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8315                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8316                if (lines > 0) {
8317                    sb.append("\n");
8318
8319                    // Merge several logcat streams, and take the last N lines
8320                    InputStreamReader input = null;
8321                    try {
8322                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8323                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8324                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8325
8326                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8327                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8328                        input = new InputStreamReader(logcat.getInputStream());
8329
8330                        int num;
8331                        char[] buf = new char[8192];
8332                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8333                    } catch (IOException e) {
8334                        Slog.e(TAG, "Error running logcat", e);
8335                    } finally {
8336                        if (input != null) try { input.close(); } catch (IOException e) {}
8337                    }
8338                }
8339
8340                dbox.addText(dropboxTag, sb.toString());
8341            }
8342        };
8343
8344        if (process == null) {
8345            // If process is null, we are being called from some internal code
8346            // and may be about to die -- run this synchronously.
8347            worker.run();
8348        } else {
8349            worker.start();
8350        }
8351    }
8352
8353    /**
8354     * Bring up the "unexpected error" dialog box for a crashing app.
8355     * Deal with edge cases (intercepts from instrumented applications,
8356     * ActivityController, error intent receivers, that sort of thing).
8357     * @param r the application crashing
8358     * @param crashInfo describing the failure
8359     */
8360    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8361        long timeMillis = System.currentTimeMillis();
8362        String shortMsg = crashInfo.exceptionClassName;
8363        String longMsg = crashInfo.exceptionMessage;
8364        String stackTrace = crashInfo.stackTrace;
8365        if (shortMsg != null && longMsg != null) {
8366            longMsg = shortMsg + ": " + longMsg;
8367        } else if (shortMsg != null) {
8368            longMsg = shortMsg;
8369        }
8370
8371        AppErrorResult result = new AppErrorResult();
8372        synchronized (this) {
8373            if (mController != null) {
8374                try {
8375                    String name = r != null ? r.processName : null;
8376                    int pid = r != null ? r.pid : Binder.getCallingPid();
8377                    if (!mController.appCrashed(name, pid,
8378                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8379                        Slog.w(TAG, "Force-killing crashed app " + name
8380                                + " at watcher's request");
8381                        Process.killProcess(pid);
8382                        return;
8383                    }
8384                } catch (RemoteException e) {
8385                    mController = null;
8386                }
8387            }
8388
8389            final long origId = Binder.clearCallingIdentity();
8390
8391            // If this process is running instrumentation, finish it.
8392            if (r != null && r.instrumentationClass != null) {
8393                Slog.w(TAG, "Error in app " + r.processName
8394                      + " running instrumentation " + r.instrumentationClass + ":");
8395                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8396                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8397                Bundle info = new Bundle();
8398                info.putString("shortMsg", shortMsg);
8399                info.putString("longMsg", longMsg);
8400                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8401                Binder.restoreCallingIdentity(origId);
8402                return;
8403            }
8404
8405            // If we can't identify the process or it's already exceeded its crash quota,
8406            // quit right away without showing a crash dialog.
8407            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8408                Binder.restoreCallingIdentity(origId);
8409                return;
8410            }
8411
8412            Message msg = Message.obtain();
8413            msg.what = SHOW_ERROR_MSG;
8414            HashMap data = new HashMap();
8415            data.put("result", result);
8416            data.put("app", r);
8417            msg.obj = data;
8418            mHandler.sendMessage(msg);
8419
8420            Binder.restoreCallingIdentity(origId);
8421        }
8422
8423        int res = result.get();
8424
8425        Intent appErrorIntent = null;
8426        synchronized (this) {
8427            if (r != null && !r.isolated) {
8428                // XXX Can't keep track of crash time for isolated processes,
8429                // since they don't have a persistent identity.
8430                mProcessCrashTimes.put(r.info.processName, r.uid,
8431                        SystemClock.uptimeMillis());
8432            }
8433            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8434                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8435            }
8436        }
8437
8438        if (appErrorIntent != null) {
8439            try {
8440                mContext.startActivity(appErrorIntent);
8441            } catch (ActivityNotFoundException e) {
8442                Slog.w(TAG, "bug report receiver dissappeared", e);
8443            }
8444        }
8445    }
8446
8447    Intent createAppErrorIntentLocked(ProcessRecord r,
8448            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8449        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8450        if (report == null) {
8451            return null;
8452        }
8453        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8454        result.setComponent(r.errorReportReceiver);
8455        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8456        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8457        return result;
8458    }
8459
8460    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8461            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8462        if (r.errorReportReceiver == null) {
8463            return null;
8464        }
8465
8466        if (!r.crashing && !r.notResponding) {
8467            return null;
8468        }
8469
8470        ApplicationErrorReport report = new ApplicationErrorReport();
8471        report.packageName = r.info.packageName;
8472        report.installerPackageName = r.errorReportReceiver.getPackageName();
8473        report.processName = r.processName;
8474        report.time = timeMillis;
8475        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8476
8477        if (r.crashing) {
8478            report.type = ApplicationErrorReport.TYPE_CRASH;
8479            report.crashInfo = crashInfo;
8480        } else if (r.notResponding) {
8481            report.type = ApplicationErrorReport.TYPE_ANR;
8482            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8483
8484            report.anrInfo.activity = r.notRespondingReport.tag;
8485            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8486            report.anrInfo.info = r.notRespondingReport.longMsg;
8487        }
8488
8489        return report;
8490    }
8491
8492    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8493        enforceNotIsolatedCaller("getProcessesInErrorState");
8494        // assume our apps are happy - lazy create the list
8495        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8496
8497        final boolean allUsers = ActivityManager.checkUidPermission(
8498                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8499                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8500        int userId = UserHandle.getUserId(Binder.getCallingUid());
8501
8502        synchronized (this) {
8503
8504            // iterate across all processes
8505            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8506                ProcessRecord app = mLruProcesses.get(i);
8507                if (!allUsers && app.userId != userId) {
8508                    continue;
8509                }
8510                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8511                    // This one's in trouble, so we'll generate a report for it
8512                    // crashes are higher priority (in case there's a crash *and* an anr)
8513                    ActivityManager.ProcessErrorStateInfo report = null;
8514                    if (app.crashing) {
8515                        report = app.crashingReport;
8516                    } else if (app.notResponding) {
8517                        report = app.notRespondingReport;
8518                    }
8519
8520                    if (report != null) {
8521                        if (errList == null) {
8522                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8523                        }
8524                        errList.add(report);
8525                    } else {
8526                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8527                                " crashing = " + app.crashing +
8528                                " notResponding = " + app.notResponding);
8529                    }
8530                }
8531            }
8532        }
8533
8534        return errList;
8535    }
8536
8537    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8538        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8539            if (currApp != null) {
8540                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8541            }
8542            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8543        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8544            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8545        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8546            if (currApp != null) {
8547                currApp.lru = 0;
8548            }
8549            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8550        } else if (adj >= ProcessList.SERVICE_ADJ) {
8551            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8552        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8553            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8554        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8555            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8556        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8557            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8558        } else {
8559            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8560        }
8561    }
8562
8563    private void fillInProcMemInfo(ProcessRecord app,
8564            ActivityManager.RunningAppProcessInfo outInfo) {
8565        outInfo.pid = app.pid;
8566        outInfo.uid = app.info.uid;
8567        if (mHeavyWeightProcess == app) {
8568            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8569        }
8570        if (app.persistent) {
8571            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8572        }
8573        if (app.hasActivities) {
8574            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8575        }
8576        outInfo.lastTrimLevel = app.trimMemoryLevel;
8577        int adj = app.curAdj;
8578        outInfo.importance = oomAdjToImportance(adj, outInfo);
8579        outInfo.importanceReasonCode = app.adjTypeCode;
8580    }
8581
8582    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8583        enforceNotIsolatedCaller("getRunningAppProcesses");
8584        // Lazy instantiation of list
8585        List<ActivityManager.RunningAppProcessInfo> runList = null;
8586        final boolean allUsers = ActivityManager.checkUidPermission(
8587                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8588                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8589        int userId = UserHandle.getUserId(Binder.getCallingUid());
8590        synchronized (this) {
8591            // Iterate across all processes
8592            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8593                ProcessRecord app = mLruProcesses.get(i);
8594                if (!allUsers && app.userId != userId) {
8595                    continue;
8596                }
8597                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8598                    // Generate process state info for running application
8599                    ActivityManager.RunningAppProcessInfo currApp =
8600                        new ActivityManager.RunningAppProcessInfo(app.processName,
8601                                app.pid, app.getPackageList());
8602                    fillInProcMemInfo(app, currApp);
8603                    if (app.adjSource instanceof ProcessRecord) {
8604                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8605                        currApp.importanceReasonImportance = oomAdjToImportance(
8606                                app.adjSourceOom, null);
8607                    } else if (app.adjSource instanceof ActivityRecord) {
8608                        ActivityRecord r = (ActivityRecord)app.adjSource;
8609                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8610                    }
8611                    if (app.adjTarget instanceof ComponentName) {
8612                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8613                    }
8614                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8615                    //        + " lru=" + currApp.lru);
8616                    if (runList == null) {
8617                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8618                    }
8619                    runList.add(currApp);
8620                }
8621            }
8622        }
8623        return runList;
8624    }
8625
8626    public List<ApplicationInfo> getRunningExternalApplications() {
8627        enforceNotIsolatedCaller("getRunningExternalApplications");
8628        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8629        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8630        if (runningApps != null && runningApps.size() > 0) {
8631            Set<String> extList = new HashSet<String>();
8632            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8633                if (app.pkgList != null) {
8634                    for (String pkg : app.pkgList) {
8635                        extList.add(pkg);
8636                    }
8637                }
8638            }
8639            IPackageManager pm = AppGlobals.getPackageManager();
8640            for (String pkg : extList) {
8641                try {
8642                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8643                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8644                        retList.add(info);
8645                    }
8646                } catch (RemoteException e) {
8647                }
8648            }
8649        }
8650        return retList;
8651    }
8652
8653    @Override
8654    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8655        enforceNotIsolatedCaller("getMyMemoryState");
8656        synchronized (this) {
8657            ProcessRecord proc;
8658            synchronized (mPidsSelfLocked) {
8659                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8660            }
8661            fillInProcMemInfo(proc, outInfo);
8662        }
8663    }
8664
8665    @Override
8666    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8667        if (checkCallingPermission(android.Manifest.permission.DUMP)
8668                != PackageManager.PERMISSION_GRANTED) {
8669            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8670                    + Binder.getCallingPid()
8671                    + ", uid=" + Binder.getCallingUid()
8672                    + " without permission "
8673                    + android.Manifest.permission.DUMP);
8674            return;
8675        }
8676
8677        boolean dumpAll = false;
8678        boolean dumpClient = false;
8679        String dumpPackage = null;
8680
8681        int opti = 0;
8682        while (opti < args.length) {
8683            String opt = args[opti];
8684            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8685                break;
8686            }
8687            opti++;
8688            if ("-a".equals(opt)) {
8689                dumpAll = true;
8690            } else if ("-c".equals(opt)) {
8691                dumpClient = true;
8692            } else if ("-h".equals(opt)) {
8693                pw.println("Activity manager dump options:");
8694                pw.println("  [-a] [-c] [-h] [cmd] ...");
8695                pw.println("  cmd may be one of:");
8696                pw.println("    a[ctivities]: activity stack state");
8697                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8698                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8699                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8700                pw.println("    o[om]: out of memory management");
8701                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8702                pw.println("    provider [COMP_SPEC]: provider client-side state");
8703                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8704                pw.println("    service [COMP_SPEC]: service client-side state");
8705                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8706                pw.println("    all: dump all activities");
8707                pw.println("    top: dump the top activity");
8708                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8709                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8710                pw.println("    a partial substring in a component name, a");
8711                pw.println("    hex object identifier.");
8712                pw.println("  -a: include all available server state.");
8713                pw.println("  -c: include client state.");
8714                return;
8715            } else {
8716                pw.println("Unknown argument: " + opt + "; use -h for help");
8717            }
8718        }
8719
8720        long origId = Binder.clearCallingIdentity();
8721        boolean more = false;
8722        // Is the caller requesting to dump a particular piece of data?
8723        if (opti < args.length) {
8724            String cmd = args[opti];
8725            opti++;
8726            if ("activities".equals(cmd) || "a".equals(cmd)) {
8727                synchronized (this) {
8728                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8729                }
8730            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8731                String[] newArgs;
8732                String name;
8733                if (opti >= args.length) {
8734                    name = null;
8735                    newArgs = EMPTY_STRING_ARRAY;
8736                } else {
8737                    name = args[opti];
8738                    opti++;
8739                    newArgs = new String[args.length - opti];
8740                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8741                            args.length - opti);
8742                }
8743                synchronized (this) {
8744                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8745                }
8746            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8747                String[] newArgs;
8748                String name;
8749                if (opti >= args.length) {
8750                    name = null;
8751                    newArgs = EMPTY_STRING_ARRAY;
8752                } else {
8753                    name = args[opti];
8754                    opti++;
8755                    newArgs = new String[args.length - opti];
8756                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8757                            args.length - opti);
8758                }
8759                synchronized (this) {
8760                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8761                }
8762            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8763                String[] newArgs;
8764                String name;
8765                if (opti >= args.length) {
8766                    name = null;
8767                    newArgs = EMPTY_STRING_ARRAY;
8768                } else {
8769                    name = args[opti];
8770                    opti++;
8771                    newArgs = new String[args.length - opti];
8772                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8773                            args.length - opti);
8774                }
8775                synchronized (this) {
8776                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8777                }
8778            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8779                synchronized (this) {
8780                    dumpOomLocked(fd, pw, args, opti, true);
8781                }
8782            } else if ("provider".equals(cmd)) {
8783                String[] newArgs;
8784                String name;
8785                if (opti >= args.length) {
8786                    name = null;
8787                    newArgs = EMPTY_STRING_ARRAY;
8788                } else {
8789                    name = args[opti];
8790                    opti++;
8791                    newArgs = new String[args.length - opti];
8792                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8793                }
8794                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8795                    pw.println("No providers match: " + name);
8796                    pw.println("Use -h for help.");
8797                }
8798            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8799                synchronized (this) {
8800                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8801                }
8802            } else if ("service".equals(cmd)) {
8803                String[] newArgs;
8804                String name;
8805                if (opti >= args.length) {
8806                    name = null;
8807                    newArgs = EMPTY_STRING_ARRAY;
8808                } else {
8809                    name = args[opti];
8810                    opti++;
8811                    newArgs = new String[args.length - opti];
8812                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8813                            args.length - opti);
8814                }
8815                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8816                    pw.println("No services match: " + name);
8817                    pw.println("Use -h for help.");
8818                }
8819            } else if ("package".equals(cmd)) {
8820                String[] newArgs;
8821                if (opti >= args.length) {
8822                    pw.println("package: no package name specified");
8823                    pw.println("Use -h for help.");
8824                } else {
8825                    dumpPackage = args[opti];
8826                    opti++;
8827                    newArgs = new String[args.length - opti];
8828                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8829                            args.length - opti);
8830                    args = newArgs;
8831                    opti = 0;
8832                    more = true;
8833                }
8834            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8835                synchronized (this) {
8836                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8837                }
8838            } else {
8839                // Dumping a single activity?
8840                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8841                    pw.println("Bad activity command, or no activities match: " + cmd);
8842                    pw.println("Use -h for help.");
8843                }
8844            }
8845            if (!more) {
8846                Binder.restoreCallingIdentity(origId);
8847                return;
8848            }
8849        }
8850
8851        // No piece of data specified, dump everything.
8852        synchronized (this) {
8853            boolean needSep;
8854            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8855            if (needSep) {
8856                pw.println(" ");
8857            }
8858            if (dumpAll) {
8859                pw.println("-------------------------------------------------------------------------------");
8860            }
8861            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8862            if (needSep) {
8863                pw.println(" ");
8864            }
8865            if (dumpAll) {
8866                pw.println("-------------------------------------------------------------------------------");
8867            }
8868            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8869            if (needSep) {
8870                pw.println(" ");
8871            }
8872            if (dumpAll) {
8873                pw.println("-------------------------------------------------------------------------------");
8874            }
8875            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8876            if (needSep) {
8877                pw.println(" ");
8878            }
8879            if (dumpAll) {
8880                pw.println("-------------------------------------------------------------------------------");
8881            }
8882            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8883            if (needSep) {
8884                pw.println(" ");
8885            }
8886            if (dumpAll) {
8887                pw.println("-------------------------------------------------------------------------------");
8888            }
8889            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8890        }
8891        Binder.restoreCallingIdentity(origId);
8892    }
8893
8894    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8895            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8896        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8897        pw.println("  Main stack:");
8898        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8899                dumpPackage);
8900        pw.println(" ");
8901        pw.println("  Running activities (most recent first):");
8902        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8903                dumpPackage);
8904        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8905            pw.println(" ");
8906            pw.println("  Activities waiting for another to become visible:");
8907            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8908                    !dumpAll, false, dumpPackage);
8909        }
8910        if (mMainStack.mStoppingActivities.size() > 0) {
8911            pw.println(" ");
8912            pw.println("  Activities waiting to stop:");
8913            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8914                    !dumpAll, false, dumpPackage);
8915        }
8916        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8917            pw.println(" ");
8918            pw.println("  Activities waiting to sleep:");
8919            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8920                    !dumpAll, false, dumpPackage);
8921        }
8922        if (mMainStack.mFinishingActivities.size() > 0) {
8923            pw.println(" ");
8924            pw.println("  Activities waiting to finish:");
8925            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8926                    !dumpAll, false, dumpPackage);
8927        }
8928
8929        pw.println(" ");
8930        if (mMainStack.mPausingActivity != null) {
8931            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8932        }
8933        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8934        pw.println("  mFocusedActivity: " + mFocusedActivity);
8935        if (dumpAll) {
8936            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8937            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8938            pw.println("  mDismissKeyguardOnNextActivity: "
8939                    + mMainStack.mDismissKeyguardOnNextActivity);
8940        }
8941
8942        if (mRecentTasks.size() > 0) {
8943            pw.println();
8944            pw.println("  Recent tasks:");
8945
8946            final int N = mRecentTasks.size();
8947            for (int i=0; i<N; i++) {
8948                TaskRecord tr = mRecentTasks.get(i);
8949                if (dumpPackage != null) {
8950                    if (tr.realActivity == null ||
8951                            !dumpPackage.equals(tr.realActivity)) {
8952                        continue;
8953                    }
8954                }
8955                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8956                        pw.println(tr);
8957                if (dumpAll) {
8958                    mRecentTasks.get(i).dump(pw, "    ");
8959                }
8960            }
8961        }
8962
8963        if (dumpAll) {
8964            pw.println(" ");
8965            pw.println("  mCurTask: " + mCurTask);
8966        }
8967
8968        return true;
8969    }
8970
8971    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8972            int opti, boolean dumpAll, String dumpPackage) {
8973        boolean needSep = false;
8974        int numPers = 0;
8975
8976        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8977
8978        if (dumpAll) {
8979            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8980                final int NA = procs.size();
8981                for (int ia=0; ia<NA; ia++) {
8982                    ProcessRecord r = procs.valueAt(ia);
8983                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8984                        continue;
8985                    }
8986                    if (!needSep) {
8987                        pw.println("  All known processes:");
8988                        needSep = true;
8989                    }
8990                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8991                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8992                        pw.print(" "); pw.println(r);
8993                    r.dump(pw, "    ");
8994                    if (r.persistent) {
8995                        numPers++;
8996                    }
8997                }
8998            }
8999        }
9000
9001        if (mIsolatedProcesses.size() > 0) {
9002            if (needSep) pw.println(" ");
9003            needSep = true;
9004            pw.println("  Isolated process list (sorted by uid):");
9005            for (int i=0; i<mIsolatedProcesses.size(); i++) {
9006                ProcessRecord r = mIsolatedProcesses.valueAt(i);
9007                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9008                    continue;
9009                }
9010                pw.println(String.format("%sIsolated #%2d: %s",
9011                        "    ", i, r.toString()));
9012            }
9013        }
9014
9015        if (mLruProcesses.size() > 0) {
9016            if (needSep) pw.println(" ");
9017            needSep = true;
9018            pw.println("  Process LRU list (sorted by oom_adj):");
9019            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9020                    "Proc", "PERS", false, dumpPackage);
9021            needSep = true;
9022        }
9023
9024        if (dumpAll) {
9025            synchronized (mPidsSelfLocked) {
9026                boolean printed = false;
9027                for (int i=0; i<mPidsSelfLocked.size(); i++) {
9028                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
9029                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9030                        continue;
9031                    }
9032                    if (!printed) {
9033                        if (needSep) pw.println(" ");
9034                        needSep = true;
9035                        pw.println("  PID mappings:");
9036                        printed = true;
9037                    }
9038                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9039                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9040                }
9041            }
9042        }
9043
9044        if (mForegroundProcesses.size() > 0) {
9045            synchronized (mPidsSelfLocked) {
9046                boolean printed = false;
9047                for (int i=0; i<mForegroundProcesses.size(); i++) {
9048                    ProcessRecord r = mPidsSelfLocked.get(
9049                            mForegroundProcesses.valueAt(i).pid);
9050                    if (dumpPackage != null && (r == null
9051                            || !dumpPackage.equals(r.info.packageName))) {
9052                        continue;
9053                    }
9054                    if (!printed) {
9055                        if (needSep) pw.println(" ");
9056                        needSep = true;
9057                        pw.println("  Foreground Processes:");
9058                        printed = true;
9059                    }
9060                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9061                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9062                }
9063            }
9064        }
9065
9066        if (mPersistentStartingProcesses.size() > 0) {
9067            if (needSep) pw.println(" ");
9068            needSep = true;
9069            pw.println("  Persisent processes that are starting:");
9070            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9071                    "Starting Norm", "Restarting PERS", dumpPackage);
9072        }
9073
9074        if (mRemovedProcesses.size() > 0) {
9075            if (needSep) pw.println(" ");
9076            needSep = true;
9077            pw.println("  Processes that are being removed:");
9078            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9079                    "Removed Norm", "Removed PERS", dumpPackage);
9080        }
9081
9082        if (mProcessesOnHold.size() > 0) {
9083            if (needSep) pw.println(" ");
9084            needSep = true;
9085            pw.println("  Processes that are on old until the system is ready:");
9086            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9087                    "OnHold Norm", "OnHold PERS", dumpPackage);
9088        }
9089
9090        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9091
9092        if (mProcessCrashTimes.getMap().size() > 0) {
9093            boolean printed = false;
9094            long now = SystemClock.uptimeMillis();
9095            for (Map.Entry<String, SparseArray<Long>> procs
9096                    : mProcessCrashTimes.getMap().entrySet()) {
9097                String pname = procs.getKey();
9098                SparseArray<Long> uids = procs.getValue();
9099                final int N = uids.size();
9100                for (int i=0; i<N; i++) {
9101                    int puid = uids.keyAt(i);
9102                    ProcessRecord r = mProcessNames.get(pname, puid);
9103                    if (dumpPackage != null && (r == null
9104                            || !dumpPackage.equals(r.info.packageName))) {
9105                        continue;
9106                    }
9107                    if (!printed) {
9108                        if (needSep) pw.println(" ");
9109                        needSep = true;
9110                        pw.println("  Time since processes crashed:");
9111                        printed = true;
9112                    }
9113                    pw.print("    Process "); pw.print(pname);
9114                            pw.print(" uid "); pw.print(puid);
9115                            pw.print(": last crashed ");
9116                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9117                            pw.println(" ago");
9118                }
9119            }
9120        }
9121
9122        if (mBadProcesses.getMap().size() > 0) {
9123            boolean printed = false;
9124            for (Map.Entry<String, SparseArray<Long>> procs
9125                    : mBadProcesses.getMap().entrySet()) {
9126                String pname = procs.getKey();
9127                SparseArray<Long> uids = procs.getValue();
9128                final int N = uids.size();
9129                for (int i=0; i<N; i++) {
9130                    int puid = uids.keyAt(i);
9131                    ProcessRecord r = mProcessNames.get(pname, puid);
9132                    if (dumpPackage != null && (r == null
9133                            || !dumpPackage.equals(r.info.packageName))) {
9134                        continue;
9135                    }
9136                    if (!printed) {
9137                        if (needSep) pw.println(" ");
9138                        needSep = true;
9139                        pw.println("  Bad processes:");
9140                    }
9141                    pw.print("    Bad process "); pw.print(pname);
9142                            pw.print(" uid "); pw.print(puid);
9143                            pw.print(": crashed at time ");
9144                            pw.println(uids.valueAt(i));
9145                }
9146            }
9147        }
9148
9149        pw.println();
9150        pw.println("  mStartedUsers:");
9151        for (int i=0; i<mStartedUsers.size(); i++) {
9152            UserStartedState uss = mStartedUsers.valueAt(i);
9153            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9154                    pw.println(":");
9155            uss.dump("      ", pw);
9156        }
9157        pw.println("  mHomeProcess: " + mHomeProcess);
9158        pw.println("  mPreviousProcess: " + mPreviousProcess);
9159        if (dumpAll) {
9160            StringBuilder sb = new StringBuilder(128);
9161            sb.append("  mPreviousProcessVisibleTime: ");
9162            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9163            pw.println(sb);
9164        }
9165        if (mHeavyWeightProcess != null) {
9166            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9167        }
9168        pw.println("  mConfiguration: " + mConfiguration);
9169        if (dumpAll) {
9170            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9171            if (mCompatModePackages.getPackages().size() > 0) {
9172                boolean printed = false;
9173                for (Map.Entry<String, Integer> entry
9174                        : mCompatModePackages.getPackages().entrySet()) {
9175                    String pkg = entry.getKey();
9176                    int mode = entry.getValue();
9177                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9178                        continue;
9179                    }
9180                    if (!printed) {
9181                        pw.println("  mScreenCompatPackages:");
9182                        printed = true;
9183                    }
9184                    pw.print("    "); pw.print(pkg); pw.print(": ");
9185                            pw.print(mode); pw.println();
9186                }
9187            }
9188        }
9189        if (mSleeping || mWentToSleep || mLockScreenShown) {
9190            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9191                    + " mLockScreenShown " + mLockScreenShown);
9192        }
9193        if (mShuttingDown) {
9194            pw.println("  mShuttingDown=" + mShuttingDown);
9195        }
9196        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9197                || mOrigWaitForDebugger) {
9198            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9199                    + " mDebugTransient=" + mDebugTransient
9200                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9201        }
9202        if (mOpenGlTraceApp != null) {
9203            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9204        }
9205        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9206                || mProfileFd != null) {
9207            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9208            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9209            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9210                    + mAutoStopProfiler);
9211        }
9212        if (mAlwaysFinishActivities || mController != null) {
9213            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9214                    + " mController=" + mController);
9215        }
9216        if (dumpAll) {
9217            pw.println("  Total persistent processes: " + numPers);
9218            pw.println("  mStartRunning=" + mStartRunning
9219                    + " mProcessesReady=" + mProcessesReady
9220                    + " mSystemReady=" + mSystemReady);
9221            pw.println("  mBooting=" + mBooting
9222                    + " mBooted=" + mBooted
9223                    + " mFactoryTest=" + mFactoryTest);
9224            pw.print("  mLastPowerCheckRealtime=");
9225                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9226                    pw.println("");
9227            pw.print("  mLastPowerCheckUptime=");
9228                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9229                    pw.println("");
9230            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9231            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9232            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9233            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9234                    + " mNumHiddenProcs=" + mNumHiddenProcs
9235                    + " mNumServiceProcs=" + mNumServiceProcs
9236                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9237        }
9238
9239        return true;
9240    }
9241
9242    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9243            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9244        if (mProcessesToGc.size() > 0) {
9245            boolean printed = false;
9246            long now = SystemClock.uptimeMillis();
9247            for (int i=0; i<mProcessesToGc.size(); i++) {
9248                ProcessRecord proc = mProcessesToGc.get(i);
9249                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9250                    continue;
9251                }
9252                if (!printed) {
9253                    if (needSep) pw.println(" ");
9254                    needSep = true;
9255                    pw.println("  Processes that are waiting to GC:");
9256                    printed = true;
9257                }
9258                pw.print("    Process "); pw.println(proc);
9259                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9260                        pw.print(", last gced=");
9261                        pw.print(now-proc.lastRequestedGc);
9262                        pw.print(" ms ago, last lowMem=");
9263                        pw.print(now-proc.lastLowMemory);
9264                        pw.println(" ms ago");
9265
9266            }
9267        }
9268        return needSep;
9269    }
9270
9271    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9272            int opti, boolean dumpAll) {
9273        boolean needSep = false;
9274
9275        if (mLruProcesses.size() > 0) {
9276            if (needSep) pw.println(" ");
9277            needSep = true;
9278            pw.println("  OOM levels:");
9279            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9280            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9281            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9282            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9283            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9284            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9285            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9286            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9287            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9288            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9289            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9290            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9291            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9292
9293            if (needSep) pw.println(" ");
9294            needSep = true;
9295            pw.println("  Process OOM control:");
9296            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9297                    "Proc", "PERS", true, null);
9298            needSep = true;
9299        }
9300
9301        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9302
9303        pw.println();
9304        pw.println("  mHomeProcess: " + mHomeProcess);
9305        pw.println("  mPreviousProcess: " + mPreviousProcess);
9306        if (mHeavyWeightProcess != null) {
9307            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9308        }
9309
9310        return true;
9311    }
9312
9313    /**
9314     * There are three ways to call this:
9315     *  - no provider specified: dump all the providers
9316     *  - a flattened component name that matched an existing provider was specified as the
9317     *    first arg: dump that one provider
9318     *  - the first arg isn't the flattened component name of an existing provider:
9319     *    dump all providers whose component contains the first arg as a substring
9320     */
9321    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9322            int opti, boolean dumpAll) {
9323        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9324    }
9325
9326    static class ItemMatcher {
9327        ArrayList<ComponentName> components;
9328        ArrayList<String> strings;
9329        ArrayList<Integer> objects;
9330        boolean all;
9331
9332        ItemMatcher() {
9333            all = true;
9334        }
9335
9336        void build(String name) {
9337            ComponentName componentName = ComponentName.unflattenFromString(name);
9338            if (componentName != null) {
9339                if (components == null) {
9340                    components = new ArrayList<ComponentName>();
9341                }
9342                components.add(componentName);
9343                all = false;
9344            } else {
9345                int objectId = 0;
9346                // Not a '/' separated full component name; maybe an object ID?
9347                try {
9348                    objectId = Integer.parseInt(name, 16);
9349                    if (objects == null) {
9350                        objects = new ArrayList<Integer>();
9351                    }
9352                    objects.add(objectId);
9353                    all = false;
9354                } catch (RuntimeException e) {
9355                    // Not an integer; just do string match.
9356                    if (strings == null) {
9357                        strings = new ArrayList<String>();
9358                    }
9359                    strings.add(name);
9360                    all = false;
9361                }
9362            }
9363        }
9364
9365        int build(String[] args, int opti) {
9366            for (; opti<args.length; opti++) {
9367                String name = args[opti];
9368                if ("--".equals(name)) {
9369                    return opti+1;
9370                }
9371                build(name);
9372            }
9373            return opti;
9374        }
9375
9376        boolean match(Object object, ComponentName comp) {
9377            if (all) {
9378                return true;
9379            }
9380            if (components != null) {
9381                for (int i=0; i<components.size(); i++) {
9382                    if (components.get(i).equals(comp)) {
9383                        return true;
9384                    }
9385                }
9386            }
9387            if (objects != null) {
9388                for (int i=0; i<objects.size(); i++) {
9389                    if (System.identityHashCode(object) == objects.get(i)) {
9390                        return true;
9391                    }
9392                }
9393            }
9394            if (strings != null) {
9395                String flat = comp.flattenToString();
9396                for (int i=0; i<strings.size(); i++) {
9397                    if (flat.contains(strings.get(i))) {
9398                        return true;
9399                    }
9400                }
9401            }
9402            return false;
9403        }
9404    }
9405
9406    /**
9407     * There are three things that cmd can be:
9408     *  - a flattened component name that matches an existing activity
9409     *  - the cmd arg isn't the flattened component name of an existing activity:
9410     *    dump all activity whose component contains the cmd as a substring
9411     *  - A hex number of the ActivityRecord object instance.
9412     */
9413    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9414            int opti, boolean dumpAll) {
9415        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9416
9417        if ("all".equals(name)) {
9418            synchronized (this) {
9419                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9420                    activities.add(r1);
9421                }
9422            }
9423        } else if ("top".equals(name)) {
9424            synchronized (this) {
9425                final int N = mMainStack.mHistory.size();
9426                if (N > 0) {
9427                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9428                }
9429            }
9430        } else {
9431            ItemMatcher matcher = new ItemMatcher();
9432            matcher.build(name);
9433
9434            synchronized (this) {
9435                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9436                    if (matcher.match(r1, r1.intent.getComponent())) {
9437                        activities.add(r1);
9438                    }
9439                }
9440            }
9441        }
9442
9443        if (activities.size() <= 0) {
9444            return false;
9445        }
9446
9447        String[] newArgs = new String[args.length - opti];
9448        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9449
9450        TaskRecord lastTask = null;
9451        boolean needSep = false;
9452        for (int i=activities.size()-1; i>=0; i--) {
9453            ActivityRecord r = (ActivityRecord)activities.get(i);
9454            if (needSep) {
9455                pw.println();
9456            }
9457            needSep = true;
9458            synchronized (this) {
9459                if (lastTask != r.task) {
9460                    lastTask = r.task;
9461                    pw.print("TASK "); pw.print(lastTask.affinity);
9462                            pw.print(" id="); pw.println(lastTask.taskId);
9463                    if (dumpAll) {
9464                        lastTask.dump(pw, "  ");
9465                    }
9466                }
9467            }
9468            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9469        }
9470        return true;
9471    }
9472
9473    /**
9474     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9475     * there is a thread associated with the activity.
9476     */
9477    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9478            final ActivityRecord r, String[] args, boolean dumpAll) {
9479        String innerPrefix = prefix + "  ";
9480        synchronized (this) {
9481            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9482                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9483                    pw.print(" pid=");
9484                    if (r.app != null) pw.println(r.app.pid);
9485                    else pw.println("(not running)");
9486            if (dumpAll) {
9487                r.dump(pw, innerPrefix);
9488            }
9489        }
9490        if (r.app != null && r.app.thread != null) {
9491            // flush anything that is already in the PrintWriter since the thread is going
9492            // to write to the file descriptor directly
9493            pw.flush();
9494            try {
9495                TransferPipe tp = new TransferPipe();
9496                try {
9497                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9498                            r.appToken, innerPrefix, args);
9499                    tp.go(fd);
9500                } finally {
9501                    tp.kill();
9502                }
9503            } catch (IOException e) {
9504                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9505            } catch (RemoteException e) {
9506                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9507            }
9508        }
9509    }
9510
9511    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9512            int opti, boolean dumpAll, String dumpPackage) {
9513        boolean needSep = false;
9514        boolean onlyHistory = false;
9515
9516        if ("history".equals(dumpPackage)) {
9517            onlyHistory = true;
9518            dumpPackage = null;
9519        }
9520
9521        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9522        if (!onlyHistory && dumpAll) {
9523            if (mRegisteredReceivers.size() > 0) {
9524                boolean printed = false;
9525                Iterator it = mRegisteredReceivers.values().iterator();
9526                while (it.hasNext()) {
9527                    ReceiverList r = (ReceiverList)it.next();
9528                    if (dumpPackage != null && (r.app == null ||
9529                            !dumpPackage.equals(r.app.info.packageName))) {
9530                        continue;
9531                    }
9532                    if (!printed) {
9533                        pw.println("  Registered Receivers:");
9534                        needSep = true;
9535                        printed = true;
9536                    }
9537                    pw.print("  * "); pw.println(r);
9538                    r.dump(pw, "    ");
9539                }
9540            }
9541
9542            if (mReceiverResolver.dump(pw, needSep ?
9543                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9544                    "    ", dumpPackage, false)) {
9545                needSep = true;
9546            }
9547        }
9548
9549        for (BroadcastQueue q : mBroadcastQueues) {
9550            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9551        }
9552
9553        needSep = true;
9554
9555        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9556            for (int user=0; user<mStickyBroadcasts.size(); user++) {
9557                if (needSep) {
9558                    pw.println();
9559                }
9560                needSep = true;
9561                pw.print("  Sticky broadcasts for user ");
9562                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9563                StringBuilder sb = new StringBuilder(128);
9564                for (Map.Entry<String, ArrayList<Intent>> ent
9565                        : mStickyBroadcasts.valueAt(user).entrySet()) {
9566                    pw.print("  * Sticky action "); pw.print(ent.getKey());
9567                    if (dumpAll) {
9568                        pw.println(":");
9569                        ArrayList<Intent> intents = ent.getValue();
9570                        final int N = intents.size();
9571                        for (int i=0; i<N; i++) {
9572                            sb.setLength(0);
9573                            sb.append("    Intent: ");
9574                            intents.get(i).toShortString(sb, false, true, false, false);
9575                            pw.println(sb.toString());
9576                            Bundle bundle = intents.get(i).getExtras();
9577                            if (bundle != null) {
9578                                pw.print("      ");
9579                                pw.println(bundle.toString());
9580                            }
9581                        }
9582                    } else {
9583                        pw.println("");
9584                    }
9585                }
9586            }
9587        }
9588
9589        if (!onlyHistory && dumpAll) {
9590            pw.println();
9591            for (BroadcastQueue queue : mBroadcastQueues) {
9592                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9593                        + queue.mBroadcastsScheduled);
9594            }
9595            pw.println("  mHandler:");
9596            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9597            needSep = true;
9598        }
9599
9600        return needSep;
9601    }
9602
9603    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9604            int opti, boolean dumpAll, String dumpPackage) {
9605        boolean needSep = true;
9606
9607        ItemMatcher matcher = new ItemMatcher();
9608        matcher.build(args, opti);
9609
9610        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9611
9612        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9613
9614        if (mLaunchingProviders.size() > 0) {
9615            boolean printed = false;
9616            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9617                ContentProviderRecord r = mLaunchingProviders.get(i);
9618                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9619                    continue;
9620                }
9621                if (!printed) {
9622                    if (needSep) pw.println(" ");
9623                    needSep = true;
9624                    pw.println("  Launching content providers:");
9625                    printed = true;
9626                }
9627                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9628                        pw.println(r);
9629            }
9630        }
9631
9632        if (mGrantedUriPermissions.size() > 0) {
9633            if (needSep) pw.println();
9634            needSep = true;
9635            pw.println("Granted Uri Permissions:");
9636            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9637                int uid = mGrantedUriPermissions.keyAt(i);
9638                HashMap<Uri, UriPermission> perms
9639                        = mGrantedUriPermissions.valueAt(i);
9640                pw.print("  * UID "); pw.print(uid);
9641                        pw.println(" holds:");
9642                for (UriPermission perm : perms.values()) {
9643                    pw.print("    "); pw.println(perm);
9644                    if (dumpAll) {
9645                        perm.dump(pw, "      ");
9646                    }
9647                }
9648            }
9649            needSep = true;
9650        }
9651
9652        return needSep;
9653    }
9654
9655    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9656            int opti, boolean dumpAll, String dumpPackage) {
9657        boolean needSep = false;
9658
9659        if (mIntentSenderRecords.size() > 0) {
9660            boolean printed = false;
9661            Iterator<WeakReference<PendingIntentRecord>> it
9662                    = mIntentSenderRecords.values().iterator();
9663            while (it.hasNext()) {
9664                WeakReference<PendingIntentRecord> ref = it.next();
9665                PendingIntentRecord rec = ref != null ? ref.get(): null;
9666                if (dumpPackage != null && (rec == null
9667                        || !dumpPackage.equals(rec.key.packageName))) {
9668                    continue;
9669                }
9670                if (!printed) {
9671                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9672                    printed = true;
9673                }
9674                needSep = true;
9675                if (rec != null) {
9676                    pw.print("  * "); pw.println(rec);
9677                    if (dumpAll) {
9678                        rec.dump(pw, "    ");
9679                    }
9680                } else {
9681                    pw.print("  * "); pw.println(ref);
9682                }
9683            }
9684        }
9685
9686        return needSep;
9687    }
9688
9689    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9690            String prefix, String label, boolean complete, boolean brief, boolean client,
9691            String dumpPackage) {
9692        TaskRecord lastTask = null;
9693        boolean needNL = false;
9694        final String innerPrefix = prefix + "      ";
9695        final String[] args = new String[0];
9696        for (int i=list.size()-1; i>=0; i--) {
9697            final ActivityRecord r = (ActivityRecord)list.get(i);
9698            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9699                continue;
9700            }
9701            final boolean full = !brief && (complete || !r.isInHistory());
9702            if (needNL) {
9703                pw.println(" ");
9704                needNL = false;
9705            }
9706            if (lastTask != r.task) {
9707                lastTask = r.task;
9708                pw.print(prefix);
9709                pw.print(full ? "* " : "  ");
9710                pw.println(lastTask);
9711                if (full) {
9712                    lastTask.dump(pw, prefix + "  ");
9713                } else if (complete) {
9714                    // Complete + brief == give a summary.  Isn't that obvious?!?
9715                    if (lastTask.intent != null) {
9716                        pw.print(prefix); pw.print("  ");
9717                                pw.println(lastTask.intent.toInsecureStringWithClip());
9718                    }
9719                }
9720            }
9721            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9722            pw.print(" #"); pw.print(i); pw.print(": ");
9723            pw.println(r);
9724            if (full) {
9725                r.dump(pw, innerPrefix);
9726            } else if (complete) {
9727                // Complete + brief == give a summary.  Isn't that obvious?!?
9728                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9729                if (r.app != null) {
9730                    pw.print(innerPrefix); pw.println(r.app);
9731                }
9732            }
9733            if (client && r.app != null && r.app.thread != null) {
9734                // flush anything that is already in the PrintWriter since the thread is going
9735                // to write to the file descriptor directly
9736                pw.flush();
9737                try {
9738                    TransferPipe tp = new TransferPipe();
9739                    try {
9740                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9741                                r.appToken, innerPrefix, args);
9742                        // Short timeout, since blocking here can
9743                        // deadlock with the application.
9744                        tp.go(fd, 2000);
9745                    } finally {
9746                        tp.kill();
9747                    }
9748                } catch (IOException e) {
9749                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9750                } catch (RemoteException e) {
9751                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9752                }
9753                needNL = true;
9754            }
9755        }
9756    }
9757
9758    private static String buildOomTag(String prefix, String space, int val, int base) {
9759        if (val == base) {
9760            if (space == null) return prefix;
9761            return prefix + "  ";
9762        }
9763        return prefix + "+" + Integer.toString(val-base);
9764    }
9765
9766    private static final int dumpProcessList(PrintWriter pw,
9767            ActivityManagerService service, List list,
9768            String prefix, String normalLabel, String persistentLabel,
9769            String dumpPackage) {
9770        int numPers = 0;
9771        final int N = list.size()-1;
9772        for (int i=N; i>=0; i--) {
9773            ProcessRecord r = (ProcessRecord)list.get(i);
9774            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9775                continue;
9776            }
9777            pw.println(String.format("%s%s #%2d: %s",
9778                    prefix, (r.persistent ? persistentLabel : normalLabel),
9779                    i, r.toString()));
9780            if (r.persistent) {
9781                numPers++;
9782            }
9783        }
9784        return numPers;
9785    }
9786
9787    private static final boolean dumpProcessOomList(PrintWriter pw,
9788            ActivityManagerService service, List<ProcessRecord> origList,
9789            String prefix, String normalLabel, String persistentLabel,
9790            boolean inclDetails, String dumpPackage) {
9791
9792        ArrayList<Pair<ProcessRecord, Integer>> list
9793                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9794        for (int i=0; i<origList.size(); i++) {
9795            ProcessRecord r = origList.get(i);
9796            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9797                continue;
9798            }
9799            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9800        }
9801
9802        if (list.size() <= 0) {
9803            return false;
9804        }
9805
9806        Comparator<Pair<ProcessRecord, Integer>> comparator
9807                = new Comparator<Pair<ProcessRecord, Integer>>() {
9808            @Override
9809            public int compare(Pair<ProcessRecord, Integer> object1,
9810                    Pair<ProcessRecord, Integer> object2) {
9811                if (object1.first.setAdj != object2.first.setAdj) {
9812                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9813                }
9814                if (object1.second.intValue() != object2.second.intValue()) {
9815                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9816                }
9817                return 0;
9818            }
9819        };
9820
9821        Collections.sort(list, comparator);
9822
9823        final long curRealtime = SystemClock.elapsedRealtime();
9824        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9825        final long curUptime = SystemClock.uptimeMillis();
9826        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9827
9828        for (int i=list.size()-1; i>=0; i--) {
9829            ProcessRecord r = list.get(i).first;
9830            String oomAdj;
9831            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9832                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9833            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9834                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9835            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9836                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9837            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9838                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9839            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9840                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9841            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9842                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9843            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9844                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9845            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9846                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9847            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9848                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9849            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9850                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9851            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9852                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9853            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9854                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9855            } else {
9856                oomAdj = Integer.toString(r.setAdj);
9857            }
9858            String schedGroup;
9859            switch (r.setSchedGroup) {
9860                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9861                    schedGroup = "B";
9862                    break;
9863                case Process.THREAD_GROUP_DEFAULT:
9864                    schedGroup = "F";
9865                    break;
9866                default:
9867                    schedGroup = Integer.toString(r.setSchedGroup);
9868                    break;
9869            }
9870            String foreground;
9871            if (r.foregroundActivities) {
9872                foreground = "A";
9873            } else if (r.foregroundServices) {
9874                foreground = "S";
9875            } else {
9876                foreground = " ";
9877            }
9878            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9879                    prefix, (r.persistent ? persistentLabel : normalLabel),
9880                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9881                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9882            if (r.adjSource != null || r.adjTarget != null) {
9883                pw.print(prefix);
9884                pw.print("    ");
9885                if (r.adjTarget instanceof ComponentName) {
9886                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9887                } else if (r.adjTarget != null) {
9888                    pw.print(r.adjTarget.toString());
9889                } else {
9890                    pw.print("{null}");
9891                }
9892                pw.print("<=");
9893                if (r.adjSource instanceof ProcessRecord) {
9894                    pw.print("Proc{");
9895                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9896                    pw.println("}");
9897                } else if (r.adjSource != null) {
9898                    pw.println(r.adjSource.toString());
9899                } else {
9900                    pw.println("{null}");
9901                }
9902            }
9903            if (inclDetails) {
9904                pw.print(prefix);
9905                pw.print("    ");
9906                pw.print("oom: max="); pw.print(r.maxAdj);
9907                pw.print(" hidden="); pw.print(r.hiddenAdj);
9908                pw.print(" empty="); pw.print(r.emptyAdj);
9909                pw.print(" curRaw="); pw.print(r.curRawAdj);
9910                pw.print(" setRaw="); pw.print(r.setRawAdj);
9911                pw.print(" cur="); pw.print(r.curAdj);
9912                pw.print(" set="); pw.println(r.setAdj);
9913                pw.print(prefix);
9914                pw.print("    ");
9915                pw.print("keeping="); pw.print(r.keeping);
9916                pw.print(" hidden="); pw.print(r.hidden);
9917                pw.print(" empty="); pw.print(r.empty);
9918                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9919
9920                if (!r.keeping) {
9921                    if (r.lastWakeTime != 0) {
9922                        long wtime;
9923                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9924                        synchronized (stats) {
9925                            wtime = stats.getProcessWakeTime(r.info.uid,
9926                                    r.pid, curRealtime);
9927                        }
9928                        long timeUsed = wtime - r.lastWakeTime;
9929                        pw.print(prefix);
9930                        pw.print("    ");
9931                        pw.print("keep awake over ");
9932                        TimeUtils.formatDuration(realtimeSince, pw);
9933                        pw.print(" used ");
9934                        TimeUtils.formatDuration(timeUsed, pw);
9935                        pw.print(" (");
9936                        pw.print((timeUsed*100)/realtimeSince);
9937                        pw.println("%)");
9938                    }
9939                    if (r.lastCpuTime != 0) {
9940                        long timeUsed = r.curCpuTime - r.lastCpuTime;
9941                        pw.print(prefix);
9942                        pw.print("    ");
9943                        pw.print("run cpu over ");
9944                        TimeUtils.formatDuration(uptimeSince, pw);
9945                        pw.print(" used ");
9946                        TimeUtils.formatDuration(timeUsed, pw);
9947                        pw.print(" (");
9948                        pw.print((timeUsed*100)/uptimeSince);
9949                        pw.println("%)");
9950                    }
9951                }
9952            }
9953        }
9954        return true;
9955    }
9956
9957    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
9958        ArrayList<ProcessRecord> procs;
9959        synchronized (this) {
9960            if (args != null && args.length > start
9961                    && args[start].charAt(0) != '-') {
9962                procs = new ArrayList<ProcessRecord>();
9963                int pid = -1;
9964                try {
9965                    pid = Integer.parseInt(args[start]);
9966                } catch (NumberFormatException e) {
9967
9968                }
9969                for (int i=mLruProcesses.size()-1; i>=0; i--) {
9970                    ProcessRecord proc = mLruProcesses.get(i);
9971                    if (proc.pid == pid) {
9972                        procs.add(proc);
9973                    } else if (proc.processName.equals(args[start])) {
9974                        procs.add(proc);
9975                    }
9976                }
9977                if (procs.size() <= 0) {
9978                    pw.println("No process found for: " + args[start]);
9979                    return null;
9980                }
9981            } else {
9982                procs = new ArrayList<ProcessRecord>(mLruProcesses);
9983            }
9984        }
9985        return procs;
9986    }
9987
9988    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9989            PrintWriter pw, String[] args) {
9990        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9991        if (procs == null) {
9992            return;
9993        }
9994
9995        long uptime = SystemClock.uptimeMillis();
9996        long realtime = SystemClock.elapsedRealtime();
9997        pw.println("Applications Graphics Acceleration Info:");
9998        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9999
10000        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10001            ProcessRecord r = procs.get(i);
10002            if (r.thread != null) {
10003                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10004                pw.flush();
10005                try {
10006                    TransferPipe tp = new TransferPipe();
10007                    try {
10008                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10009                        tp.go(fd);
10010                    } finally {
10011                        tp.kill();
10012                    }
10013                } catch (IOException e) {
10014                    pw.println("Failure while dumping the app: " + r);
10015                    pw.flush();
10016                } catch (RemoteException e) {
10017                    pw.println("Got a RemoteException while dumping the app " + r);
10018                    pw.flush();
10019                }
10020            }
10021        }
10022    }
10023
10024    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10025        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10026        if (procs == null) {
10027            return;
10028        }
10029
10030        pw.println("Applications Database Info:");
10031
10032        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10033            ProcessRecord r = procs.get(i);
10034            if (r.thread != null) {
10035                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10036                pw.flush();
10037                try {
10038                    TransferPipe tp = new TransferPipe();
10039                    try {
10040                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10041                        tp.go(fd);
10042                    } finally {
10043                        tp.kill();
10044                    }
10045                } catch (IOException e) {
10046                    pw.println("Failure while dumping the app: " + r);
10047                    pw.flush();
10048                } catch (RemoteException e) {
10049                    pw.println("Got a RemoteException while dumping the app " + r);
10050                    pw.flush();
10051                }
10052            }
10053        }
10054    }
10055
10056    final static class MemItem {
10057        final String label;
10058        final String shortLabel;
10059        final long pss;
10060        final int id;
10061        ArrayList<MemItem> subitems;
10062
10063        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10064            label = _label;
10065            shortLabel = _shortLabel;
10066            pss = _pss;
10067            id = _id;
10068        }
10069    }
10070
10071    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10072            boolean sort) {
10073        if (sort) {
10074            Collections.sort(items, new Comparator<MemItem>() {
10075                @Override
10076                public int compare(MemItem lhs, MemItem rhs) {
10077                    if (lhs.pss < rhs.pss) {
10078                        return 1;
10079                    } else if (lhs.pss > rhs.pss) {
10080                        return -1;
10081                    }
10082                    return 0;
10083                }
10084            });
10085        }
10086
10087        for (int i=0; i<items.size(); i++) {
10088            MemItem mi = items.get(i);
10089            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10090            if (mi.subitems != null) {
10091                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10092            }
10093        }
10094    }
10095
10096    // These are in KB.
10097    static final long[] DUMP_MEM_BUCKETS = new long[] {
10098        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10099        120*1024, 160*1024, 200*1024,
10100        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10101        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10102    };
10103
10104    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10105            boolean stackLike) {
10106        int start = label.lastIndexOf('.');
10107        if (start >= 0) start++;
10108        else start = 0;
10109        int end = label.length();
10110        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10111            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10112                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10113                out.append(bucket);
10114                out.append(stackLike ? "MB." : "MB ");
10115                out.append(label, start, end);
10116                return;
10117            }
10118        }
10119        out.append(memKB/1024);
10120        out.append(stackLike ? "MB." : "MB ");
10121        out.append(label, start, end);
10122    }
10123
10124    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10125            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10126            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10127            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10128            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10129    };
10130    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10131            "System", "Persistent", "Foreground",
10132            "Visible", "Perceptible", "Heavy Weight",
10133            "Backup", "A Services", "Home", "Previous",
10134            "B Services", "Background"
10135    };
10136
10137    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10138            PrintWriter pw, String prefix, String[] args, boolean brief,
10139            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10140        boolean dumpAll = false;
10141        boolean oomOnly = false;
10142
10143        int opti = 0;
10144        while (opti < args.length) {
10145            String opt = args[opti];
10146            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10147                break;
10148            }
10149            opti++;
10150            if ("-a".equals(opt)) {
10151                dumpAll = true;
10152            } else if ("--oom".equals(opt)) {
10153                oomOnly = true;
10154            } else if ("-h".equals(opt)) {
10155                pw.println("meminfo dump options: [-a] [--oom] [process]");
10156                pw.println("  -a: include all available information for each process.");
10157                pw.println("  --oom: only show processes organized by oom adj.");
10158                pw.println("If [process] is specified it can be the name or ");
10159                pw.println("pid of a specific process to dump.");
10160                return;
10161            } else {
10162                pw.println("Unknown argument: " + opt + "; use -h for help");
10163            }
10164        }
10165
10166        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10167        if (procs == null) {
10168            return;
10169        }
10170
10171        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10172        long uptime = SystemClock.uptimeMillis();
10173        long realtime = SystemClock.elapsedRealtime();
10174
10175        if (procs.size() == 1 || isCheckinRequest) {
10176            dumpAll = true;
10177        }
10178
10179        if (isCheckinRequest) {
10180            // short checkin version
10181            pw.println(uptime + "," + realtime);
10182            pw.flush();
10183        } else {
10184            pw.println("Applications Memory Usage (kB):");
10185            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10186        }
10187
10188        String[] innerArgs = new String[args.length-opti];
10189        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10190
10191        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10192        long nativePss=0, dalvikPss=0, otherPss=0;
10193        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10194
10195        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10196        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10197                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10198
10199        long totalPss = 0;
10200
10201        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10202            ProcessRecord r = procs.get(i);
10203            if (r.thread != null) {
10204                if (!isCheckinRequest && dumpAll) {
10205                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10206                    pw.flush();
10207                }
10208                Debug.MemoryInfo mi = null;
10209                if (dumpAll) {
10210                    try {
10211                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10212                    } catch (RemoteException e) {
10213                        if (!isCheckinRequest) {
10214                            pw.println("Got RemoteException!");
10215                            pw.flush();
10216                        }
10217                    }
10218                } else {
10219                    mi = new Debug.MemoryInfo();
10220                    Debug.getMemoryInfo(r.pid, mi);
10221                }
10222
10223                if (!isCheckinRequest && mi != null) {
10224                    long myTotalPss = mi.getTotalPss();
10225                    totalPss += myTotalPss;
10226                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10227                            r.processName, myTotalPss, 0);
10228                    procMems.add(pssItem);
10229
10230                    nativePss += mi.nativePss;
10231                    dalvikPss += mi.dalvikPss;
10232                    otherPss += mi.otherPss;
10233                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10234                        long mem = mi.getOtherPss(j);
10235                        miscPss[j] += mem;
10236                        otherPss -= mem;
10237                    }
10238
10239                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10240                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10241                                || oomIndex == (oomPss.length-1)) {
10242                            oomPss[oomIndex] += myTotalPss;
10243                            if (oomProcs[oomIndex] == null) {
10244                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10245                            }
10246                            oomProcs[oomIndex].add(pssItem);
10247                            break;
10248                        }
10249                    }
10250                }
10251            }
10252        }
10253
10254        if (!isCheckinRequest && procs.size() > 1) {
10255            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10256
10257            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10258            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10259            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10260            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10261                String label = Debug.MemoryInfo.getOtherLabel(j);
10262                catMems.add(new MemItem(label, label, miscPss[j], j));
10263            }
10264
10265            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10266            for (int j=0; j<oomPss.length; j++) {
10267                if (oomPss[j] != 0) {
10268                    String label = DUMP_MEM_OOM_LABEL[j];
10269                    MemItem item = new MemItem(label, label, oomPss[j],
10270                            DUMP_MEM_OOM_ADJ[j]);
10271                    item.subitems = oomProcs[j];
10272                    oomMems.add(item);
10273                }
10274            }
10275
10276            if (outTag != null || outStack != null) {
10277                if (outTag != null) {
10278                    appendMemBucket(outTag, totalPss, "total", false);
10279                }
10280                if (outStack != null) {
10281                    appendMemBucket(outStack, totalPss, "total", true);
10282                }
10283                boolean firstLine = true;
10284                for (int i=0; i<oomMems.size(); i++) {
10285                    MemItem miCat = oomMems.get(i);
10286                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10287                        continue;
10288                    }
10289                    if (miCat.id < ProcessList.SERVICE_ADJ
10290                            || miCat.id == ProcessList.HOME_APP_ADJ
10291                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10292                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10293                            outTag.append(" / ");
10294                        }
10295                        if (outStack != null) {
10296                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10297                                if (firstLine) {
10298                                    outStack.append(":");
10299                                    firstLine = false;
10300                                }
10301                                outStack.append("\n\t at ");
10302                            } else {
10303                                outStack.append("$");
10304                            }
10305                        }
10306                        for (int j=0; j<miCat.subitems.size(); j++) {
10307                            MemItem mi = miCat.subitems.get(j);
10308                            if (j > 0) {
10309                                if (outTag != null) {
10310                                    outTag.append(" ");
10311                                }
10312                                if (outStack != null) {
10313                                    outStack.append("$");
10314                                }
10315                            }
10316                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10317                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10318                            }
10319                            if (outStack != null) {
10320                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10321                            }
10322                        }
10323                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10324                            outStack.append("(");
10325                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10326                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10327                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10328                                    outStack.append(":");
10329                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10330                                }
10331                            }
10332                            outStack.append(")");
10333                        }
10334                    }
10335                }
10336            }
10337
10338            if (!brief && !oomOnly) {
10339                pw.println();
10340                pw.println("Total PSS by process:");
10341                dumpMemItems(pw, "  ", procMems, true);
10342                pw.println();
10343            }
10344            pw.println("Total PSS by OOM adjustment:");
10345            dumpMemItems(pw, "  ", oomMems, false);
10346            if (!oomOnly) {
10347                PrintWriter out = categoryPw != null ? categoryPw : pw;
10348                out.println();
10349                out.println("Total PSS by category:");
10350                dumpMemItems(out, "  ", catMems, true);
10351            }
10352            pw.println();
10353            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10354            final int[] SINGLE_LONG_FORMAT = new int[] {
10355                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10356            };
10357            long[] longOut = new long[1];
10358            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10359                    SINGLE_LONG_FORMAT, null, longOut, null);
10360            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10361            longOut[0] = 0;
10362            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10363                    SINGLE_LONG_FORMAT, null, longOut, null);
10364            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10365            longOut[0] = 0;
10366            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10367                    SINGLE_LONG_FORMAT, null, longOut, null);
10368            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10369            longOut[0] = 0;
10370            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10371                    SINGLE_LONG_FORMAT, null, longOut, null);
10372            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10373            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10374                    pw.print(shared); pw.println(" kB");
10375            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10376                    pw.print(voltile); pw.println(" kB volatile");
10377        }
10378    }
10379
10380    /**
10381     * Searches array of arguments for the specified string
10382     * @param args array of argument strings
10383     * @param value value to search for
10384     * @return true if the value is contained in the array
10385     */
10386    private static boolean scanArgs(String[] args, String value) {
10387        if (args != null) {
10388            for (String arg : args) {
10389                if (value.equals(arg)) {
10390                    return true;
10391                }
10392            }
10393        }
10394        return false;
10395    }
10396
10397    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10398            ContentProviderRecord cpr, boolean always) {
10399        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10400
10401        if (!inLaunching || always) {
10402            synchronized (cpr) {
10403                cpr.launchingApp = null;
10404                cpr.notifyAll();
10405            }
10406            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10407            String names[] = cpr.info.authority.split(";");
10408            for (int j = 0; j < names.length; j++) {
10409                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10410            }
10411        }
10412
10413        for (int i=0; i<cpr.connections.size(); i++) {
10414            ContentProviderConnection conn = cpr.connections.get(i);
10415            if (conn.waiting) {
10416                // If this connection is waiting for the provider, then we don't
10417                // need to mess with its process unless we are always removing
10418                // or for some reason the provider is not currently launching.
10419                if (inLaunching && !always) {
10420                    continue;
10421                }
10422            }
10423            ProcessRecord capp = conn.client;
10424            conn.dead = true;
10425            if (conn.stableCount > 0) {
10426                if (!capp.persistent && capp.thread != null
10427                        && capp.pid != 0
10428                        && capp.pid != MY_PID) {
10429                    Slog.i(TAG, "Kill " + capp.processName
10430                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10431                            + " in dying process " + (proc != null ? proc.processName : "??"));
10432                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10433                            capp.processName, capp.setAdj, "dying provider "
10434                                    + cpr.name.toShortString());
10435                    Process.killProcessQuiet(capp.pid);
10436                }
10437            } else if (capp.thread != null && conn.provider.provider != null) {
10438                try {
10439                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10440                } catch (RemoteException e) {
10441                }
10442                // In the protocol here, we don't expect the client to correctly
10443                // clean up this connection, we'll just remove it.
10444                cpr.connections.remove(i);
10445                conn.client.conProviders.remove(conn);
10446            }
10447        }
10448
10449        if (inLaunching && always) {
10450            mLaunchingProviders.remove(cpr);
10451        }
10452        return inLaunching;
10453    }
10454
10455    /**
10456     * Main code for cleaning up a process when it has gone away.  This is
10457     * called both as a result of the process dying, or directly when stopping
10458     * a process when running in single process mode.
10459     */
10460    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10461            boolean restarting, boolean allowRestart, int index) {
10462        if (index >= 0) {
10463            mLruProcesses.remove(index);
10464        }
10465
10466        mProcessesToGc.remove(app);
10467
10468        // Dismiss any open dialogs.
10469        if (app.crashDialog != null) {
10470            app.crashDialog.dismiss();
10471            app.crashDialog = null;
10472        }
10473        if (app.anrDialog != null) {
10474            app.anrDialog.dismiss();
10475            app.anrDialog = null;
10476        }
10477        if (app.waitDialog != null) {
10478            app.waitDialog.dismiss();
10479            app.waitDialog = null;
10480        }
10481
10482        app.crashing = false;
10483        app.notResponding = false;
10484
10485        app.resetPackageList();
10486        app.unlinkDeathRecipient();
10487        app.thread = null;
10488        app.forcingToForeground = null;
10489        app.foregroundServices = false;
10490        app.foregroundActivities = false;
10491        app.hasShownUi = false;
10492        app.hasAboveClient = false;
10493
10494        mServices.killServicesLocked(app, allowRestart);
10495
10496        boolean restart = false;
10497
10498        // Remove published content providers.
10499        if (!app.pubProviders.isEmpty()) {
10500            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10501            while (it.hasNext()) {
10502                ContentProviderRecord cpr = it.next();
10503
10504                final boolean always = app.bad || !allowRestart;
10505                if (removeDyingProviderLocked(app, cpr, always) || always) {
10506                    // We left the provider in the launching list, need to
10507                    // restart it.
10508                    restart = true;
10509                }
10510
10511                cpr.provider = null;
10512                cpr.proc = null;
10513            }
10514            app.pubProviders.clear();
10515        }
10516
10517        // Take care of any launching providers waiting for this process.
10518        if (checkAppInLaunchingProvidersLocked(app, false)) {
10519            restart = true;
10520        }
10521
10522        // Unregister from connected content providers.
10523        if (!app.conProviders.isEmpty()) {
10524            for (int i=0; i<app.conProviders.size(); i++) {
10525                ContentProviderConnection conn = app.conProviders.get(i);
10526                conn.provider.connections.remove(conn);
10527            }
10528            app.conProviders.clear();
10529        }
10530
10531        // At this point there may be remaining entries in mLaunchingProviders
10532        // where we were the only one waiting, so they are no longer of use.
10533        // Look for these and clean up if found.
10534        // XXX Commented out for now.  Trying to figure out a way to reproduce
10535        // the actual situation to identify what is actually going on.
10536        if (false) {
10537            for (int i=0; i<mLaunchingProviders.size(); i++) {
10538                ContentProviderRecord cpr = (ContentProviderRecord)
10539                        mLaunchingProviders.get(i);
10540                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10541                    synchronized (cpr) {
10542                        cpr.launchingApp = null;
10543                        cpr.notifyAll();
10544                    }
10545                }
10546            }
10547        }
10548
10549        skipCurrentReceiverLocked(app);
10550
10551        // Unregister any receivers.
10552        if (app.receivers.size() > 0) {
10553            Iterator<ReceiverList> it = app.receivers.iterator();
10554            while (it.hasNext()) {
10555                removeReceiverLocked(it.next());
10556            }
10557            app.receivers.clear();
10558        }
10559
10560        // If the app is undergoing backup, tell the backup manager about it
10561        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10562            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10563            try {
10564                IBackupManager bm = IBackupManager.Stub.asInterface(
10565                        ServiceManager.getService(Context.BACKUP_SERVICE));
10566                bm.agentDisconnected(app.info.packageName);
10567            } catch (RemoteException e) {
10568                // can't happen; backup manager is local
10569            }
10570        }
10571
10572        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10573            ProcessChangeItem item = mPendingProcessChanges.get(i);
10574            if (item.pid == app.pid) {
10575                mPendingProcessChanges.remove(i);
10576                mAvailProcessChanges.add(item);
10577            }
10578        }
10579        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10580
10581        // If the caller is restarting this app, then leave it in its
10582        // current lists and let the caller take care of it.
10583        if (restarting) {
10584            return;
10585        }
10586
10587        if (!app.persistent || app.isolated) {
10588            if (DEBUG_PROCESSES) Slog.v(TAG,
10589                    "Removing non-persistent process during cleanup: " + app);
10590            mProcessNames.remove(app.processName, app.uid);
10591            mIsolatedProcesses.remove(app.uid);
10592            if (mHeavyWeightProcess == app) {
10593                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10594                        mHeavyWeightProcess.userId, 0));
10595                mHeavyWeightProcess = null;
10596            }
10597        } else if (!app.removed) {
10598            // This app is persistent, so we need to keep its record around.
10599            // If it is not already on the pending app list, add it there
10600            // and start a new process for it.
10601            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10602                mPersistentStartingProcesses.add(app);
10603                restart = true;
10604            }
10605        }
10606        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10607                "Clean-up removing on hold: " + app);
10608        mProcessesOnHold.remove(app);
10609
10610        if (app == mHomeProcess) {
10611            mHomeProcess = null;
10612        }
10613        if (app == mPreviousProcess) {
10614            mPreviousProcess = null;
10615        }
10616
10617        if (restart && !app.isolated) {
10618            // We have components that still need to be running in the
10619            // process, so re-launch it.
10620            mProcessNames.put(app.processName, app.uid, app);
10621            startProcessLocked(app, "restart", app.processName);
10622        } else if (app.pid > 0 && app.pid != MY_PID) {
10623            // Goodbye!
10624            synchronized (mPidsSelfLocked) {
10625                mPidsSelfLocked.remove(app.pid);
10626                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10627            }
10628            app.setPid(0);
10629        }
10630    }
10631
10632    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10633        // Look through the content providers we are waiting to have launched,
10634        // and if any run in this process then either schedule a restart of
10635        // the process or kill the client waiting for it if this process has
10636        // gone bad.
10637        int NL = mLaunchingProviders.size();
10638        boolean restart = false;
10639        for (int i=0; i<NL; i++) {
10640            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10641            if (cpr.launchingApp == app) {
10642                if (!alwaysBad && !app.bad) {
10643                    restart = true;
10644                } else {
10645                    removeDyingProviderLocked(app, cpr, true);
10646                    // cpr should have been removed from mLaunchingProviders
10647                    NL = mLaunchingProviders.size();
10648                    i--;
10649                }
10650            }
10651        }
10652        return restart;
10653    }
10654
10655    // =========================================================
10656    // SERVICES
10657    // =========================================================
10658
10659    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10660            int flags) {
10661        enforceNotIsolatedCaller("getServices");
10662        synchronized (this) {
10663            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10664        }
10665    }
10666
10667    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10668        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10669        synchronized (this) {
10670            return mServices.getRunningServiceControlPanelLocked(name);
10671        }
10672    }
10673
10674    public ComponentName startService(IApplicationThread caller, Intent service,
10675            String resolvedType, int userId) {
10676        enforceNotIsolatedCaller("startService");
10677        // Refuse possible leaked file descriptors
10678        if (service != null && service.hasFileDescriptors() == true) {
10679            throw new IllegalArgumentException("File descriptors passed in Intent");
10680        }
10681
10682        if (DEBUG_SERVICE)
10683            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10684        synchronized(this) {
10685            final int callingPid = Binder.getCallingPid();
10686            final int callingUid = Binder.getCallingUid();
10687            checkValidCaller(callingUid, userId);
10688            final long origId = Binder.clearCallingIdentity();
10689            ComponentName res = mServices.startServiceLocked(caller, service,
10690                    resolvedType, callingPid, callingUid, userId);
10691            Binder.restoreCallingIdentity(origId);
10692            return res;
10693        }
10694    }
10695
10696    ComponentName startServiceInPackage(int uid,
10697            Intent service, String resolvedType, int userId) {
10698        synchronized(this) {
10699            if (DEBUG_SERVICE)
10700                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10701            final long origId = Binder.clearCallingIdentity();
10702            ComponentName res = mServices.startServiceLocked(null, service,
10703                    resolvedType, -1, uid, userId);
10704            Binder.restoreCallingIdentity(origId);
10705            return res;
10706        }
10707    }
10708
10709    public int stopService(IApplicationThread caller, Intent service,
10710            String resolvedType, int userId) {
10711        enforceNotIsolatedCaller("stopService");
10712        // Refuse possible leaked file descriptors
10713        if (service != null && service.hasFileDescriptors() == true) {
10714            throw new IllegalArgumentException("File descriptors passed in Intent");
10715        }
10716
10717        checkValidCaller(Binder.getCallingUid(), userId);
10718
10719        synchronized(this) {
10720            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10721        }
10722    }
10723
10724    public IBinder peekService(Intent service, String resolvedType) {
10725        enforceNotIsolatedCaller("peekService");
10726        // Refuse possible leaked file descriptors
10727        if (service != null && service.hasFileDescriptors() == true) {
10728            throw new IllegalArgumentException("File descriptors passed in Intent");
10729        }
10730        synchronized(this) {
10731            return mServices.peekServiceLocked(service, resolvedType);
10732        }
10733    }
10734
10735    public boolean stopServiceToken(ComponentName className, IBinder token,
10736            int startId) {
10737        synchronized(this) {
10738            return mServices.stopServiceTokenLocked(className, token, startId);
10739        }
10740    }
10741
10742    public void setServiceForeground(ComponentName className, IBinder token,
10743            int id, Notification notification, boolean removeNotification) {
10744        synchronized(this) {
10745            mServices.setServiceForegroundLocked(className, token, id, notification,
10746                    removeNotification);
10747        }
10748    }
10749
10750    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
10751            boolean requireFull, String name, String callerPackage) {
10752        synchronized(this) {
10753            return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll,
10754                    requireFull, name, callerPackage);
10755        }
10756    }
10757
10758    int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll,
10759            boolean requireFull, String name, String callerPackage) {
10760        final int callingUserId = UserHandle.getUserId(callingUid);
10761        if (callingUserId != userId) {
10762            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10763                if ((requireFull || checkComponentPermission(
10764                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10765                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
10766                        && checkComponentPermission(
10767                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10768                                callingPid, callingUid, -1, true)
10769                                != PackageManager.PERMISSION_GRANTED) {
10770                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
10771                        // In this case, they would like to just execute as their
10772                        // owner user instead of failing.
10773                        userId = callingUserId;
10774                    } else {
10775                        StringBuilder builder = new StringBuilder(128);
10776                        builder.append("Permission Denial: ");
10777                        builder.append(name);
10778                        if (callerPackage != null) {
10779                            builder.append(" from ");
10780                            builder.append(callerPackage);
10781                        }
10782                        builder.append(" asks to run as user ");
10783                        builder.append(userId);
10784                        builder.append(" but is calling from user ");
10785                        builder.append(UserHandle.getUserId(callingUid));
10786                        builder.append("; this requires ");
10787                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
10788                        if (!requireFull) {
10789                            builder.append("or");
10790                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
10791                        }
10792                        String msg = builder.toString();
10793                        Slog.w(TAG, msg);
10794                        throw new SecurityException(msg);
10795                    }
10796                }
10797            }
10798            if (userId == UserHandle.USER_CURRENT
10799                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
10800                userId = mCurrentUserId;
10801            }
10802            if (!allowAll && userId < 0) {
10803                throw new IllegalArgumentException(
10804                        "Call does not support special user #" + userId);
10805            }
10806        }
10807        return userId;
10808    }
10809
10810    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10811            String className, int flags) {
10812        boolean result = false;
10813        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10814            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10815                if (ActivityManager.checkUidPermission(
10816                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10817                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10818                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10819                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10820                            + " requests FLAG_SINGLE_USER, but app does not hold "
10821                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10822                    Slog.w(TAG, msg);
10823                    throw new SecurityException(msg);
10824                }
10825                result = true;
10826            }
10827        } else if (componentProcessName == aInfo.packageName) {
10828            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10829        } else if ("system".equals(componentProcessName)) {
10830            result = true;
10831        }
10832        if (DEBUG_MU) {
10833            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10834                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10835        }
10836        return result;
10837    }
10838
10839    public int bindService(IApplicationThread caller, IBinder token,
10840            Intent service, String resolvedType,
10841            IServiceConnection connection, int flags, int userId) {
10842        enforceNotIsolatedCaller("bindService");
10843        // Refuse possible leaked file descriptors
10844        if (service != null && service.hasFileDescriptors() == true) {
10845            throw new IllegalArgumentException("File descriptors passed in Intent");
10846        }
10847
10848        synchronized(this) {
10849            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10850                    connection, flags, userId);
10851        }
10852    }
10853
10854    public boolean unbindService(IServiceConnection connection) {
10855        synchronized (this) {
10856            return mServices.unbindServiceLocked(connection);
10857        }
10858    }
10859
10860    public void publishService(IBinder token, Intent intent, IBinder service) {
10861        // Refuse possible leaked file descriptors
10862        if (intent != null && intent.hasFileDescriptors() == true) {
10863            throw new IllegalArgumentException("File descriptors passed in Intent");
10864        }
10865
10866        synchronized(this) {
10867            if (!(token instanceof ServiceRecord)) {
10868                throw new IllegalArgumentException("Invalid service token");
10869            }
10870            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
10871        }
10872    }
10873
10874    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10875        // Refuse possible leaked file descriptors
10876        if (intent != null && intent.hasFileDescriptors() == true) {
10877            throw new IllegalArgumentException("File descriptors passed in Intent");
10878        }
10879
10880        synchronized(this) {
10881            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
10882        }
10883    }
10884
10885    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10886        synchronized(this) {
10887            if (!(token instanceof ServiceRecord)) {
10888                throw new IllegalArgumentException("Invalid service token");
10889            }
10890            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
10891        }
10892    }
10893
10894    // =========================================================
10895    // BACKUP AND RESTORE
10896    // =========================================================
10897
10898    // Cause the target app to be launched if necessary and its backup agent
10899    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10900    // activity manager to announce its creation.
10901    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10902        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10903        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10904
10905        synchronized(this) {
10906            // !!! TODO: currently no check here that we're already bound
10907            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10908            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10909            synchronized (stats) {
10910                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10911            }
10912
10913            // Backup agent is now in use, its package can't be stopped.
10914            try {
10915                AppGlobals.getPackageManager().setPackageStoppedState(
10916                        app.packageName, false, UserHandle.getUserId(app.uid));
10917            } catch (RemoteException e) {
10918            } catch (IllegalArgumentException e) {
10919                Slog.w(TAG, "Failed trying to unstop package "
10920                        + app.packageName + ": " + e);
10921            }
10922
10923            BackupRecord r = new BackupRecord(ss, app, backupMode);
10924            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10925                    ? new ComponentName(app.packageName, app.backupAgentName)
10926                    : new ComponentName("android", "FullBackupAgent");
10927            // startProcessLocked() returns existing proc's record if it's already running
10928            ProcessRecord proc = startProcessLocked(app.processName, app,
10929                    false, 0, "backup", hostingName, false, false);
10930            if (proc == null) {
10931                Slog.e(TAG, "Unable to start backup agent process " + r);
10932                return false;
10933            }
10934
10935            r.app = proc;
10936            mBackupTarget = r;
10937            mBackupAppName = app.packageName;
10938
10939            // Try not to kill the process during backup
10940            updateOomAdjLocked(proc);
10941
10942            // If the process is already attached, schedule the creation of the backup agent now.
10943            // If it is not yet live, this will be done when it attaches to the framework.
10944            if (proc.thread != null) {
10945                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
10946                try {
10947                    proc.thread.scheduleCreateBackupAgent(app,
10948                            compatibilityInfoForPackageLocked(app), backupMode);
10949                } catch (RemoteException e) {
10950                    // Will time out on the backup manager side
10951                }
10952            } else {
10953                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
10954            }
10955            // Invariants: at this point, the target app process exists and the application
10956            // is either already running or in the process of coming up.  mBackupTarget and
10957            // mBackupAppName describe the app, so that when it binds back to the AM we
10958            // know that it's scheduled for a backup-agent operation.
10959        }
10960
10961        return true;
10962    }
10963
10964    // A backup agent has just come up
10965    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10966        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
10967                + " = " + agent);
10968
10969        synchronized(this) {
10970            if (!agentPackageName.equals(mBackupAppName)) {
10971                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10972                return;
10973            }
10974        }
10975
10976        long oldIdent = Binder.clearCallingIdentity();
10977        try {
10978            IBackupManager bm = IBackupManager.Stub.asInterface(
10979                    ServiceManager.getService(Context.BACKUP_SERVICE));
10980            bm.agentConnected(agentPackageName, agent);
10981        } catch (RemoteException e) {
10982            // can't happen; the backup manager service is local
10983        } catch (Exception e) {
10984            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10985            e.printStackTrace();
10986        } finally {
10987            Binder.restoreCallingIdentity(oldIdent);
10988        }
10989    }
10990
10991    // done with this agent
10992    public void unbindBackupAgent(ApplicationInfo appInfo) {
10993        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
10994        if (appInfo == null) {
10995            Slog.w(TAG, "unbind backup agent for null app");
10996            return;
10997        }
10998
10999        synchronized(this) {
11000            if (mBackupAppName == null) {
11001                Slog.w(TAG, "Unbinding backup agent with no active backup");
11002                return;
11003            }
11004
11005            if (!mBackupAppName.equals(appInfo.packageName)) {
11006                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11007                return;
11008            }
11009
11010            ProcessRecord proc = mBackupTarget.app;
11011            mBackupTarget = null;
11012            mBackupAppName = null;
11013
11014            // Not backing this app up any more; reset its OOM adjustment
11015            updateOomAdjLocked(proc);
11016
11017            // If the app crashed during backup, 'thread' will be null here
11018            if (proc.thread != null) {
11019                try {
11020                    proc.thread.scheduleDestroyBackupAgent(appInfo,
11021                            compatibilityInfoForPackageLocked(appInfo));
11022                } catch (Exception e) {
11023                    Slog.e(TAG, "Exception when unbinding backup agent:");
11024                    e.printStackTrace();
11025                }
11026            }
11027        }
11028    }
11029    // =========================================================
11030    // BROADCASTS
11031    // =========================================================
11032
11033    private final List getStickiesLocked(String action, IntentFilter filter,
11034            List cur, int userId) {
11035        final ContentResolver resolver = mContext.getContentResolver();
11036        HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11037        if (stickies == null) {
11038            return cur;
11039        }
11040        final ArrayList<Intent> list = stickies.get(action);
11041        if (list == null) {
11042            return cur;
11043        }
11044        int N = list.size();
11045        for (int i=0; i<N; i++) {
11046            Intent intent = list.get(i);
11047            if (filter.match(resolver, intent, true, TAG) >= 0) {
11048                if (cur == null) {
11049                    cur = new ArrayList<Intent>();
11050                }
11051                cur.add(intent);
11052            }
11053        }
11054        return cur;
11055    }
11056
11057    boolean isPendingBroadcastProcessLocked(int pid) {
11058        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11059                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11060    }
11061
11062    void skipPendingBroadcastLocked(int pid) {
11063            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11064            for (BroadcastQueue queue : mBroadcastQueues) {
11065                queue.skipPendingBroadcastLocked(pid);
11066            }
11067    }
11068
11069    // The app just attached; send any pending broadcasts that it should receive
11070    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11071        boolean didSomething = false;
11072        for (BroadcastQueue queue : mBroadcastQueues) {
11073            didSomething |= queue.sendPendingBroadcastsLocked(app);
11074        }
11075        return didSomething;
11076    }
11077
11078    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11079            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11080        enforceNotIsolatedCaller("registerReceiver");
11081        int callingUid;
11082        int callingPid;
11083        synchronized(this) {
11084            ProcessRecord callerApp = null;
11085            if (caller != null) {
11086                callerApp = getRecordForAppLocked(caller);
11087                if (callerApp == null) {
11088                    throw new SecurityException(
11089                            "Unable to find app for caller " + caller
11090                            + " (pid=" + Binder.getCallingPid()
11091                            + ") when registering receiver " + receiver);
11092                }
11093                if (callerApp.info.uid != Process.SYSTEM_UID &&
11094                        !callerApp.pkgList.contains(callerPackage)) {
11095                    throw new SecurityException("Given caller package " + callerPackage
11096                            + " is not running in process " + callerApp);
11097                }
11098                callingUid = callerApp.info.uid;
11099                callingPid = callerApp.pid;
11100            } else {
11101                callerPackage = null;
11102                callingUid = Binder.getCallingUid();
11103                callingPid = Binder.getCallingPid();
11104            }
11105
11106            userId = this.handleIncomingUserLocked(callingPid, callingUid, userId,
11107                    true, true, "registerReceiver", callerPackage);
11108
11109            List allSticky = null;
11110
11111            // Look for any matching sticky broadcasts...
11112            Iterator actions = filter.actionsIterator();
11113            if (actions != null) {
11114                while (actions.hasNext()) {
11115                    String action = (String)actions.next();
11116                    allSticky = getStickiesLocked(action, filter, allSticky,
11117                            UserHandle.USER_ALL);
11118                    allSticky = getStickiesLocked(action, filter, allSticky,
11119                            UserHandle.getUserId(callingUid));
11120                }
11121            } else {
11122                allSticky = getStickiesLocked(null, filter, allSticky,
11123                        UserHandle.USER_ALL);
11124                allSticky = getStickiesLocked(null, filter, allSticky,
11125                        UserHandle.getUserId(callingUid));
11126            }
11127
11128            // The first sticky in the list is returned directly back to
11129            // the client.
11130            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11131
11132            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11133                    + ": " + sticky);
11134
11135            if (receiver == null) {
11136                return sticky;
11137            }
11138
11139            ReceiverList rl
11140                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11141            if (rl == null) {
11142                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11143                        userId, receiver);
11144                if (rl.app != null) {
11145                    rl.app.receivers.add(rl);
11146                } else {
11147                    try {
11148                        receiver.asBinder().linkToDeath(rl, 0);
11149                    } catch (RemoteException e) {
11150                        return sticky;
11151                    }
11152                    rl.linkedToDeath = true;
11153                }
11154                mRegisteredReceivers.put(receiver.asBinder(), rl);
11155            } else if (rl.uid != callingUid) {
11156                throw new IllegalArgumentException(
11157                        "Receiver requested to register for uid " + callingUid
11158                        + " was previously registered for uid " + rl.uid);
11159            } else if (rl.pid != callingPid) {
11160                throw new IllegalArgumentException(
11161                        "Receiver requested to register for pid " + callingPid
11162                        + " was previously registered for pid " + rl.pid);
11163            } else if (rl.userId != userId) {
11164                throw new IllegalArgumentException(
11165                        "Receiver requested to register for user " + userId
11166                        + " was previously registered for user " + rl.userId);
11167            }
11168            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11169                    permission, callingUid, userId);
11170            rl.add(bf);
11171            if (!bf.debugCheck()) {
11172                Slog.w(TAG, "==> For Dynamic broadast");
11173            }
11174            mReceiverResolver.addFilter(bf);
11175
11176            // Enqueue broadcasts for all existing stickies that match
11177            // this filter.
11178            if (allSticky != null) {
11179                ArrayList receivers = new ArrayList();
11180                receivers.add(bf);
11181
11182                int N = allSticky.size();
11183                for (int i=0; i<N; i++) {
11184                    Intent intent = (Intent)allSticky.get(i);
11185                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11186                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11187                            null, -1, -1, null, receivers, null, 0, null, null,
11188                            false, true, true, -1);
11189                    queue.enqueueParallelBroadcastLocked(r);
11190                    queue.scheduleBroadcastsLocked();
11191                }
11192            }
11193
11194            return sticky;
11195        }
11196    }
11197
11198    public void unregisterReceiver(IIntentReceiver receiver) {
11199        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11200
11201        final long origId = Binder.clearCallingIdentity();
11202        try {
11203            boolean doTrim = false;
11204
11205            synchronized(this) {
11206                ReceiverList rl
11207                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11208                if (rl != null) {
11209                    if (rl.curBroadcast != null) {
11210                        BroadcastRecord r = rl.curBroadcast;
11211                        final boolean doNext = finishReceiverLocked(
11212                                receiver.asBinder(), r.resultCode, r.resultData,
11213                                r.resultExtras, r.resultAbort, true);
11214                        if (doNext) {
11215                            doTrim = true;
11216                            r.queue.processNextBroadcast(false);
11217                        }
11218                    }
11219
11220                    if (rl.app != null) {
11221                        rl.app.receivers.remove(rl);
11222                    }
11223                    removeReceiverLocked(rl);
11224                    if (rl.linkedToDeath) {
11225                        rl.linkedToDeath = false;
11226                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11227                    }
11228                }
11229            }
11230
11231            // If we actually concluded any broadcasts, we might now be able
11232            // to trim the recipients' apps from our working set
11233            if (doTrim) {
11234                trimApplications();
11235                return;
11236            }
11237
11238        } finally {
11239            Binder.restoreCallingIdentity(origId);
11240        }
11241    }
11242
11243    void removeReceiverLocked(ReceiverList rl) {
11244        mRegisteredReceivers.remove(rl.receiver.asBinder());
11245        int N = rl.size();
11246        for (int i=0; i<N; i++) {
11247            mReceiverResolver.removeFilter(rl.get(i));
11248        }
11249    }
11250
11251    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11252        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11253            ProcessRecord r = mLruProcesses.get(i);
11254            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11255                try {
11256                    r.thread.dispatchPackageBroadcast(cmd, packages);
11257                } catch (RemoteException ex) {
11258                }
11259            }
11260        }
11261    }
11262
11263    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11264            int[] users) {
11265        List<ResolveInfo> receivers = null;
11266        try {
11267            HashSet<ComponentName> singleUserReceivers = null;
11268            boolean scannedFirstReceivers = false;
11269            for (int user : users) {
11270                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11271                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11272                if (newReceivers != null && newReceivers.size() == 0) {
11273                    newReceivers = null;
11274                }
11275                if (receivers == null) {
11276                    receivers = newReceivers;
11277                } else if (newReceivers != null) {
11278                    // We need to concatenate the additional receivers
11279                    // found with what we have do far.  This would be easy,
11280                    // but we also need to de-dup any receivers that are
11281                    // singleUser.
11282                    if (!scannedFirstReceivers) {
11283                        // Collect any single user receivers we had already retrieved.
11284                        scannedFirstReceivers = true;
11285                        for (int i=0; i<receivers.size(); i++) {
11286                            ResolveInfo ri = receivers.get(i);
11287                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11288                                ComponentName cn = new ComponentName(
11289                                        ri.activityInfo.packageName, ri.activityInfo.name);
11290                                if (singleUserReceivers == null) {
11291                                    singleUserReceivers = new HashSet<ComponentName>();
11292                                }
11293                                singleUserReceivers.add(cn);
11294                            }
11295                        }
11296                    }
11297                    // Add the new results to the existing results, tracking
11298                    // and de-dupping single user receivers.
11299                    for (int i=0; i<newReceivers.size(); i++) {
11300                        ResolveInfo ri = receivers.get(i);
11301                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11302                            ComponentName cn = new ComponentName(
11303                                    ri.activityInfo.packageName, ri.activityInfo.name);
11304                            if (singleUserReceivers == null) {
11305                                singleUserReceivers = new HashSet<ComponentName>();
11306                            }
11307                            if (!singleUserReceivers.contains(cn)) {
11308                                singleUserReceivers.add(cn);
11309                                receivers.add(ri);
11310                            }
11311                        } else {
11312                            receivers.add(ri);
11313                        }
11314                    }
11315                }
11316            }
11317        } catch (RemoteException ex) {
11318            // pm is in same process, this will never happen.
11319        }
11320        return receivers;
11321    }
11322
11323    private final int broadcastIntentLocked(ProcessRecord callerApp,
11324            String callerPackage, Intent intent, String resolvedType,
11325            IIntentReceiver resultTo, int resultCode, String resultData,
11326            Bundle map, String requiredPermission,
11327            boolean ordered, boolean sticky, int callingPid, int callingUid,
11328            int userId) {
11329        intent = new Intent(intent);
11330
11331        // By default broadcasts do not go to stopped apps.
11332        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11333
11334        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11335            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11336            + " ordered=" + ordered + " userid=" + userId);
11337        if ((resultTo != null) && !ordered) {
11338            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11339        }
11340
11341        userId = handleIncomingUserLocked(callingPid, callingUid, userId,
11342                true, false, "broadcast", callerPackage);
11343
11344        // Make sure that the user who is receiving this broadcast is started
11345        // If not, we will just skip it.
11346        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11347            Slog.w(TAG, "Skipping broadcast of " + intent
11348                    + ": user " + userId + " is stopped");
11349            return ActivityManager.BROADCAST_SUCCESS;
11350        }
11351
11352        /*
11353         * Prevent non-system code (defined here to be non-persistent
11354         * processes) from sending protected broadcasts.
11355         */
11356        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11357            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11358            callingUid == 0) {
11359            // Always okay.
11360        } else if (callerApp == null || !callerApp.persistent) {
11361            try {
11362                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11363                        intent.getAction())) {
11364                    String msg = "Permission Denial: not allowed to send broadcast "
11365                            + intent.getAction() + " from pid="
11366                            + callingPid + ", uid=" + callingUid;
11367                    Slog.w(TAG, msg);
11368                    throw new SecurityException(msg);
11369                }
11370            } catch (RemoteException e) {
11371                Slog.w(TAG, "Remote exception", e);
11372                return ActivityManager.BROADCAST_SUCCESS;
11373            }
11374        }
11375
11376        // Handle special intents: if this broadcast is from the package
11377        // manager about a package being removed, we need to remove all of
11378        // its activities from the history stack.
11379        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11380                intent.getAction());
11381        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11382                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11383                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11384                || uidRemoved) {
11385            if (checkComponentPermission(
11386                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11387                    callingPid, callingUid, -1, true)
11388                    == PackageManager.PERMISSION_GRANTED) {
11389                if (uidRemoved) {
11390                    final Bundle intentExtras = intent.getExtras();
11391                    final int uid = intentExtras != null
11392                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11393                    if (uid >= 0) {
11394                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11395                        synchronized (bs) {
11396                            bs.removeUidStatsLocked(uid);
11397                        }
11398                    }
11399                } else {
11400                    // If resources are unavailable just force stop all
11401                    // those packages and flush the attribute cache as well.
11402                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11403                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11404                        if (list != null && (list.length > 0)) {
11405                            for (String pkg : list) {
11406                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11407                            }
11408                            sendPackageBroadcastLocked(
11409                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11410                        }
11411                    } else {
11412                        Uri data = intent.getData();
11413                        String ssp;
11414                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11415                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11416                                forceStopPackageLocked(ssp,
11417                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11418                                        false, userId);
11419                            }
11420                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11421                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11422                                        new String[] {ssp}, userId);
11423                            }
11424                        }
11425                    }
11426                }
11427            } else {
11428                String msg = "Permission Denial: " + intent.getAction()
11429                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11430                        + ", uid=" + callingUid + ")"
11431                        + " requires "
11432                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11433                Slog.w(TAG, msg);
11434                throw new SecurityException(msg);
11435            }
11436
11437        // Special case for adding a package: by default turn on compatibility
11438        // mode.
11439        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11440            Uri data = intent.getData();
11441            String ssp;
11442            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11443                mCompatModePackages.handlePackageAddedLocked(ssp,
11444                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11445            }
11446        }
11447
11448        /*
11449         * If this is the time zone changed action, queue up a message that will reset the timezone
11450         * of all currently running processes. This message will get queued up before the broadcast
11451         * happens.
11452         */
11453        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11454            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11455        }
11456
11457        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11458            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11459        }
11460
11461        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11462            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11463            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11464        }
11465
11466        // Add to the sticky list if requested.
11467        if (sticky) {
11468            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11469                    callingPid, callingUid)
11470                    != PackageManager.PERMISSION_GRANTED) {
11471                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11472                        + callingPid + ", uid=" + callingUid
11473                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11474                Slog.w(TAG, msg);
11475                throw new SecurityException(msg);
11476            }
11477            if (requiredPermission != null) {
11478                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11479                        + " and enforce permission " + requiredPermission);
11480                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11481            }
11482            if (intent.getComponent() != null) {
11483                throw new SecurityException(
11484                        "Sticky broadcasts can't target a specific component");
11485            }
11486            // We use userId directly here, since the "all" target is maintained
11487            // as a separate set of sticky broadcasts.
11488            if (userId != UserHandle.USER_ALL) {
11489                // But first, if this is not a broadcast to all users, then
11490                // make sure it doesn't conflict with an existing broadcast to
11491                // all users.
11492                HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11493                        UserHandle.USER_ALL);
11494                if (stickies != null) {
11495                    ArrayList<Intent> list = stickies.get(intent.getAction());
11496                    if (list != null) {
11497                        int N = list.size();
11498                        int i;
11499                        for (i=0; i<N; i++) {
11500                            if (intent.filterEquals(list.get(i))) {
11501                                throw new IllegalArgumentException(
11502                                        "Sticky broadcast " + intent + " for user "
11503                                        + userId + " conflicts with existing global broadcast");
11504                            }
11505                        }
11506                    }
11507                }
11508            }
11509            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11510            if (stickies == null) {
11511                stickies = new HashMap<String, ArrayList<Intent>>();
11512                mStickyBroadcasts.put(userId, stickies);
11513            }
11514            ArrayList<Intent> list = stickies.get(intent.getAction());
11515            if (list == null) {
11516                list = new ArrayList<Intent>();
11517                stickies.put(intent.getAction(), list);
11518            }
11519            int N = list.size();
11520            int i;
11521            for (i=0; i<N; i++) {
11522                if (intent.filterEquals(list.get(i))) {
11523                    // This sticky already exists, replace it.
11524                    list.set(i, new Intent(intent));
11525                    break;
11526                }
11527            }
11528            if (i >= N) {
11529                list.add(new Intent(intent));
11530            }
11531        }
11532
11533        int[] users;
11534        if (userId == UserHandle.USER_ALL) {
11535            // Caller wants broadcast to go to all started users.
11536            users = new int[mStartedUsers.size()];
11537            for (int i=0; i<mStartedUsers.size(); i++) {
11538                users[i] = mStartedUsers.keyAt(i);
11539            }
11540        } else {
11541            // Caller wants broadcast to go to one specific user.
11542            users = new int[] {userId};
11543        }
11544
11545        // Figure out who all will receive this broadcast.
11546        List receivers = null;
11547        List<BroadcastFilter> registeredReceivers = null;
11548        // Need to resolve the intent to interested receivers...
11549        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11550                 == 0) {
11551            receivers = collectReceiverComponents(intent, resolvedType, users);
11552        }
11553        if (intent.getComponent() == null) {
11554            registeredReceivers = mReceiverResolver.queryIntent(intent,
11555                    resolvedType, false, userId);
11556        }
11557
11558        final boolean replacePending =
11559                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11560
11561        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11562                + " replacePending=" + replacePending);
11563
11564        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11565        if (!ordered && NR > 0) {
11566            // If we are not serializing this broadcast, then send the
11567            // registered receivers separately so they don't wait for the
11568            // components to be launched.
11569            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11570            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11571                    callerPackage, callingPid, callingUid, requiredPermission,
11572                    registeredReceivers, resultTo, resultCode, resultData, map,
11573                    ordered, sticky, false, userId);
11574            if (DEBUG_BROADCAST) Slog.v(
11575                    TAG, "Enqueueing parallel broadcast " + r);
11576            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11577            if (!replaced) {
11578                queue.enqueueParallelBroadcastLocked(r);
11579                queue.scheduleBroadcastsLocked();
11580            }
11581            registeredReceivers = null;
11582            NR = 0;
11583        }
11584
11585        // Merge into one list.
11586        int ir = 0;
11587        if (receivers != null) {
11588            // A special case for PACKAGE_ADDED: do not allow the package
11589            // being added to see this broadcast.  This prevents them from
11590            // using this as a back door to get run as soon as they are
11591            // installed.  Maybe in the future we want to have a special install
11592            // broadcast or such for apps, but we'd like to deliberately make
11593            // this decision.
11594            String skipPackages[] = null;
11595            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11596                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11597                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11598                Uri data = intent.getData();
11599                if (data != null) {
11600                    String pkgName = data.getSchemeSpecificPart();
11601                    if (pkgName != null) {
11602                        skipPackages = new String[] { pkgName };
11603                    }
11604                }
11605            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11606                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11607            }
11608            if (skipPackages != null && (skipPackages.length > 0)) {
11609                for (String skipPackage : skipPackages) {
11610                    if (skipPackage != null) {
11611                        int NT = receivers.size();
11612                        for (int it=0; it<NT; it++) {
11613                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11614                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11615                                receivers.remove(it);
11616                                it--;
11617                                NT--;
11618                            }
11619                        }
11620                    }
11621                }
11622            }
11623
11624            int NT = receivers != null ? receivers.size() : 0;
11625            int it = 0;
11626            ResolveInfo curt = null;
11627            BroadcastFilter curr = null;
11628            while (it < NT && ir < NR) {
11629                if (curt == null) {
11630                    curt = (ResolveInfo)receivers.get(it);
11631                }
11632                if (curr == null) {
11633                    curr = registeredReceivers.get(ir);
11634                }
11635                if (curr.getPriority() >= curt.priority) {
11636                    // Insert this broadcast record into the final list.
11637                    receivers.add(it, curr);
11638                    ir++;
11639                    curr = null;
11640                    it++;
11641                    NT++;
11642                } else {
11643                    // Skip to the next ResolveInfo in the final list.
11644                    it++;
11645                    curt = null;
11646                }
11647            }
11648        }
11649        while (ir < NR) {
11650            if (receivers == null) {
11651                receivers = new ArrayList();
11652            }
11653            receivers.add(registeredReceivers.get(ir));
11654            ir++;
11655        }
11656
11657        if ((receivers != null && receivers.size() > 0)
11658                || resultTo != null) {
11659            BroadcastQueue queue = broadcastQueueForIntent(intent);
11660            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11661                    callerPackage, callingPid, callingUid, requiredPermission,
11662                    receivers, resultTo, resultCode, resultData, map, ordered,
11663                    sticky, false, userId);
11664            if (DEBUG_BROADCAST) Slog.v(
11665                    TAG, "Enqueueing ordered broadcast " + r
11666                    + ": prev had " + queue.mOrderedBroadcasts.size());
11667            if (DEBUG_BROADCAST) {
11668                int seq = r.intent.getIntExtra("seq", -1);
11669                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11670            }
11671            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11672            if (!replaced) {
11673                queue.enqueueOrderedBroadcastLocked(r);
11674                queue.scheduleBroadcastsLocked();
11675            }
11676        }
11677
11678        return ActivityManager.BROADCAST_SUCCESS;
11679    }
11680
11681    final Intent verifyBroadcastLocked(Intent intent) {
11682        // Refuse possible leaked file descriptors
11683        if (intent != null && intent.hasFileDescriptors() == true) {
11684            throw new IllegalArgumentException("File descriptors passed in Intent");
11685        }
11686
11687        int flags = intent.getFlags();
11688
11689        if (!mProcessesReady) {
11690            // if the caller really truly claims to know what they're doing, go
11691            // ahead and allow the broadcast without launching any receivers
11692            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11693                intent = new Intent(intent);
11694                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11695            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11696                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11697                        + " before boot completion");
11698                throw new IllegalStateException("Cannot broadcast before boot completed");
11699            }
11700        }
11701
11702        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11703            throw new IllegalArgumentException(
11704                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11705        }
11706
11707        return intent;
11708    }
11709
11710    public final int broadcastIntent(IApplicationThread caller,
11711            Intent intent, String resolvedType, IIntentReceiver resultTo,
11712            int resultCode, String resultData, Bundle map,
11713            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11714        enforceNotIsolatedCaller("broadcastIntent");
11715        synchronized(this) {
11716            intent = verifyBroadcastLocked(intent);
11717
11718            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11719            final int callingPid = Binder.getCallingPid();
11720            final int callingUid = Binder.getCallingUid();
11721            final long origId = Binder.clearCallingIdentity();
11722            int res = broadcastIntentLocked(callerApp,
11723                    callerApp != null ? callerApp.info.packageName : null,
11724                    intent, resolvedType, resultTo,
11725                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11726                    callingPid, callingUid, userId);
11727            Binder.restoreCallingIdentity(origId);
11728            return res;
11729        }
11730    }
11731
11732    int broadcastIntentInPackage(String packageName, int uid,
11733            Intent intent, String resolvedType, IIntentReceiver resultTo,
11734            int resultCode, String resultData, Bundle map,
11735            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11736        synchronized(this) {
11737            intent = verifyBroadcastLocked(intent);
11738
11739            final long origId = Binder.clearCallingIdentity();
11740            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11741                    resultTo, resultCode, resultData, map, requiredPermission,
11742                    serialized, sticky, -1, uid, userId);
11743            Binder.restoreCallingIdentity(origId);
11744            return res;
11745        }
11746    }
11747
11748    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11749        // Refuse possible leaked file descriptors
11750        if (intent != null && intent.hasFileDescriptors() == true) {
11751            throw new IllegalArgumentException("File descriptors passed in Intent");
11752        }
11753
11754        userId = handleIncomingUserLocked(Binder.getCallingPid(),
11755                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
11756
11757        synchronized(this) {
11758            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11759                    != PackageManager.PERMISSION_GRANTED) {
11760                String msg = "Permission Denial: unbroadcastIntent() from pid="
11761                        + Binder.getCallingPid()
11762                        + ", uid=" + Binder.getCallingUid()
11763                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11764                Slog.w(TAG, msg);
11765                throw new SecurityException(msg);
11766            }
11767            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11768            if (stickies != null) {
11769                ArrayList<Intent> list = stickies.get(intent.getAction());
11770                if (list != null) {
11771                    int N = list.size();
11772                    int i;
11773                    for (i=0; i<N; i++) {
11774                        if (intent.filterEquals(list.get(i))) {
11775                            list.remove(i);
11776                            break;
11777                        }
11778                    }
11779                    if (list.size() <= 0) {
11780                        stickies.remove(intent.getAction());
11781                    }
11782                }
11783                if (stickies.size() <= 0) {
11784                    mStickyBroadcasts.remove(userId);
11785                }
11786            }
11787        }
11788    }
11789
11790    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11791            String resultData, Bundle resultExtras, boolean resultAbort,
11792            boolean explicit) {
11793        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11794        if (r == null) {
11795            Slog.w(TAG, "finishReceiver called but not found on queue");
11796            return false;
11797        }
11798
11799        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11800                explicit);
11801    }
11802
11803    public void finishReceiver(IBinder who, int resultCode, String resultData,
11804            Bundle resultExtras, boolean resultAbort) {
11805        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11806
11807        // Refuse possible leaked file descriptors
11808        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11809            throw new IllegalArgumentException("File descriptors passed in Bundle");
11810        }
11811
11812        final long origId = Binder.clearCallingIdentity();
11813        try {
11814            boolean doNext = false;
11815            BroadcastRecord r = null;
11816
11817            synchronized(this) {
11818                r = broadcastRecordForReceiverLocked(who);
11819                if (r != null) {
11820                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11821                        resultData, resultExtras, resultAbort, true);
11822                }
11823            }
11824
11825            if (doNext) {
11826                r.queue.processNextBroadcast(false);
11827            }
11828            trimApplications();
11829        } finally {
11830            Binder.restoreCallingIdentity(origId);
11831        }
11832    }
11833
11834    // =========================================================
11835    // INSTRUMENTATION
11836    // =========================================================
11837
11838    public boolean startInstrumentation(ComponentName className,
11839            String profileFile, int flags, Bundle arguments,
11840            IInstrumentationWatcher watcher) {
11841        enforceNotIsolatedCaller("startInstrumentation");
11842        // Refuse possible leaked file descriptors
11843        if (arguments != null && arguments.hasFileDescriptors()) {
11844            throw new IllegalArgumentException("File descriptors passed in Bundle");
11845        }
11846
11847        synchronized(this) {
11848            InstrumentationInfo ii = null;
11849            ApplicationInfo ai = null;
11850            try {
11851                ii = mContext.getPackageManager().getInstrumentationInfo(
11852                    className, STOCK_PM_FLAGS);
11853                ai = mContext.getPackageManager().getApplicationInfo(
11854                        ii.targetPackage, STOCK_PM_FLAGS);
11855            } catch (PackageManager.NameNotFoundException e) {
11856            }
11857            if (ii == null) {
11858                reportStartInstrumentationFailure(watcher, className,
11859                        "Unable to find instrumentation info for: " + className);
11860                return false;
11861            }
11862            if (ai == null) {
11863                reportStartInstrumentationFailure(watcher, className,
11864                        "Unable to find instrumentation target package: " + ii.targetPackage);
11865                return false;
11866            }
11867
11868            int match = mContext.getPackageManager().checkSignatures(
11869                    ii.targetPackage, ii.packageName);
11870            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11871                String msg = "Permission Denial: starting instrumentation "
11872                        + className + " from pid="
11873                        + Binder.getCallingPid()
11874                        + ", uid=" + Binder.getCallingPid()
11875                        + " not allowed because package " + ii.packageName
11876                        + " does not have a signature matching the target "
11877                        + ii.targetPackage;
11878                reportStartInstrumentationFailure(watcher, className, msg);
11879                throw new SecurityException(msg);
11880            }
11881
11882            int userId = UserHandle.getCallingUserId();
11883            final long origId = Binder.clearCallingIdentity();
11884            // Instrumentation can kill and relaunch even persistent processes
11885            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
11886            ProcessRecord app = addAppLocked(ai, false);
11887            app.instrumentationClass = className;
11888            app.instrumentationInfo = ai;
11889            app.instrumentationProfileFile = profileFile;
11890            app.instrumentationArguments = arguments;
11891            app.instrumentationWatcher = watcher;
11892            app.instrumentationResultClass = className;
11893            Binder.restoreCallingIdentity(origId);
11894        }
11895
11896        return true;
11897    }
11898
11899    /**
11900     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11901     * error to the logs, but if somebody is watching, send the report there too.  This enables
11902     * the "am" command to report errors with more information.
11903     *
11904     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11905     * @param cn The component name of the instrumentation.
11906     * @param report The error report.
11907     */
11908    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11909            ComponentName cn, String report) {
11910        Slog.w(TAG, report);
11911        try {
11912            if (watcher != null) {
11913                Bundle results = new Bundle();
11914                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11915                results.putString("Error", report);
11916                watcher.instrumentationStatus(cn, -1, results);
11917            }
11918        } catch (RemoteException e) {
11919            Slog.w(TAG, e);
11920        }
11921    }
11922
11923    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11924        if (app.instrumentationWatcher != null) {
11925            try {
11926                // NOTE:  IInstrumentationWatcher *must* be oneway here
11927                app.instrumentationWatcher.instrumentationFinished(
11928                    app.instrumentationClass,
11929                    resultCode,
11930                    results);
11931            } catch (RemoteException e) {
11932            }
11933        }
11934        app.instrumentationWatcher = null;
11935        app.instrumentationClass = null;
11936        app.instrumentationInfo = null;
11937        app.instrumentationProfileFile = null;
11938        app.instrumentationArguments = null;
11939
11940        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
11941    }
11942
11943    public void finishInstrumentation(IApplicationThread target,
11944            int resultCode, Bundle results) {
11945        int userId = UserHandle.getCallingUserId();
11946        // Refuse possible leaked file descriptors
11947        if (results != null && results.hasFileDescriptors()) {
11948            throw new IllegalArgumentException("File descriptors passed in Intent");
11949        }
11950
11951        synchronized(this) {
11952            ProcessRecord app = getRecordForAppLocked(target);
11953            if (app == null) {
11954                Slog.w(TAG, "finishInstrumentation: no app for " + target);
11955                return;
11956            }
11957            final long origId = Binder.clearCallingIdentity();
11958            finishInstrumentationLocked(app, resultCode, results);
11959            Binder.restoreCallingIdentity(origId);
11960        }
11961    }
11962
11963    // =========================================================
11964    // CONFIGURATION
11965    // =========================================================
11966
11967    public ConfigurationInfo getDeviceConfigurationInfo() {
11968        ConfigurationInfo config = new ConfigurationInfo();
11969        synchronized (this) {
11970            config.reqTouchScreen = mConfiguration.touchscreen;
11971            config.reqKeyboardType = mConfiguration.keyboard;
11972            config.reqNavigation = mConfiguration.navigation;
11973            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11974                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
11975                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11976            }
11977            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11978                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
11979                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11980            }
11981            config.reqGlEsVersion = GL_ES_VERSION;
11982        }
11983        return config;
11984    }
11985
11986    public Configuration getConfiguration() {
11987        Configuration ci;
11988        synchronized(this) {
11989            ci = new Configuration(mConfiguration);
11990        }
11991        return ci;
11992    }
11993
11994    public void updatePersistentConfiguration(Configuration values) {
11995        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11996                "updateConfiguration()");
11997        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
11998                "updateConfiguration()");
11999        if (values == null) {
12000            throw new NullPointerException("Configuration must not be null");
12001        }
12002
12003        synchronized(this) {
12004            final long origId = Binder.clearCallingIdentity();
12005            updateConfigurationLocked(values, null, true, false);
12006            Binder.restoreCallingIdentity(origId);
12007        }
12008    }
12009
12010    public void updateConfiguration(Configuration values) {
12011        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12012                "updateConfiguration()");
12013
12014        synchronized(this) {
12015            if (values == null && mWindowManager != null) {
12016                // sentinel: fetch the current configuration from the window manager
12017                values = mWindowManager.computeNewConfiguration();
12018            }
12019
12020            if (mWindowManager != null) {
12021                mProcessList.applyDisplaySize(mWindowManager);
12022            }
12023
12024            final long origId = Binder.clearCallingIdentity();
12025            if (values != null) {
12026                Settings.System.clearConfiguration(values);
12027            }
12028            updateConfigurationLocked(values, null, false, false);
12029            Binder.restoreCallingIdentity(origId);
12030        }
12031    }
12032
12033    /**
12034     * Do either or both things: (1) change the current configuration, and (2)
12035     * make sure the given activity is running with the (now) current
12036     * configuration.  Returns true if the activity has been left running, or
12037     * false if <var>starting</var> is being destroyed to match the new
12038     * configuration.
12039     * @param persistent TODO
12040     */
12041    boolean updateConfigurationLocked(Configuration values,
12042            ActivityRecord starting, boolean persistent, boolean initLocale) {
12043        // do nothing if we are headless
12044        if (mHeadless) return true;
12045
12046        int changes = 0;
12047
12048        boolean kept = true;
12049
12050        if (values != null) {
12051            Configuration newConfig = new Configuration(mConfiguration);
12052            changes = newConfig.updateFrom(values);
12053            if (changes != 0) {
12054                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12055                    Slog.i(TAG, "Updating configuration to: " + values);
12056                }
12057
12058                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12059
12060                if (values.locale != null && !initLocale) {
12061                    saveLocaleLocked(values.locale,
12062                                     !values.locale.equals(mConfiguration.locale),
12063                                     values.userSetLocale);
12064                }
12065
12066                mConfigurationSeq++;
12067                if (mConfigurationSeq <= 0) {
12068                    mConfigurationSeq = 1;
12069                }
12070                newConfig.seq = mConfigurationSeq;
12071                mConfiguration = newConfig;
12072                Slog.i(TAG, "Config changed: " + newConfig);
12073
12074                final Configuration configCopy = new Configuration(mConfiguration);
12075
12076                // TODO: If our config changes, should we auto dismiss any currently
12077                // showing dialogs?
12078                mShowDialogs = shouldShowDialogs(newConfig);
12079
12080                AttributeCache ac = AttributeCache.instance();
12081                if (ac != null) {
12082                    ac.updateConfiguration(configCopy);
12083                }
12084
12085                // Make sure all resources in our process are updated
12086                // right now, so that anyone who is going to retrieve
12087                // resource values after we return will be sure to get
12088                // the new ones.  This is especially important during
12089                // boot, where the first config change needs to guarantee
12090                // all resources have that config before following boot
12091                // code is executed.
12092                mSystemThread.applyConfigurationToResources(configCopy);
12093
12094                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12095                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12096                    msg.obj = new Configuration(configCopy);
12097                    mHandler.sendMessage(msg);
12098                }
12099
12100                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12101                    ProcessRecord app = mLruProcesses.get(i);
12102                    try {
12103                        if (app.thread != null) {
12104                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12105                                    + app.processName + " new config " + mConfiguration);
12106                            app.thread.scheduleConfigurationChanged(configCopy);
12107                        }
12108                    } catch (Exception e) {
12109                    }
12110                }
12111                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12112                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12113                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
12114                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12115                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12116                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12117                    broadcastIntentLocked(null, null,
12118                            new Intent(Intent.ACTION_LOCALE_CHANGED),
12119                            null, null, 0, null, null,
12120                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12121                }
12122            }
12123        }
12124
12125        if (changes != 0 && starting == null) {
12126            // If the configuration changed, and the caller is not already
12127            // in the process of starting an activity, then find the top
12128            // activity to check if its configuration needs to change.
12129            starting = mMainStack.topRunningActivityLocked(null);
12130        }
12131
12132        if (starting != null) {
12133            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12134            // And we need to make sure at this point that all other activities
12135            // are made visible with the correct configuration.
12136            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12137        }
12138
12139        if (values != null && mWindowManager != null) {
12140            mWindowManager.setNewConfiguration(mConfiguration);
12141        }
12142
12143        return kept;
12144    }
12145
12146    /**
12147     * Decide based on the configuration whether we should shouw the ANR,
12148     * crash, etc dialogs.  The idea is that if there is no affordnace to
12149     * press the on-screen buttons, we shouldn't show the dialog.
12150     *
12151     * A thought: SystemUI might also want to get told about this, the Power
12152     * dialog / global actions also might want different behaviors.
12153     */
12154    private static final boolean shouldShowDialogs(Configuration config) {
12155        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12156                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12157    }
12158
12159    /**
12160     * Save the locale.  You must be inside a synchronized (this) block.
12161     */
12162    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12163        if(isDiff) {
12164            SystemProperties.set("user.language", l.getLanguage());
12165            SystemProperties.set("user.region", l.getCountry());
12166        }
12167
12168        if(isPersist) {
12169            SystemProperties.set("persist.sys.language", l.getLanguage());
12170            SystemProperties.set("persist.sys.country", l.getCountry());
12171            SystemProperties.set("persist.sys.localevar", l.getVariant());
12172        }
12173    }
12174
12175    @Override
12176    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12177        ActivityRecord srec = ActivityRecord.forToken(token);
12178        return srec != null && srec.task.affinity != null &&
12179                srec.task.affinity.equals(destAffinity);
12180    }
12181
12182    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12183            Intent resultData) {
12184        ComponentName dest = destIntent.getComponent();
12185
12186        synchronized (this) {
12187            ActivityRecord srec = ActivityRecord.forToken(token);
12188            if (srec == null) {
12189                return false;
12190            }
12191            ArrayList<ActivityRecord> history = srec.stack.mHistory;
12192            final int start = history.indexOf(srec);
12193            if (start < 0) {
12194                // Current activity is not in history stack; do nothing.
12195                return false;
12196            }
12197            int finishTo = start - 1;
12198            ActivityRecord parent = null;
12199            boolean foundParentInTask = false;
12200            if (dest != null) {
12201                TaskRecord tr = srec.task;
12202                for (int i = start - 1; i >= 0; i--) {
12203                    ActivityRecord r = history.get(i);
12204                    if (tr != r.task) {
12205                        // Couldn't find parent in the same task; stop at the one above this.
12206                        // (Root of current task; in-app "home" behavior)
12207                        // Always at least finish the current activity.
12208                        finishTo = Math.min(start - 1, i + 1);
12209                        parent = history.get(finishTo);
12210                        break;
12211                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
12212                            r.info.name.equals(dest.getClassName())) {
12213                        finishTo = i;
12214                        parent = r;
12215                        foundParentInTask = true;
12216                        break;
12217                    }
12218                }
12219            }
12220
12221            if (mController != null) {
12222                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12223                if (next != null) {
12224                    // ask watcher if this is allowed
12225                    boolean resumeOK = true;
12226                    try {
12227                        resumeOK = mController.activityResuming(next.packageName);
12228                    } catch (RemoteException e) {
12229                        mController = null;
12230                    }
12231
12232                    if (!resumeOK) {
12233                        return false;
12234                    }
12235                }
12236            }
12237            final long origId = Binder.clearCallingIdentity();
12238            for (int i = start; i > finishTo; i--) {
12239                ActivityRecord r = history.get(i);
12240                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12241                        "navigate-up");
12242                // Only return the supplied result for the first activity finished
12243                resultCode = Activity.RESULT_CANCELED;
12244                resultData = null;
12245            }
12246
12247            if (parent != null && foundParentInTask) {
12248                final int parentLaunchMode = parent.info.launchMode;
12249                final int destIntentFlags = destIntent.getFlags();
12250                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12251                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12252                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12253                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12254                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12255                } else {
12256                    try {
12257                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12258                                destIntent.getComponent(), 0, UserHandle.getCallingUserId());
12259                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12260                                null, aInfo, parent.appToken, null,
12261                                0, -1, parent.launchedFromUid, 0, null, true, null);
12262                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12263                    } catch (RemoteException e) {
12264                        foundParentInTask = false;
12265                    }
12266                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12267                            resultData, "navigate-up");
12268                }
12269            }
12270            Binder.restoreCallingIdentity(origId);
12271            return foundParentInTask;
12272        }
12273    }
12274
12275    public int getLaunchedFromUid(IBinder activityToken) {
12276        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12277        if (srec == null) {
12278            return -1;
12279        }
12280        return srec.launchedFromUid;
12281    }
12282
12283    // =========================================================
12284    // LIFETIME MANAGEMENT
12285    // =========================================================
12286
12287    // Returns which broadcast queue the app is the current [or imminent] receiver
12288    // on, or 'null' if the app is not an active broadcast recipient.
12289    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12290        BroadcastRecord r = app.curReceiver;
12291        if (r != null) {
12292            return r.queue;
12293        }
12294
12295        // It's not the current receiver, but it might be starting up to become one
12296        synchronized (this) {
12297            for (BroadcastQueue queue : mBroadcastQueues) {
12298                r = queue.mPendingBroadcast;
12299                if (r != null && r.curApp == app) {
12300                    // found it; report which queue it's in
12301                    return queue;
12302                }
12303            }
12304        }
12305
12306        return null;
12307    }
12308
12309    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12310            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12311        if (mAdjSeq == app.adjSeq) {
12312            // This adjustment has already been computed.  If we are calling
12313            // from the top, we may have already computed our adjustment with
12314            // an earlier hidden adjustment that isn't really for us... if
12315            // so, use the new hidden adjustment.
12316            if (!recursed && app.hidden) {
12317                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12318                        app.hasActivities ? hiddenAdj : emptyAdj;
12319            }
12320            return app.curRawAdj;
12321        }
12322
12323        if (app.thread == null) {
12324            app.adjSeq = mAdjSeq;
12325            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12326            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12327        }
12328
12329        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12330        app.adjSource = null;
12331        app.adjTarget = null;
12332        app.empty = false;
12333        app.hidden = false;
12334
12335        final int activitiesSize = app.activities.size();
12336
12337        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12338            // The max adjustment doesn't allow this app to be anything
12339            // below foreground, so it is not worth doing work for it.
12340            app.adjType = "fixed";
12341            app.adjSeq = mAdjSeq;
12342            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12343            app.hasActivities = false;
12344            app.foregroundActivities = false;
12345            app.keeping = true;
12346            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12347            // System process can do UI, and when they do we want to have
12348            // them trim their memory after the user leaves the UI.  To
12349            // facilitate this, here we need to determine whether or not it
12350            // is currently showing UI.
12351            app.systemNoUi = true;
12352            if (app == TOP_APP) {
12353                app.systemNoUi = false;
12354                app.hasActivities = true;
12355            } else if (activitiesSize > 0) {
12356                for (int j = 0; j < activitiesSize; j++) {
12357                    final ActivityRecord r = app.activities.get(j);
12358                    if (r.visible) {
12359                        app.systemNoUi = false;
12360                    }
12361                    if (r.app == app) {
12362                        app.hasActivities = true;
12363                    }
12364                }
12365            }
12366            return (app.curAdj=app.maxAdj);
12367        }
12368
12369        app.keeping = false;
12370        app.systemNoUi = false;
12371        app.hasActivities = false;
12372
12373        // Determine the importance of the process, starting with most
12374        // important to least, and assign an appropriate OOM adjustment.
12375        int adj;
12376        int schedGroup;
12377        boolean foregroundActivities = false;
12378        boolean interesting = false;
12379        BroadcastQueue queue;
12380        if (app == TOP_APP) {
12381            // The last app on the list is the foreground app.
12382            adj = ProcessList.FOREGROUND_APP_ADJ;
12383            schedGroup = Process.THREAD_GROUP_DEFAULT;
12384            app.adjType = "top-activity";
12385            foregroundActivities = true;
12386            interesting = true;
12387            app.hasActivities = true;
12388        } else if (app.instrumentationClass != null) {
12389            // Don't want to kill running instrumentation.
12390            adj = ProcessList.FOREGROUND_APP_ADJ;
12391            schedGroup = Process.THREAD_GROUP_DEFAULT;
12392            app.adjType = "instrumentation";
12393            interesting = true;
12394        } else if ((queue = isReceivingBroadcast(app)) != null) {
12395            // An app that is currently receiving a broadcast also
12396            // counts as being in the foreground for OOM killer purposes.
12397            // It's placed in a sched group based on the nature of the
12398            // broadcast as reflected by which queue it's active in.
12399            adj = ProcessList.FOREGROUND_APP_ADJ;
12400            schedGroup = (queue == mFgBroadcastQueue)
12401                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12402            app.adjType = "broadcast";
12403        } else if (app.executingServices.size() > 0) {
12404            // An app that is currently executing a service callback also
12405            // counts as being in the foreground.
12406            adj = ProcessList.FOREGROUND_APP_ADJ;
12407            schedGroup = Process.THREAD_GROUP_DEFAULT;
12408            app.adjType = "exec-service";
12409        } else {
12410            // Assume process is hidden (has activities); we will correct
12411            // later if this is not the case.
12412            adj = hiddenAdj;
12413            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12414            app.hidden = true;
12415            app.adjType = "bg-activities";
12416        }
12417
12418        boolean hasStoppingActivities = false;
12419
12420        // Examine all activities if not already foreground.
12421        if (!foregroundActivities && activitiesSize > 0) {
12422            for (int j = 0; j < activitiesSize; j++) {
12423                final ActivityRecord r = app.activities.get(j);
12424                if (r.visible) {
12425                    // App has a visible activity; only upgrade adjustment.
12426                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12427                        adj = ProcessList.VISIBLE_APP_ADJ;
12428                        app.adjType = "visible";
12429                    }
12430                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12431                    app.hidden = false;
12432                    app.hasActivities = true;
12433                    foregroundActivities = true;
12434                    break;
12435                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12436                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12437                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12438                        app.adjType = "pausing";
12439                    }
12440                    app.hidden = false;
12441                    foregroundActivities = true;
12442                } else if (r.state == ActivityState.STOPPING) {
12443                    // We will apply the actual adjustment later, because
12444                    // we want to allow this process to immediately go through
12445                    // any memory trimming that is in effect.
12446                    app.hidden = false;
12447                    foregroundActivities = true;
12448                    hasStoppingActivities = true;
12449                }
12450                if (r.app == app) {
12451                    app.hasActivities = true;
12452                }
12453            }
12454        }
12455
12456        if (adj == hiddenAdj && !app.hasActivities) {
12457            // Whoops, this process is completely empty as far as we know
12458            // at this point.
12459            adj = emptyAdj;
12460            app.empty = true;
12461            app.adjType = "bg-empty";
12462        }
12463
12464        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12465            if (app.foregroundServices) {
12466                // The user is aware of this app, so make it visible.
12467                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12468                app.hidden = false;
12469                app.adjType = "foreground-service";
12470                schedGroup = Process.THREAD_GROUP_DEFAULT;
12471            } else if (app.forcingToForeground != null) {
12472                // The user is aware of this app, so make it visible.
12473                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12474                app.hidden = false;
12475                app.adjType = "force-foreground";
12476                app.adjSource = app.forcingToForeground;
12477                schedGroup = Process.THREAD_GROUP_DEFAULT;
12478            }
12479        }
12480
12481        if (app.foregroundServices) {
12482            interesting = true;
12483        }
12484
12485        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12486            // We don't want to kill the current heavy-weight process.
12487            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12488            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12489            app.hidden = false;
12490            app.adjType = "heavy";
12491        }
12492
12493        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12494            // This process is hosting what we currently consider to be the
12495            // home app, so we don't want to let it go into the background.
12496            adj = ProcessList.HOME_APP_ADJ;
12497            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12498            app.hidden = false;
12499            app.adjType = "home";
12500        }
12501
12502        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12503                && app.activities.size() > 0) {
12504            // This was the previous process that showed UI to the user.
12505            // We want to try to keep it around more aggressively, to give
12506            // a good experience around switching between two apps.
12507            adj = ProcessList.PREVIOUS_APP_ADJ;
12508            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12509            app.hidden = false;
12510            app.adjType = "previous";
12511        }
12512
12513        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12514                + " reason=" + app.adjType);
12515
12516        // By default, we use the computed adjustment.  It may be changed if
12517        // there are applications dependent on our services or providers, but
12518        // this gives us a baseline and makes sure we don't get into an
12519        // infinite recursion.
12520        app.adjSeq = mAdjSeq;
12521        app.curRawAdj = app.nonStoppingAdj = adj;
12522
12523        if (mBackupTarget != null && app == mBackupTarget.app) {
12524            // If possible we want to avoid killing apps while they're being backed up
12525            if (adj > ProcessList.BACKUP_APP_ADJ) {
12526                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12527                adj = ProcessList.BACKUP_APP_ADJ;
12528                app.adjType = "backup";
12529                app.hidden = false;
12530            }
12531        }
12532
12533        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12534                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12535            final long now = SystemClock.uptimeMillis();
12536            // This process is more important if the top activity is
12537            // bound to the service.
12538            Iterator<ServiceRecord> jt = app.services.iterator();
12539            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12540                ServiceRecord s = jt.next();
12541                if (s.startRequested) {
12542                    if (app.hasShownUi && app != mHomeProcess) {
12543                        // If this process has shown some UI, let it immediately
12544                        // go to the LRU list because it may be pretty heavy with
12545                        // UI stuff.  We'll tag it with a label just to help
12546                        // debug and understand what is going on.
12547                        if (adj > ProcessList.SERVICE_ADJ) {
12548                            app.adjType = "started-bg-ui-services";
12549                        }
12550                    } else {
12551                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12552                            // This service has seen some activity within
12553                            // recent memory, so we will keep its process ahead
12554                            // of the background processes.
12555                            if (adj > ProcessList.SERVICE_ADJ) {
12556                                adj = ProcessList.SERVICE_ADJ;
12557                                app.adjType = "started-services";
12558                                app.hidden = false;
12559                            }
12560                        }
12561                        // If we have let the service slide into the background
12562                        // state, still have some text describing what it is doing
12563                        // even though the service no longer has an impact.
12564                        if (adj > ProcessList.SERVICE_ADJ) {
12565                            app.adjType = "started-bg-services";
12566                        }
12567                    }
12568                    // Don't kill this process because it is doing work; it
12569                    // has said it is doing work.
12570                    app.keeping = true;
12571                }
12572                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12573                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12574                    Iterator<ArrayList<ConnectionRecord>> kt
12575                            = s.connections.values().iterator();
12576                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12577                        ArrayList<ConnectionRecord> clist = kt.next();
12578                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12579                            // XXX should compute this based on the max of
12580                            // all connected clients.
12581                            ConnectionRecord cr = clist.get(i);
12582                            if (cr.binding.client == app) {
12583                                // Binding to ourself is not interesting.
12584                                continue;
12585                            }
12586                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12587                                ProcessRecord client = cr.binding.client;
12588                                int clientAdj = adj;
12589                                int myHiddenAdj = hiddenAdj;
12590                                if (myHiddenAdj > client.hiddenAdj) {
12591                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12592                                        myHiddenAdj = client.hiddenAdj;
12593                                    } else {
12594                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12595                                    }
12596                                }
12597                                int myEmptyAdj = emptyAdj;
12598                                if (myEmptyAdj > client.emptyAdj) {
12599                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12600                                        myEmptyAdj = client.emptyAdj;
12601                                    } else {
12602                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12603                                    }
12604                                }
12605                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12606                                        myEmptyAdj, TOP_APP, true, doingAll);
12607                                String adjType = null;
12608                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12609                                    // Not doing bind OOM management, so treat
12610                                    // this guy more like a started service.
12611                                    if (app.hasShownUi && app != mHomeProcess) {
12612                                        // If this process has shown some UI, let it immediately
12613                                        // go to the LRU list because it may be pretty heavy with
12614                                        // UI stuff.  We'll tag it with a label just to help
12615                                        // debug and understand what is going on.
12616                                        if (adj > clientAdj) {
12617                                            adjType = "bound-bg-ui-services";
12618                                        }
12619                                        app.hidden = false;
12620                                        clientAdj = adj;
12621                                    } else {
12622                                        if (now >= (s.lastActivity
12623                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12624                                            // This service has not seen activity within
12625                                            // recent memory, so allow it to drop to the
12626                                            // LRU list if there is no other reason to keep
12627                                            // it around.  We'll also tag it with a label just
12628                                            // to help debug and undertand what is going on.
12629                                            if (adj > clientAdj) {
12630                                                adjType = "bound-bg-services";
12631                                            }
12632                                            clientAdj = adj;
12633                                        }
12634                                    }
12635                                }
12636                                if (adj > clientAdj) {
12637                                    // If this process has recently shown UI, and
12638                                    // the process that is binding to it is less
12639                                    // important than being visible, then we don't
12640                                    // care about the binding as much as we care
12641                                    // about letting this process get into the LRU
12642                                    // list to be killed and restarted if needed for
12643                                    // memory.
12644                                    if (app.hasShownUi && app != mHomeProcess
12645                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12646                                        adjType = "bound-bg-ui-services";
12647                                    } else {
12648                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12649                                                |Context.BIND_IMPORTANT)) != 0) {
12650                                            adj = clientAdj;
12651                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12652                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12653                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12654                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12655                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12656                                            adj = clientAdj;
12657                                        } else {
12658                                            app.pendingUiClean = true;
12659                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12660                                                adj = ProcessList.VISIBLE_APP_ADJ;
12661                                            }
12662                                        }
12663                                        if (!client.hidden) {
12664                                            app.hidden = false;
12665                                        }
12666                                        if (client.keeping) {
12667                                            app.keeping = true;
12668                                        }
12669                                        adjType = "service";
12670                                    }
12671                                }
12672                                if (adjType != null) {
12673                                    app.adjType = adjType;
12674                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12675                                            .REASON_SERVICE_IN_USE;
12676                                    app.adjSource = cr.binding.client;
12677                                    app.adjSourceOom = clientAdj;
12678                                    app.adjTarget = s.name;
12679                                }
12680                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12681                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12682                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12683                                    }
12684                                }
12685                            }
12686                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12687                                ActivityRecord a = cr.activity;
12688                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12689                                        (a.visible || a.state == ActivityState.RESUMED
12690                                         || a.state == ActivityState.PAUSING)) {
12691                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12692                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12693                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12694                                    }
12695                                    app.hidden = false;
12696                                    app.adjType = "service";
12697                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12698                                            .REASON_SERVICE_IN_USE;
12699                                    app.adjSource = a;
12700                                    app.adjSourceOom = adj;
12701                                    app.adjTarget = s.name;
12702                                }
12703                            }
12704                        }
12705                    }
12706                }
12707            }
12708
12709            // Finally, if this process has active services running in it, we
12710            // would like to avoid killing it unless it would prevent the current
12711            // application from running.  By default we put the process in
12712            // with the rest of the background processes; as we scan through
12713            // its services we may bump it up from there.
12714            if (adj > hiddenAdj) {
12715                adj = hiddenAdj;
12716                app.hidden = false;
12717                app.adjType = "bg-services";
12718            }
12719        }
12720
12721        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12722                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12723            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12724            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12725                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12726                ContentProviderRecord cpr = jt.next();
12727                for (int i = cpr.connections.size()-1;
12728                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12729                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12730                        i--) {
12731                    ContentProviderConnection conn = cpr.connections.get(i);
12732                    ProcessRecord client = conn.client;
12733                    if (client == app) {
12734                        // Being our own client is not interesting.
12735                        continue;
12736                    }
12737                    int myHiddenAdj = hiddenAdj;
12738                    if (myHiddenAdj > client.hiddenAdj) {
12739                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12740                            myHiddenAdj = client.hiddenAdj;
12741                        } else {
12742                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12743                        }
12744                    }
12745                    int myEmptyAdj = emptyAdj;
12746                    if (myEmptyAdj > client.emptyAdj) {
12747                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12748                            myEmptyAdj = client.emptyAdj;
12749                        } else {
12750                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12751                        }
12752                    }
12753                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12754                            myEmptyAdj, TOP_APP, true, doingAll);
12755                    if (adj > clientAdj) {
12756                        if (app.hasShownUi && app != mHomeProcess
12757                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12758                            app.adjType = "bg-ui-provider";
12759                        } else {
12760                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12761                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12762                            app.adjType = "provider";
12763                        }
12764                        if (!client.hidden) {
12765                            app.hidden = false;
12766                        }
12767                        if (client.keeping) {
12768                            app.keeping = true;
12769                        }
12770                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12771                                .REASON_PROVIDER_IN_USE;
12772                        app.adjSource = client;
12773                        app.adjSourceOom = clientAdj;
12774                        app.adjTarget = cpr.name;
12775                    }
12776                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12777                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12778                    }
12779                }
12780                // If the provider has external (non-framework) process
12781                // dependencies, ensure that its adjustment is at least
12782                // FOREGROUND_APP_ADJ.
12783                if (cpr.hasExternalProcessHandles()) {
12784                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12785                        adj = ProcessList.FOREGROUND_APP_ADJ;
12786                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12787                        app.hidden = false;
12788                        app.keeping = true;
12789                        app.adjType = "provider";
12790                        app.adjTarget = cpr.name;
12791                    }
12792                }
12793            }
12794        }
12795
12796        if (adj == ProcessList.SERVICE_ADJ) {
12797            if (doingAll) {
12798                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12799                mNewNumServiceProcs++;
12800            }
12801            if (app.serviceb) {
12802                adj = ProcessList.SERVICE_B_ADJ;
12803            }
12804        } else {
12805            app.serviceb = false;
12806        }
12807
12808        app.nonStoppingAdj = adj;
12809
12810        if (hasStoppingActivities) {
12811            // Only upgrade adjustment.
12812            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12813                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12814                app.adjType = "stopping";
12815            }
12816        }
12817
12818        app.curRawAdj = adj;
12819
12820        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12821        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12822        if (adj > app.maxAdj) {
12823            adj = app.maxAdj;
12824            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12825                schedGroup = Process.THREAD_GROUP_DEFAULT;
12826            }
12827        }
12828        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12829            app.keeping = true;
12830        }
12831
12832        if (app.hasAboveClient) {
12833            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12834            // then we need to drop its adjustment to be lower than the service's
12835            // in order to honor the request.  We want to drop it by one adjustment
12836            // level...  but there is special meaning applied to various levels so
12837            // we will skip some of them.
12838            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12839                // System process will not get dropped, ever
12840            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12841                adj = ProcessList.VISIBLE_APP_ADJ;
12842            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12843                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12844            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12845                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12846            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12847                adj++;
12848            }
12849        }
12850
12851        int importance = app.memImportance;
12852        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12853            app.curAdj = adj;
12854            app.curSchedGroup = schedGroup;
12855            if (!interesting) {
12856                // For this reporting, if there is not something explicitly
12857                // interesting in this process then we will push it to the
12858                // background importance.
12859                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12860            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12861                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12862            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12863                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12864            } else if (adj >= ProcessList.HOME_APP_ADJ) {
12865                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12866            } else if (adj >= ProcessList.SERVICE_ADJ) {
12867                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12868            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12869                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12870            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12871                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12872            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12873                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12874            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12875                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12876            } else {
12877                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12878            }
12879        }
12880
12881        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12882        if (foregroundActivities != app.foregroundActivities) {
12883            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12884        }
12885        if (changes != 0) {
12886            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12887            app.memImportance = importance;
12888            app.foregroundActivities = foregroundActivities;
12889            int i = mPendingProcessChanges.size()-1;
12890            ProcessChangeItem item = null;
12891            while (i >= 0) {
12892                item = mPendingProcessChanges.get(i);
12893                if (item.pid == app.pid) {
12894                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12895                    break;
12896                }
12897                i--;
12898            }
12899            if (i < 0) {
12900                // No existing item in pending changes; need a new one.
12901                final int NA = mAvailProcessChanges.size();
12902                if (NA > 0) {
12903                    item = mAvailProcessChanges.remove(NA-1);
12904                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12905                } else {
12906                    item = new ProcessChangeItem();
12907                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
12908                }
12909                item.changes = 0;
12910                item.pid = app.pid;
12911                item.uid = app.info.uid;
12912                if (mPendingProcessChanges.size() == 0) {
12913                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
12914                            "*** Enqueueing dispatch processes changed!");
12915                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
12916                }
12917                mPendingProcessChanges.add(item);
12918            }
12919            item.changes |= changes;
12920            item.importance = importance;
12921            item.foregroundActivities = foregroundActivities;
12922            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
12923                    + Integer.toHexString(System.identityHashCode(item))
12924                    + " " + app.toShortString() + ": changes=" + item.changes
12925                    + " importance=" + item.importance
12926                    + " foreground=" + item.foregroundActivities
12927                    + " type=" + app.adjType + " source=" + app.adjSource
12928                    + " target=" + app.adjTarget);
12929        }
12930
12931        return app.curRawAdj;
12932    }
12933
12934    /**
12935     * Ask a given process to GC right now.
12936     */
12937    final void performAppGcLocked(ProcessRecord app) {
12938        try {
12939            app.lastRequestedGc = SystemClock.uptimeMillis();
12940            if (app.thread != null) {
12941                if (app.reportLowMemory) {
12942                    app.reportLowMemory = false;
12943                    app.thread.scheduleLowMemory();
12944                } else {
12945                    app.thread.processInBackground();
12946                }
12947            }
12948        } catch (Exception e) {
12949            // whatever.
12950        }
12951    }
12952
12953    /**
12954     * Returns true if things are idle enough to perform GCs.
12955     */
12956    private final boolean canGcNowLocked() {
12957        boolean processingBroadcasts = false;
12958        for (BroadcastQueue q : mBroadcastQueues) {
12959            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
12960                processingBroadcasts = true;
12961            }
12962        }
12963        return !processingBroadcasts
12964                && (mSleeping || (mMainStack.mResumedActivity != null &&
12965                        mMainStack.mResumedActivity.idle));
12966    }
12967
12968    /**
12969     * Perform GCs on all processes that are waiting for it, but only
12970     * if things are idle.
12971     */
12972    final void performAppGcsLocked() {
12973        final int N = mProcessesToGc.size();
12974        if (N <= 0) {
12975            return;
12976        }
12977        if (canGcNowLocked()) {
12978            while (mProcessesToGc.size() > 0) {
12979                ProcessRecord proc = mProcessesToGc.remove(0);
12980                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
12981                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12982                            <= SystemClock.uptimeMillis()) {
12983                        // To avoid spamming the system, we will GC processes one
12984                        // at a time, waiting a few seconds between each.
12985                        performAppGcLocked(proc);
12986                        scheduleAppGcsLocked();
12987                        return;
12988                    } else {
12989                        // It hasn't been long enough since we last GCed this
12990                        // process...  put it in the list to wait for its time.
12991                        addProcessToGcListLocked(proc);
12992                        break;
12993                    }
12994                }
12995            }
12996
12997            scheduleAppGcsLocked();
12998        }
12999    }
13000
13001    /**
13002     * If all looks good, perform GCs on all processes waiting for them.
13003     */
13004    final void performAppGcsIfAppropriateLocked() {
13005        if (canGcNowLocked()) {
13006            performAppGcsLocked();
13007            return;
13008        }
13009        // Still not idle, wait some more.
13010        scheduleAppGcsLocked();
13011    }
13012
13013    /**
13014     * Schedule the execution of all pending app GCs.
13015     */
13016    final void scheduleAppGcsLocked() {
13017        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13018
13019        if (mProcessesToGc.size() > 0) {
13020            // Schedule a GC for the time to the next process.
13021            ProcessRecord proc = mProcessesToGc.get(0);
13022            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13023
13024            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13025            long now = SystemClock.uptimeMillis();
13026            if (when < (now+GC_TIMEOUT)) {
13027                when = now + GC_TIMEOUT;
13028            }
13029            mHandler.sendMessageAtTime(msg, when);
13030        }
13031    }
13032
13033    /**
13034     * Add a process to the array of processes waiting to be GCed.  Keeps the
13035     * list in sorted order by the last GC time.  The process can't already be
13036     * on the list.
13037     */
13038    final void addProcessToGcListLocked(ProcessRecord proc) {
13039        boolean added = false;
13040        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13041            if (mProcessesToGc.get(i).lastRequestedGc <
13042                    proc.lastRequestedGc) {
13043                added = true;
13044                mProcessesToGc.add(i+1, proc);
13045                break;
13046            }
13047        }
13048        if (!added) {
13049            mProcessesToGc.add(0, proc);
13050        }
13051    }
13052
13053    /**
13054     * Set up to ask a process to GC itself.  This will either do it
13055     * immediately, or put it on the list of processes to gc the next
13056     * time things are idle.
13057     */
13058    final void scheduleAppGcLocked(ProcessRecord app) {
13059        long now = SystemClock.uptimeMillis();
13060        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13061            return;
13062        }
13063        if (!mProcessesToGc.contains(app)) {
13064            addProcessToGcListLocked(app);
13065            scheduleAppGcsLocked();
13066        }
13067    }
13068
13069    final void checkExcessivePowerUsageLocked(boolean doKills) {
13070        updateCpuStatsNow();
13071
13072        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13073        boolean doWakeKills = doKills;
13074        boolean doCpuKills = doKills;
13075        if (mLastPowerCheckRealtime == 0) {
13076            doWakeKills = false;
13077        }
13078        if (mLastPowerCheckUptime == 0) {
13079            doCpuKills = false;
13080        }
13081        if (stats.isScreenOn()) {
13082            doWakeKills = false;
13083        }
13084        final long curRealtime = SystemClock.elapsedRealtime();
13085        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13086        final long curUptime = SystemClock.uptimeMillis();
13087        final long uptimeSince = curUptime - mLastPowerCheckUptime;
13088        mLastPowerCheckRealtime = curRealtime;
13089        mLastPowerCheckUptime = curUptime;
13090        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13091            doWakeKills = false;
13092        }
13093        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13094            doCpuKills = false;
13095        }
13096        int i = mLruProcesses.size();
13097        while (i > 0) {
13098            i--;
13099            ProcessRecord app = mLruProcesses.get(i);
13100            if (!app.keeping) {
13101                long wtime;
13102                synchronized (stats) {
13103                    wtime = stats.getProcessWakeTime(app.info.uid,
13104                            app.pid, curRealtime);
13105                }
13106                long wtimeUsed = wtime - app.lastWakeTime;
13107                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13108                if (DEBUG_POWER) {
13109                    StringBuilder sb = new StringBuilder(128);
13110                    sb.append("Wake for ");
13111                    app.toShortString(sb);
13112                    sb.append(": over ");
13113                    TimeUtils.formatDuration(realtimeSince, sb);
13114                    sb.append(" used ");
13115                    TimeUtils.formatDuration(wtimeUsed, sb);
13116                    sb.append(" (");
13117                    sb.append((wtimeUsed*100)/realtimeSince);
13118                    sb.append("%)");
13119                    Slog.i(TAG, sb.toString());
13120                    sb.setLength(0);
13121                    sb.append("CPU for ");
13122                    app.toShortString(sb);
13123                    sb.append(": over ");
13124                    TimeUtils.formatDuration(uptimeSince, sb);
13125                    sb.append(" used ");
13126                    TimeUtils.formatDuration(cputimeUsed, sb);
13127                    sb.append(" (");
13128                    sb.append((cputimeUsed*100)/uptimeSince);
13129                    sb.append("%)");
13130                    Slog.i(TAG, sb.toString());
13131                }
13132                // If a process has held a wake lock for more
13133                // than 50% of the time during this period,
13134                // that sounds bad.  Kill!
13135                if (doWakeKills && realtimeSince > 0
13136                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13137                    synchronized (stats) {
13138                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13139                                realtimeSince, wtimeUsed);
13140                    }
13141                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13142                            + " (pid " + app.pid + "): held " + wtimeUsed
13143                            + " during " + realtimeSince);
13144                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13145                            app.processName, app.setAdj, "excessive wake lock");
13146                    Process.killProcessQuiet(app.pid);
13147                } else if (doCpuKills && uptimeSince > 0
13148                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13149                    synchronized (stats) {
13150                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13151                                uptimeSince, cputimeUsed);
13152                    }
13153                    Slog.w(TAG, "Excessive CPU in " + app.processName
13154                            + " (pid " + app.pid + "): used " + cputimeUsed
13155                            + " during " + uptimeSince);
13156                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13157                            app.processName, app.setAdj, "excessive cpu");
13158                    Process.killProcessQuiet(app.pid);
13159                } else {
13160                    app.lastWakeTime = wtime;
13161                    app.lastCpuTime = app.curCpuTime;
13162                }
13163            }
13164        }
13165    }
13166
13167    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13168            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13169        app.hiddenAdj = hiddenAdj;
13170        app.emptyAdj = emptyAdj;
13171
13172        if (app.thread == null) {
13173            return false;
13174        }
13175
13176        final boolean wasKeeping = app.keeping;
13177
13178        boolean success = true;
13179
13180        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13181
13182        if (app.curRawAdj != app.setRawAdj) {
13183            if (wasKeeping && !app.keeping) {
13184                // This app is no longer something we want to keep.  Note
13185                // its current wake lock time to later know to kill it if
13186                // it is not behaving well.
13187                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13188                synchronized (stats) {
13189                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13190                            app.pid, SystemClock.elapsedRealtime());
13191                }
13192                app.lastCpuTime = app.curCpuTime;
13193            }
13194
13195            app.setRawAdj = app.curRawAdj;
13196        }
13197
13198        if (app.curAdj != app.setAdj) {
13199            if (Process.setOomAdj(app.pid, app.curAdj)) {
13200                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13201                    TAG, "Set " + app.pid + " " + app.processName +
13202                    " adj " + app.curAdj + ": " + app.adjType);
13203                app.setAdj = app.curAdj;
13204            } else {
13205                success = false;
13206                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13207            }
13208        }
13209        if (app.setSchedGroup != app.curSchedGroup) {
13210            app.setSchedGroup = app.curSchedGroup;
13211            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13212                    "Setting process group of " + app.processName
13213                    + " to " + app.curSchedGroup);
13214            if (app.waitingToKill != null &&
13215                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13216                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13217                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13218                        app.processName, app.setAdj, app.waitingToKill);
13219                app.killedBackground = true;
13220                Process.killProcessQuiet(app.pid);
13221                success = false;
13222            } else {
13223                if (true) {
13224                    long oldId = Binder.clearCallingIdentity();
13225                    try {
13226                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13227                    } catch (Exception e) {
13228                        Slog.w(TAG, "Failed setting process group of " + app.pid
13229                                + " to " + app.curSchedGroup);
13230                        e.printStackTrace();
13231                    } finally {
13232                        Binder.restoreCallingIdentity(oldId);
13233                    }
13234                } else {
13235                    if (app.thread != null) {
13236                        try {
13237                            app.thread.setSchedulingGroup(app.curSchedGroup);
13238                        } catch (RemoteException e) {
13239                        }
13240                    }
13241                }
13242            }
13243        }
13244        return success;
13245    }
13246
13247    private final ActivityRecord resumedAppLocked() {
13248        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13249        if (resumedActivity == null || resumedActivity.app == null) {
13250            resumedActivity = mMainStack.mPausingActivity;
13251            if (resumedActivity == null || resumedActivity.app == null) {
13252                resumedActivity = mMainStack.topRunningActivityLocked(null);
13253            }
13254        }
13255        return resumedActivity;
13256    }
13257
13258    final boolean updateOomAdjLocked(ProcessRecord app) {
13259        final ActivityRecord TOP_ACT = resumedAppLocked();
13260        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13261        int curAdj = app.curAdj;
13262        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13263            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13264
13265        mAdjSeq++;
13266
13267        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
13268                TOP_APP, false);
13269        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13270            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13271        if (nowHidden != wasHidden) {
13272            // Changed to/from hidden state, so apps after it in the LRU
13273            // list may also be changed.
13274            updateOomAdjLocked();
13275        }
13276        return success;
13277    }
13278
13279    final void updateOomAdjLocked() {
13280        final ActivityRecord TOP_ACT = resumedAppLocked();
13281        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13282
13283        if (false) {
13284            RuntimeException e = new RuntimeException();
13285            e.fillInStackTrace();
13286            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13287        }
13288
13289        mAdjSeq++;
13290        mNewNumServiceProcs = 0;
13291
13292        // Let's determine how many processes we have running vs.
13293        // how many slots we have for background processes; we may want
13294        // to put multiple processes in a slot of there are enough of
13295        // them.
13296        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13297                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13298        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
13299        if (emptyFactor < 1) emptyFactor = 1;
13300        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13301        if (hiddenFactor < 1) hiddenFactor = 1;
13302        int stepHidden = 0;
13303        int stepEmpty = 0;
13304        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13305        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13306        int numHidden = 0;
13307        int numEmpty = 0;
13308        int numTrimming = 0;
13309
13310        mNumNonHiddenProcs = 0;
13311        mNumHiddenProcs = 0;
13312
13313        // First update the OOM adjustment for each of the
13314        // application processes based on their current state.
13315        int i = mLruProcesses.size();
13316        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13317        int nextHiddenAdj = curHiddenAdj+1;
13318        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13319        int nextEmptyAdj = curEmptyAdj+2;
13320        while (i > 0) {
13321            i--;
13322            ProcessRecord app = mLruProcesses.get(i);
13323            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13324            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
13325            if (!app.killedBackground) {
13326                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13327                    // This process was assigned as a hidden process...  step the
13328                    // hidden level.
13329                    mNumHiddenProcs++;
13330                    if (curHiddenAdj != nextHiddenAdj) {
13331                        stepHidden++;
13332                        if (stepHidden >= hiddenFactor) {
13333                            stepHidden = 0;
13334                            curHiddenAdj = nextHiddenAdj;
13335                            nextHiddenAdj += 2;
13336                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13337                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13338                            }
13339                        }
13340                    }
13341                    numHidden++;
13342                    if (numHidden > hiddenProcessLimit) {
13343                        Slog.i(TAG, "No longer want " + app.processName
13344                                + " (pid " + app.pid + "): hidden #" + numHidden);
13345                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13346                                app.processName, app.setAdj, "too many background");
13347                        app.killedBackground = true;
13348                        Process.killProcessQuiet(app.pid);
13349                    }
13350                } else {
13351                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13352                        // This process was assigned as an empty process...  step the
13353                        // empty level.
13354                        if (curEmptyAdj != nextEmptyAdj) {
13355                            stepEmpty++;
13356                            if (stepEmpty >= emptyFactor) {
13357                                stepEmpty = 0;
13358                                curEmptyAdj = nextEmptyAdj;
13359                                nextEmptyAdj += 2;
13360                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13361                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13362                                }
13363                            }
13364                        }
13365                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13366                        mNumNonHiddenProcs++;
13367                    }
13368                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13369                        numEmpty++;
13370                        if (numEmpty > emptyProcessLimit) {
13371                            Slog.i(TAG, "No longer want " + app.processName
13372                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13373                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13374                                    app.processName, app.setAdj, "too many background");
13375                            app.killedBackground = true;
13376                            Process.killProcessQuiet(app.pid);
13377                        }
13378                    }
13379                }
13380                if (app.isolated && app.services.size() <= 0) {
13381                    // If this is an isolated process, and there are no
13382                    // services running in it, then the process is no longer
13383                    // needed.  We agressively kill these because we can by
13384                    // definition not re-use the same process again, and it is
13385                    // good to avoid having whatever code was running in them
13386                    // left sitting around after no longer needed.
13387                    Slog.i(TAG, "Isolated process " + app.processName
13388                            + " (pid " + app.pid + ") no longer needed");
13389                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13390                            app.processName, app.setAdj, "isolated not needed");
13391                    app.killedBackground = true;
13392                    Process.killProcessQuiet(app.pid);
13393                }
13394                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13395                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13396                        && !app.killedBackground) {
13397                    numTrimming++;
13398                }
13399            }
13400        }
13401
13402        mNumServiceProcs = mNewNumServiceProcs;
13403
13404        // Now determine the memory trimming level of background processes.
13405        // Unfortunately we need to start at the back of the list to do this
13406        // properly.  We only do this if the number of background apps we
13407        // are managing to keep around is less than half the maximum we desire;
13408        // if we are keeping a good number around, we'll let them use whatever
13409        // memory they want.
13410        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13411                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13412            final int numHiddenAndEmpty = numHidden + numEmpty;
13413            final int N = mLruProcesses.size();
13414            int factor = numTrimming/3;
13415            int minFactor = 2;
13416            if (mHomeProcess != null) minFactor++;
13417            if (mPreviousProcess != null) minFactor++;
13418            if (factor < minFactor) factor = minFactor;
13419            int step = 0;
13420            int fgTrimLevel;
13421            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13422                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13423            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13424                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13425            } else {
13426                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13427            }
13428            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13429            for (i=0; i<N; i++) {
13430                ProcessRecord app = mLruProcesses.get(i);
13431                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13432                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13433                        && !app.killedBackground) {
13434                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13435                        try {
13436                            app.thread.scheduleTrimMemory(curLevel);
13437                        } catch (RemoteException e) {
13438                        }
13439                        if (false) {
13440                            // For now we won't do this; our memory trimming seems
13441                            // to be good enough at this point that destroying
13442                            // activities causes more harm than good.
13443                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13444                                    && app != mHomeProcess && app != mPreviousProcess) {
13445                                // Need to do this on its own message because the stack may not
13446                                // be in a consistent state at this point.
13447                                // For these apps we will also finish their activities
13448                                // to help them free memory.
13449                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13450                            }
13451                        }
13452                    }
13453                    app.trimMemoryLevel = curLevel;
13454                    step++;
13455                    if (step >= factor) {
13456                        step = 0;
13457                        switch (curLevel) {
13458                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13459                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13460                                break;
13461                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13462                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13463                                break;
13464                        }
13465                    }
13466                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13467                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13468                            && app.thread != null) {
13469                        try {
13470                            app.thread.scheduleTrimMemory(
13471                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13472                        } catch (RemoteException e) {
13473                        }
13474                    }
13475                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13476                } else {
13477                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13478                            && app.pendingUiClean) {
13479                        // If this application is now in the background and it
13480                        // had done UI, then give it the special trim level to
13481                        // have it free UI resources.
13482                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13483                        if (app.trimMemoryLevel < level && app.thread != null) {
13484                            try {
13485                                app.thread.scheduleTrimMemory(level);
13486                            } catch (RemoteException e) {
13487                            }
13488                        }
13489                        app.pendingUiClean = false;
13490                    }
13491                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13492                        try {
13493                            app.thread.scheduleTrimMemory(fgTrimLevel);
13494                        } catch (RemoteException e) {
13495                        }
13496                    }
13497                    app.trimMemoryLevel = fgTrimLevel;
13498                }
13499            }
13500        } else {
13501            final int N = mLruProcesses.size();
13502            for (i=0; i<N; i++) {
13503                ProcessRecord app = mLruProcesses.get(i);
13504                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13505                        && app.pendingUiClean) {
13506                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13507                            && app.thread != null) {
13508                        try {
13509                            app.thread.scheduleTrimMemory(
13510                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13511                        } catch (RemoteException e) {
13512                        }
13513                    }
13514                    app.pendingUiClean = false;
13515                }
13516                app.trimMemoryLevel = 0;
13517            }
13518        }
13519
13520        if (mAlwaysFinishActivities) {
13521            // Need to do this on its own message because the stack may not
13522            // be in a consistent state at this point.
13523            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13524        }
13525    }
13526
13527    final void trimApplications() {
13528        synchronized (this) {
13529            int i;
13530
13531            // First remove any unused application processes whose package
13532            // has been removed.
13533            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13534                final ProcessRecord app = mRemovedProcesses.get(i);
13535                if (app.activities.size() == 0
13536                        && app.curReceiver == null && app.services.size() == 0) {
13537                    Slog.i(
13538                        TAG, "Exiting empty application process "
13539                        + app.processName + " ("
13540                        + (app.thread != null ? app.thread.asBinder() : null)
13541                        + ")\n");
13542                    if (app.pid > 0 && app.pid != MY_PID) {
13543                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13544                                app.processName, app.setAdj, "empty");
13545                        Process.killProcessQuiet(app.pid);
13546                    } else {
13547                        try {
13548                            app.thread.scheduleExit();
13549                        } catch (Exception e) {
13550                            // Ignore exceptions.
13551                        }
13552                    }
13553                    cleanUpApplicationRecordLocked(app, false, true, -1);
13554                    mRemovedProcesses.remove(i);
13555
13556                    if (app.persistent) {
13557                        if (app.persistent) {
13558                            addAppLocked(app.info, false);
13559                        }
13560                    }
13561                }
13562            }
13563
13564            // Now update the oom adj for all processes.
13565            updateOomAdjLocked();
13566        }
13567    }
13568
13569    /** This method sends the specified signal to each of the persistent apps */
13570    public void signalPersistentProcesses(int sig) throws RemoteException {
13571        if (sig != Process.SIGNAL_USR1) {
13572            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13573        }
13574
13575        synchronized (this) {
13576            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13577                    != PackageManager.PERMISSION_GRANTED) {
13578                throw new SecurityException("Requires permission "
13579                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13580            }
13581
13582            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13583                ProcessRecord r = mLruProcesses.get(i);
13584                if (r.thread != null && r.persistent) {
13585                    Process.sendSignal(r.pid, sig);
13586                }
13587            }
13588        }
13589    }
13590
13591    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13592        if (proc == null || proc == mProfileProc) {
13593            proc = mProfileProc;
13594            path = mProfileFile;
13595            profileType = mProfileType;
13596            clearProfilerLocked();
13597        }
13598        if (proc == null) {
13599            return;
13600        }
13601        try {
13602            proc.thread.profilerControl(false, path, null, profileType);
13603        } catch (RemoteException e) {
13604            throw new IllegalStateException("Process disappeared");
13605        }
13606    }
13607
13608    private void clearProfilerLocked() {
13609        if (mProfileFd != null) {
13610            try {
13611                mProfileFd.close();
13612            } catch (IOException e) {
13613            }
13614        }
13615        mProfileApp = null;
13616        mProfileProc = null;
13617        mProfileFile = null;
13618        mProfileType = 0;
13619        mAutoStopProfiler = false;
13620    }
13621
13622    public boolean profileControl(String process, boolean start,
13623            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13624
13625        try {
13626            synchronized (this) {
13627                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13628                // its own permission.
13629                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13630                        != PackageManager.PERMISSION_GRANTED) {
13631                    throw new SecurityException("Requires permission "
13632                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13633                }
13634
13635                if (start && fd == null) {
13636                    throw new IllegalArgumentException("null fd");
13637                }
13638
13639                ProcessRecord proc = null;
13640                if (process != null) {
13641                    try {
13642                        int pid = Integer.parseInt(process);
13643                        synchronized (mPidsSelfLocked) {
13644                            proc = mPidsSelfLocked.get(pid);
13645                        }
13646                    } catch (NumberFormatException e) {
13647                    }
13648
13649                    if (proc == null) {
13650                        HashMap<String, SparseArray<ProcessRecord>> all
13651                                = mProcessNames.getMap();
13652                        SparseArray<ProcessRecord> procs = all.get(process);
13653                        if (procs != null && procs.size() > 0) {
13654                            proc = procs.valueAt(0);
13655                        }
13656                    }
13657                }
13658
13659                if (start && (proc == null || proc.thread == null)) {
13660                    throw new IllegalArgumentException("Unknown process: " + process);
13661                }
13662
13663                if (start) {
13664                    stopProfilerLocked(null, null, 0);
13665                    setProfileApp(proc.info, proc.processName, path, fd, false);
13666                    mProfileProc = proc;
13667                    mProfileType = profileType;
13668                    try {
13669                        fd = fd.dup();
13670                    } catch (IOException e) {
13671                        fd = null;
13672                    }
13673                    proc.thread.profilerControl(start, path, fd, profileType);
13674                    fd = null;
13675                    mProfileFd = null;
13676                } else {
13677                    stopProfilerLocked(proc, path, profileType);
13678                    if (fd != null) {
13679                        try {
13680                            fd.close();
13681                        } catch (IOException e) {
13682                        }
13683                    }
13684                }
13685
13686                return true;
13687            }
13688        } catch (RemoteException e) {
13689            throw new IllegalStateException("Process disappeared");
13690        } finally {
13691            if (fd != null) {
13692                try {
13693                    fd.close();
13694                } catch (IOException e) {
13695                }
13696            }
13697        }
13698    }
13699
13700    public boolean dumpHeap(String process, boolean managed,
13701            String path, ParcelFileDescriptor fd) throws RemoteException {
13702
13703        try {
13704            synchronized (this) {
13705                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13706                // its own permission (same as profileControl).
13707                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13708                        != PackageManager.PERMISSION_GRANTED) {
13709                    throw new SecurityException("Requires permission "
13710                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13711                }
13712
13713                if (fd == null) {
13714                    throw new IllegalArgumentException("null fd");
13715                }
13716
13717                ProcessRecord proc = null;
13718                try {
13719                    int pid = Integer.parseInt(process);
13720                    synchronized (mPidsSelfLocked) {
13721                        proc = mPidsSelfLocked.get(pid);
13722                    }
13723                } catch (NumberFormatException e) {
13724                }
13725
13726                if (proc == null) {
13727                    HashMap<String, SparseArray<ProcessRecord>> all
13728                            = mProcessNames.getMap();
13729                    SparseArray<ProcessRecord> procs = all.get(process);
13730                    if (procs != null && procs.size() > 0) {
13731                        proc = procs.valueAt(0);
13732                    }
13733                }
13734
13735                if (proc == null || proc.thread == null) {
13736                    throw new IllegalArgumentException("Unknown process: " + process);
13737                }
13738
13739                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13740                if (!isDebuggable) {
13741                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13742                        throw new SecurityException("Process not debuggable: " + proc);
13743                    }
13744                }
13745
13746                proc.thread.dumpHeap(managed, path, fd);
13747                fd = null;
13748                return true;
13749            }
13750        } catch (RemoteException e) {
13751            throw new IllegalStateException("Process disappeared");
13752        } finally {
13753            if (fd != null) {
13754                try {
13755                    fd.close();
13756                } catch (IOException e) {
13757                }
13758            }
13759        }
13760    }
13761
13762    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13763    public void monitor() {
13764        synchronized (this) { }
13765    }
13766
13767    void onCoreSettingsChange(Bundle settings) {
13768        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13769            ProcessRecord processRecord = mLruProcesses.get(i);
13770            try {
13771                if (processRecord.thread != null) {
13772                    processRecord.thread.setCoreSettings(settings);
13773                }
13774            } catch (RemoteException re) {
13775                /* ignore */
13776            }
13777        }
13778    }
13779
13780    // Multi-user methods
13781
13782    @Override
13783    public boolean switchUser(int userId) {
13784        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13785                != PackageManager.PERMISSION_GRANTED) {
13786            String msg = "Permission Denial: switchUser() from pid="
13787                    + Binder.getCallingPid()
13788                    + ", uid=" + Binder.getCallingUid()
13789                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13790            Slog.w(TAG, msg);
13791            throw new SecurityException(msg);
13792        }
13793        synchronized (this) {
13794            if (mCurrentUserId == userId) {
13795                return true;
13796            }
13797
13798            // If the user we are switching to is not currently started, then
13799            // we need to start it now.
13800            if (mStartedUsers.get(userId) == null) {
13801                mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
13802            }
13803
13804            mCurrentUserId = userId;
13805            boolean haveActivities = mMainStack.switchUser(userId);
13806            if (!haveActivities) {
13807                startHomeActivityLocked(userId, mStartedUsers.get(userId));
13808            }
13809        }
13810
13811        long ident = Binder.clearCallingIdentity();
13812        try {
13813            // Inform of user switch
13814            Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13815            addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13816            mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,
13817                    android.Manifest.permission.MANAGE_USERS);
13818        } finally {
13819            Binder.restoreCallingIdentity(ident);
13820        }
13821
13822        return true;
13823    }
13824
13825    void finishUserSwitch(UserStartedState uss) {
13826        synchronized (this) {
13827            if (uss.mState == UserStartedState.STATE_BOOTING
13828                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
13829                uss.mState = UserStartedState.STATE_RUNNING;
13830                final int userId = uss.mHandle.getIdentifier();
13831                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
13832                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13833                broadcastIntentLocked(null, null, intent,
13834                        null, null, 0, null, null,
13835                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
13836                        false, false, MY_PID, Process.SYSTEM_UID, userId);
13837            }
13838        }
13839    }
13840
13841    @Override
13842    public int stopUser(final int userId, final IStopUserCallback callback) {
13843        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13844                != PackageManager.PERMISSION_GRANTED) {
13845            String msg = "Permission Denial: switchUser() from pid="
13846                    + Binder.getCallingPid()
13847                    + ", uid=" + Binder.getCallingUid()
13848                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13849            Slog.w(TAG, msg);
13850            throw new SecurityException(msg);
13851        }
13852        if (userId <= 0) {
13853            throw new IllegalArgumentException("Can't stop primary user " + userId);
13854        }
13855        synchronized (this) {
13856            if (mCurrentUserId == userId) {
13857                return ActivityManager.USER_OP_IS_CURRENT;
13858            }
13859
13860            final UserStartedState uss = mStartedUsers.get(userId);
13861            if (uss == null) {
13862                // User is not started, nothing to do...  but we do need to
13863                // callback if requested.
13864                if (callback != null) {
13865                    mHandler.post(new Runnable() {
13866                        @Override
13867                        public void run() {
13868                            try {
13869                                callback.userStopped(userId);
13870                            } catch (RemoteException e) {
13871                            }
13872                        }
13873                    });
13874                }
13875                return ActivityManager.USER_OP_SUCCESS;
13876            }
13877
13878            if (callback != null) {
13879                uss.mStopCallbacks.add(callback);
13880            }
13881
13882            if (uss.mState != UserStartedState.STATE_STOPPING) {
13883                uss.mState = UserStartedState.STATE_STOPPING;
13884
13885                long ident = Binder.clearCallingIdentity();
13886                try {
13887                    // Inform of user switch
13888                    Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13889                    final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() {
13890                        @Override
13891                        public void performReceive(Intent intent, int resultCode, String data,
13892                                Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
13893                            finishUserStop(uss);
13894                        }
13895                    };
13896                    broadcastIntentLocked(null, null, intent,
13897                            null, resultReceiver, 0, null, null, null,
13898                            true, false, MY_PID, Process.SYSTEM_UID, userId);
13899                } finally {
13900                    Binder.restoreCallingIdentity(ident);
13901                }
13902            }
13903        }
13904
13905        return ActivityManager.USER_OP_SUCCESS;
13906    }
13907
13908    void finishUserStop(UserStartedState uss) {
13909        final int userId = uss.mHandle.getIdentifier();
13910        boolean stopped;
13911        ArrayList<IStopUserCallback> callbacks;
13912        synchronized (this) {
13913            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
13914            if (uss.mState != UserStartedState.STATE_STOPPING
13915                    || mStartedUsers.get(userId) != uss) {
13916                stopped = false;
13917            } else {
13918                stopped = true;
13919                // User can no longer run.
13920                mStartedUsers.remove(userId);
13921
13922                // Clean up all state and processes associated with the user.
13923                // Kill all the processes for the user.
13924                forceStopUserLocked(userId);
13925            }
13926        }
13927
13928        for (int i=0; i<callbacks.size(); i++) {
13929            try {
13930                if (stopped) callbacks.get(i).userStopped(userId);
13931                else callbacks.get(i).userStopAborted(userId);
13932            } catch (RemoteException e) {
13933            }
13934        }
13935    }
13936
13937    @Override
13938    public UserInfo getCurrentUser() {
13939        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13940                != PackageManager.PERMISSION_GRANTED) {
13941            String msg = "Permission Denial: getCurrentUser() from pid="
13942                    + Binder.getCallingPid()
13943                    + ", uid=" + Binder.getCallingUid()
13944                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13945            Slog.w(TAG, msg);
13946            throw new SecurityException(msg);
13947        }
13948        synchronized (this) {
13949            return getUserManager().getUserInfo(mCurrentUserId);
13950        }
13951    }
13952
13953    private boolean userExists(int userId) {
13954        UserInfo user = getUserManager().getUserInfo(userId);
13955        return user != null;
13956    }
13957
13958    UserManager getUserManager() {
13959        if (mUserManager == null) {
13960            mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
13961        }
13962        return mUserManager;
13963    }
13964
13965    private void checkValidCaller(int uid, int userId) {
13966        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
13967
13968        throw new SecurityException("Caller uid=" + uid
13969                + " is not privileged to communicate with user=" + userId);
13970    }
13971
13972    private int applyUserId(int uid, int userId) {
13973        return UserHandle.getUid(userId, uid);
13974    }
13975
13976    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
13977        if (info == null) return null;
13978        ApplicationInfo newInfo = new ApplicationInfo(info);
13979        newInfo.uid = applyUserId(info.uid, userId);
13980        newInfo.dataDir = USER_DATA_DIR + userId + "/"
13981                + info.packageName;
13982        return newInfo;
13983    }
13984
13985    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
13986        if (aInfo == null
13987                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
13988            return aInfo;
13989        }
13990
13991        ActivityInfo info = new ActivityInfo(aInfo);
13992        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
13993        return info;
13994    }
13995}
13996