ActivityManagerService.java revision 20e809870d8ac1e5b848f2daf51b2272ef89bdfc
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.Log;
120import android.util.Pair;
121import android.util.PrintWriterPrinter;
122import android.util.Slog;
123import android.util.SparseArray;
124import android.util.SparseIntArray;
125import android.util.TimeUtils;
126import android.view.Gravity;
127import android.view.LayoutInflater;
128import android.view.View;
129import android.view.WindowManager;
130import android.view.WindowManagerPolicy;
131
132import java.io.BufferedInputStream;
133import java.io.BufferedOutputStream;
134import java.io.BufferedReader;
135import java.io.DataInputStream;
136import java.io.DataOutputStream;
137import java.io.File;
138import java.io.FileDescriptor;
139import java.io.FileInputStream;
140import java.io.FileNotFoundException;
141import java.io.FileOutputStream;
142import java.io.IOException;
143import java.io.InputStreamReader;
144import java.io.PrintWriter;
145import java.io.StringWriter;
146import java.lang.ref.WeakReference;
147import java.util.ArrayList;
148import java.util.Collections;
149import java.util.Comparator;
150import java.util.HashMap;
151import java.util.HashSet;
152import java.util.Iterator;
153import java.util.List;
154import java.util.Locale;
155import java.util.Map;
156import java.util.Map.Entry;
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.locale = Locale.getDefault();
1535        mConfigurationSeq = mConfiguration.seq = 1;
1536        mProcessStats.init();
1537
1538        mCompatModePackages = new CompatModePackages(this, systemDir);
1539
1540        // Add ourself to the Watchdog monitors.
1541        Watchdog.getInstance().addMonitor(this);
1542
1543        mProcessStatsThread = new Thread("ProcessStats") {
1544            public void run() {
1545                while (true) {
1546                    try {
1547                        try {
1548                            synchronized(this) {
1549                                final long now = SystemClock.uptimeMillis();
1550                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1551                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1552                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1553                                //        + ", write delay=" + nextWriteDelay);
1554                                if (nextWriteDelay < nextCpuDelay) {
1555                                    nextCpuDelay = nextWriteDelay;
1556                                }
1557                                if (nextCpuDelay > 0) {
1558                                    mProcessStatsMutexFree.set(true);
1559                                    this.wait(nextCpuDelay);
1560                                }
1561                            }
1562                        } catch (InterruptedException e) {
1563                        }
1564                        updateCpuStatsNow();
1565                    } catch (Exception e) {
1566                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1567                    }
1568                }
1569            }
1570        };
1571        mProcessStatsThread.start();
1572    }
1573
1574    @Override
1575    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1576            throws RemoteException {
1577        if (code == SYSPROPS_TRANSACTION) {
1578            // We need to tell all apps about the system property change.
1579            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1580            synchronized(this) {
1581                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1582                    final int NA = apps.size();
1583                    for (int ia=0; ia<NA; ia++) {
1584                        ProcessRecord app = apps.valueAt(ia);
1585                        if (app.thread != null) {
1586                            procs.add(app.thread.asBinder());
1587                        }
1588                    }
1589                }
1590            }
1591
1592            int N = procs.size();
1593            for (int i=0; i<N; i++) {
1594                Parcel data2 = Parcel.obtain();
1595                try {
1596                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1597                } catch (RemoteException e) {
1598                }
1599                data2.recycle();
1600            }
1601        }
1602        try {
1603            return super.onTransact(code, data, reply, flags);
1604        } catch (RuntimeException e) {
1605            // The activity manager only throws security exceptions, so let's
1606            // log all others.
1607            if (!(e instanceof SecurityException)) {
1608                Slog.e(TAG, "Activity Manager Crash", e);
1609            }
1610            throw e;
1611        }
1612    }
1613
1614    void updateCpuStats() {
1615        final long now = SystemClock.uptimeMillis();
1616        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1617            return;
1618        }
1619        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1620            synchronized (mProcessStatsThread) {
1621                mProcessStatsThread.notify();
1622            }
1623        }
1624    }
1625
1626    void updateCpuStatsNow() {
1627        synchronized (mProcessStatsThread) {
1628            mProcessStatsMutexFree.set(false);
1629            final long now = SystemClock.uptimeMillis();
1630            boolean haveNewCpuStats = false;
1631
1632            if (MONITOR_CPU_USAGE &&
1633                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1634                mLastCpuTime.set(now);
1635                haveNewCpuStats = true;
1636                mProcessStats.update();
1637                //Slog.i(TAG, mProcessStats.printCurrentState());
1638                //Slog.i(TAG, "Total CPU usage: "
1639                //        + mProcessStats.getTotalCpuPercent() + "%");
1640
1641                // Slog the cpu usage if the property is set.
1642                if ("true".equals(SystemProperties.get("events.cpu"))) {
1643                    int user = mProcessStats.getLastUserTime();
1644                    int system = mProcessStats.getLastSystemTime();
1645                    int iowait = mProcessStats.getLastIoWaitTime();
1646                    int irq = mProcessStats.getLastIrqTime();
1647                    int softIrq = mProcessStats.getLastSoftIrqTime();
1648                    int idle = mProcessStats.getLastIdleTime();
1649
1650                    int total = user + system + iowait + irq + softIrq + idle;
1651                    if (total == 0) total = 1;
1652
1653                    EventLog.writeEvent(EventLogTags.CPU,
1654                            ((user+system+iowait+irq+softIrq) * 100) / total,
1655                            (user * 100) / total,
1656                            (system * 100) / total,
1657                            (iowait * 100) / total,
1658                            (irq * 100) / total,
1659                            (softIrq * 100) / total);
1660                }
1661            }
1662
1663            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1664            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1665            synchronized(bstats) {
1666                synchronized(mPidsSelfLocked) {
1667                    if (haveNewCpuStats) {
1668                        if (mOnBattery) {
1669                            int perc = bstats.startAddingCpuLocked();
1670                            int totalUTime = 0;
1671                            int totalSTime = 0;
1672                            final int N = mProcessStats.countStats();
1673                            for (int i=0; i<N; i++) {
1674                                ProcessStats.Stats st = mProcessStats.getStats(i);
1675                                if (!st.working) {
1676                                    continue;
1677                                }
1678                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1679                                int otherUTime = (st.rel_utime*perc)/100;
1680                                int otherSTime = (st.rel_stime*perc)/100;
1681                                totalUTime += otherUTime;
1682                                totalSTime += otherSTime;
1683                                if (pr != null) {
1684                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1685                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1686                                            st.rel_stime-otherSTime);
1687                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1688                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1689                                } else {
1690                                    BatteryStatsImpl.Uid.Proc ps =
1691                                            bstats.getProcessStatsLocked(st.name, st.pid);
1692                                    if (ps != null) {
1693                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1694                                                st.rel_stime-otherSTime);
1695                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1696                                    }
1697                                }
1698                            }
1699                            bstats.finishAddingCpuLocked(perc, totalUTime,
1700                                    totalSTime, cpuSpeedTimes);
1701                        }
1702                    }
1703                }
1704
1705                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1706                    mLastWriteTime = now;
1707                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1708                }
1709            }
1710        }
1711    }
1712
1713    @Override
1714    public void batteryNeedsCpuUpdate() {
1715        updateCpuStatsNow();
1716    }
1717
1718    @Override
1719    public void batteryPowerChanged(boolean onBattery) {
1720        // When plugging in, update the CPU stats first before changing
1721        // the plug state.
1722        updateCpuStatsNow();
1723        synchronized (this) {
1724            synchronized(mPidsSelfLocked) {
1725                mOnBattery = DEBUG_POWER ? true : onBattery;
1726            }
1727        }
1728    }
1729
1730    /**
1731     * Initialize the application bind args. These are passed to each
1732     * process when the bindApplication() IPC is sent to the process. They're
1733     * lazily setup to make sure the services are running when they're asked for.
1734     */
1735    private HashMap<String, IBinder> getCommonServicesLocked() {
1736        if (mAppBindArgs == null) {
1737            mAppBindArgs = new HashMap<String, IBinder>();
1738
1739            // Setup the application init args
1740            mAppBindArgs.put("package", ServiceManager.getService("package"));
1741            mAppBindArgs.put("window", ServiceManager.getService("window"));
1742            mAppBindArgs.put(Context.ALARM_SERVICE,
1743                    ServiceManager.getService(Context.ALARM_SERVICE));
1744        }
1745        return mAppBindArgs;
1746    }
1747
1748    final void setFocusedActivityLocked(ActivityRecord r) {
1749        if (mFocusedActivity != r) {
1750            mFocusedActivity = r;
1751            if (r != null) {
1752                mWindowManager.setFocusedApp(r.appToken, true);
1753            }
1754        }
1755    }
1756
1757    private final void updateLruProcessInternalLocked(ProcessRecord app,
1758            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1759        // put it on the LRU to keep track of when it should be exited.
1760        int lrui = mLruProcesses.indexOf(app);
1761        if (lrui >= 0) mLruProcesses.remove(lrui);
1762
1763        int i = mLruProcesses.size()-1;
1764        int skipTop = 0;
1765
1766        app.lruSeq = mLruSeq;
1767
1768        // compute the new weight for this process.
1769        if (updateActivityTime) {
1770            app.lastActivityTime = SystemClock.uptimeMillis();
1771        }
1772        if (app.activities.size() > 0) {
1773            // If this process has activities, we more strongly want to keep
1774            // it around.
1775            app.lruWeight = app.lastActivityTime;
1776        } else if (app.pubProviders.size() > 0) {
1777            // If this process contains content providers, we want to keep
1778            // it a little more strongly.
1779            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1780            // Also don't let it kick out the first few "real" hidden processes.
1781            skipTop = ProcessList.MIN_HIDDEN_APPS;
1782        } else {
1783            // If this process doesn't have activities, we less strongly
1784            // want to keep it around, and generally want to avoid getting
1785            // in front of any very recently used activities.
1786            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1787            // Also don't let it kick out the first few "real" hidden processes.
1788            skipTop = ProcessList.MIN_HIDDEN_APPS;
1789        }
1790
1791        while (i >= 0) {
1792            ProcessRecord p = mLruProcesses.get(i);
1793            // If this app shouldn't be in front of the first N background
1794            // apps, then skip over that many that are currently hidden.
1795            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1796                skipTop--;
1797            }
1798            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1799                mLruProcesses.add(i+1, app);
1800                break;
1801            }
1802            i--;
1803        }
1804        if (i < 0) {
1805            mLruProcesses.add(0, app);
1806        }
1807
1808        // If the app is currently using a content provider or service,
1809        // bump those processes as well.
1810        if (app.connections.size() > 0) {
1811            for (ConnectionRecord cr : app.connections) {
1812                if (cr.binding != null && cr.binding.service != null
1813                        && cr.binding.service.app != null
1814                        && cr.binding.service.app.lruSeq != mLruSeq) {
1815                    updateLruProcessInternalLocked(cr.binding.service.app, false,
1816                            updateActivityTime, i+1);
1817                }
1818            }
1819        }
1820        for (int j=app.conProviders.size()-1; j>=0; j--) {
1821            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1822            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1823                updateLruProcessInternalLocked(cpr.proc, false,
1824                        updateActivityTime, i+1);
1825            }
1826        }
1827
1828        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1829        if (oomAdj) {
1830            updateOomAdjLocked();
1831        }
1832    }
1833
1834    final void updateLruProcessLocked(ProcessRecord app,
1835            boolean oomAdj, boolean updateActivityTime) {
1836        mLruSeq++;
1837        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1838    }
1839
1840    final ProcessRecord getProcessRecordLocked(
1841            String processName, int uid) {
1842        if (uid == Process.SYSTEM_UID) {
1843            // The system gets to run in any process.  If there are multiple
1844            // processes with the same uid, just pick the first (this
1845            // should never happen).
1846            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1847                    processName);
1848            if (procs == null) return null;
1849            final int N = procs.size();
1850            for (int i = 0; i < N; i++) {
1851                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1852            }
1853        }
1854        ProcessRecord proc = mProcessNames.get(processName, uid);
1855        return proc;
1856    }
1857
1858    void ensurePackageDexOpt(String packageName) {
1859        IPackageManager pm = AppGlobals.getPackageManager();
1860        try {
1861            if (pm.performDexOpt(packageName)) {
1862                mDidDexOpt = true;
1863            }
1864        } catch (RemoteException e) {
1865        }
1866    }
1867
1868    boolean isNextTransitionForward() {
1869        int transit = mWindowManager.getPendingAppTransition();
1870        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1871                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1872                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1873    }
1874
1875    final ProcessRecord startProcessLocked(String processName,
1876            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1877            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1878            boolean isolated) {
1879        ProcessRecord app;
1880        if (!isolated) {
1881            app = getProcessRecordLocked(processName, info.uid);
1882        } else {
1883            // If this is an isolated process, it can't re-use an existing process.
1884            app = null;
1885        }
1886        // We don't have to do anything more if:
1887        // (1) There is an existing application record; and
1888        // (2) The caller doesn't think it is dead, OR there is no thread
1889        //     object attached to it so we know it couldn't have crashed; and
1890        // (3) There is a pid assigned to it, so it is either starting or
1891        //     already running.
1892        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1893                + " app=" + app + " knownToBeDead=" + knownToBeDead
1894                + " thread=" + (app != null ? app.thread : null)
1895                + " pid=" + (app != null ? app.pid : -1));
1896        if (app != null && app.pid > 0) {
1897            if (!knownToBeDead || app.thread == null) {
1898                // We already have the app running, or are waiting for it to
1899                // come up (we have a pid but not yet its thread), so keep it.
1900                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1901                // If this is a new package in the process, add the package to the list
1902                app.addPackage(info.packageName);
1903                return app;
1904            } else {
1905                // An application record is attached to a previous process,
1906                // clean it up now.
1907                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1908                handleAppDiedLocked(app, true, true);
1909            }
1910        }
1911
1912        String hostingNameStr = hostingName != null
1913                ? hostingName.flattenToShortString() : null;
1914
1915        if (!isolated) {
1916            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1917                // If we are in the background, then check to see if this process
1918                // is bad.  If so, we will just silently fail.
1919                if (mBadProcesses.get(info.processName, info.uid) != null) {
1920                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1921                            + "/" + info.processName);
1922                    return null;
1923                }
1924            } else {
1925                // When the user is explicitly starting a process, then clear its
1926                // crash count so that we won't make it bad until they see at
1927                // least one crash dialog again, and make the process good again
1928                // if it had been bad.
1929                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1930                        + "/" + info.processName);
1931                mProcessCrashTimes.remove(info.processName, info.uid);
1932                if (mBadProcesses.get(info.processName, info.uid) != null) {
1933                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1934                            info.processName);
1935                    mBadProcesses.remove(info.processName, info.uid);
1936                    if (app != null) {
1937                        app.bad = false;
1938                    }
1939                }
1940            }
1941        }
1942
1943        if (app == null) {
1944            app = newProcessRecordLocked(null, info, processName, isolated);
1945            if (app == null) {
1946                Slog.w(TAG, "Failed making new process record for "
1947                        + processName + "/" + info.uid + " isolated=" + isolated);
1948                return null;
1949            }
1950            mProcessNames.put(processName, app.uid, app);
1951            if (isolated) {
1952                mIsolatedProcesses.put(app.uid, app);
1953            }
1954        } else {
1955            // If this is a new package in the process, add the package to the list
1956            app.addPackage(info.packageName);
1957        }
1958
1959        // If the system is not ready yet, then hold off on starting this
1960        // process until it is.
1961        if (!mProcessesReady
1962                && !isAllowedWhileBooting(info)
1963                && !allowWhileBooting) {
1964            if (!mProcessesOnHold.contains(app)) {
1965                mProcessesOnHold.add(app);
1966            }
1967            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1968            return app;
1969        }
1970
1971        startProcessLocked(app, hostingType, hostingNameStr);
1972        return (app.pid != 0) ? app : null;
1973    }
1974
1975    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1976        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1977    }
1978
1979    private final void startProcessLocked(ProcessRecord app,
1980            String hostingType, String hostingNameStr) {
1981        if (app.pid > 0 && app.pid != MY_PID) {
1982            synchronized (mPidsSelfLocked) {
1983                mPidsSelfLocked.remove(app.pid);
1984                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1985            }
1986            app.setPid(0);
1987        }
1988
1989        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1990                "startProcessLocked removing on hold: " + app);
1991        mProcessesOnHold.remove(app);
1992
1993        updateCpuStats();
1994
1995        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1996        mProcDeaths[0] = 0;
1997
1998        try {
1999            int uid = app.uid;
2000
2001            int[] gids = null;
2002            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2003            if (!app.isolated) {
2004                try {
2005                    final PackageManager pm = mContext.getPackageManager();
2006                    gids = pm.getPackageGids(app.info.packageName);
2007
2008                    if (Environment.isExternalStorageEmulated()) {
2009                        if (pm.checkPermission(
2010                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2011                                app.info.packageName) == PERMISSION_GRANTED) {
2012                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2013                        } else {
2014                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2015                        }
2016                    }
2017                } catch (PackageManager.NameNotFoundException e) {
2018                    Slog.w(TAG, "Unable to retrieve gids", e);
2019                }
2020            }
2021            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2022                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2023                        && mTopComponent != null
2024                        && app.processName.equals(mTopComponent.getPackageName())) {
2025                    uid = 0;
2026                }
2027                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2028                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2029                    uid = 0;
2030                }
2031            }
2032            int debugFlags = 0;
2033            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2034                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2035                // Also turn on CheckJNI for debuggable apps. It's quite
2036                // awkward to turn on otherwise.
2037                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2038            }
2039            // Run the app in safe mode if its manifest requests so or the
2040            // system is booted in safe mode.
2041            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2042                Zygote.systemInSafeMode == true) {
2043                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2044            }
2045            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2046                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2047            }
2048            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2049                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2050            }
2051            if ("1".equals(SystemProperties.get("debug.assert"))) {
2052                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2053            }
2054
2055            // Start the process.  It will either succeed and return a result containing
2056            // the PID of the new process, or else throw a RuntimeException.
2057            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2058                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2059                    app.info.targetSdkVersion, null, null);
2060
2061            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2062            synchronized (bs) {
2063                if (bs.isOnBattery()) {
2064                    app.batteryStats.incStartsLocked();
2065                }
2066            }
2067
2068            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2069                    app.processName, hostingType,
2070                    hostingNameStr != null ? hostingNameStr : "");
2071
2072            if (app.persistent) {
2073                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2074            }
2075
2076            StringBuilder buf = mStringBuilder;
2077            buf.setLength(0);
2078            buf.append("Start proc ");
2079            buf.append(app.processName);
2080            buf.append(" for ");
2081            buf.append(hostingType);
2082            if (hostingNameStr != null) {
2083                buf.append(" ");
2084                buf.append(hostingNameStr);
2085            }
2086            buf.append(": pid=");
2087            buf.append(startResult.pid);
2088            buf.append(" uid=");
2089            buf.append(uid);
2090            buf.append(" gids={");
2091            if (gids != null) {
2092                for (int gi=0; gi<gids.length; gi++) {
2093                    if (gi != 0) buf.append(", ");
2094                    buf.append(gids[gi]);
2095
2096                }
2097            }
2098            buf.append("}");
2099            Slog.i(TAG, buf.toString());
2100            app.setPid(startResult.pid);
2101            app.usingWrapper = startResult.usingWrapper;
2102            app.removed = false;
2103            synchronized (mPidsSelfLocked) {
2104                this.mPidsSelfLocked.put(startResult.pid, app);
2105                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2106                msg.obj = app;
2107                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2108                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2109            }
2110        } catch (RuntimeException e) {
2111            // XXX do better error recovery.
2112            app.setPid(0);
2113            Slog.e(TAG, "Failure starting process " + app.processName, e);
2114        }
2115    }
2116
2117    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2118        if (resumed) {
2119            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2120        } else {
2121            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2122        }
2123    }
2124
2125    boolean startHomeActivityLocked(int userId, UserStartedState startingUser) {
2126        if (mHeadless) {
2127            // Added because none of the other calls to ensureBootCompleted seem to fire
2128            // when running headless.
2129            ensureBootCompleted();
2130            return false;
2131        }
2132
2133        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2134                && mTopAction == null) {
2135            // We are running in factory test mode, but unable to find
2136            // the factory test app, so just sit around displaying the
2137            // error message and don't try to start anything.
2138            return false;
2139        }
2140        Intent intent = new Intent(
2141            mTopAction,
2142            mTopData != null ? Uri.parse(mTopData) : null);
2143        intent.setComponent(mTopComponent);
2144        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2145            intent.addCategory(Intent.CATEGORY_HOME);
2146        }
2147        ActivityInfo aInfo =
2148            intent.resolveActivityInfo(mContext.getPackageManager(),
2149                    STOCK_PM_FLAGS);
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    /**
2173     * Starts the "new version setup screen" if appropriate.
2174     */
2175    void startSetupActivityLocked() {
2176        // Only do this once per boot.
2177        if (mCheckedForSetup) {
2178            return;
2179        }
2180
2181        // We will show this screen if the current one is a different
2182        // version than the last one shown, and we are not running in
2183        // low-level factory test mode.
2184        final ContentResolver resolver = mContext.getContentResolver();
2185        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2186                Settings.Secure.getInt(resolver,
2187                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2188            mCheckedForSetup = true;
2189
2190            // See if we should be showing the platform update setup UI.
2191            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2192            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2193                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2194
2195            // We don't allow third party apps to replace this.
2196            ResolveInfo ri = null;
2197            for (int i=0; ris != null && i<ris.size(); i++) {
2198                if ((ris.get(i).activityInfo.applicationInfo.flags
2199                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2200                    ri = ris.get(i);
2201                    break;
2202                }
2203            }
2204
2205            if (ri != null) {
2206                String vers = ri.activityInfo.metaData != null
2207                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2208                        : null;
2209                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2210                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2211                            Intent.METADATA_SETUP_VERSION);
2212                }
2213                String lastVers = Settings.Secure.getString(
2214                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2215                if (vers != null && !vers.equals(lastVers)) {
2216                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2217                    intent.setComponent(new ComponentName(
2218                            ri.activityInfo.packageName, ri.activityInfo.name));
2219                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2220                            null, null, 0, 0, 0, 0, null, false, null);
2221                }
2222            }
2223        }
2224    }
2225
2226    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2227        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2228    }
2229
2230    void enforceNotIsolatedCaller(String caller) {
2231        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2232            throw new SecurityException("Isolated process not allowed to call " + caller);
2233        }
2234    }
2235
2236    public int getFrontActivityScreenCompatMode() {
2237        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2238        synchronized (this) {
2239            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2240        }
2241    }
2242
2243    public void setFrontActivityScreenCompatMode(int mode) {
2244        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2245                "setFrontActivityScreenCompatMode");
2246        synchronized (this) {
2247            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2248        }
2249    }
2250
2251    public int getPackageScreenCompatMode(String packageName) {
2252        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2253        synchronized (this) {
2254            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2255        }
2256    }
2257
2258    public void setPackageScreenCompatMode(String packageName, int mode) {
2259        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2260                "setPackageScreenCompatMode");
2261        synchronized (this) {
2262            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2263        }
2264    }
2265
2266    public boolean getPackageAskScreenCompat(String packageName) {
2267        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2268        synchronized (this) {
2269            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2270        }
2271    }
2272
2273    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2274        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2275                "setPackageAskScreenCompat");
2276        synchronized (this) {
2277            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2278        }
2279    }
2280
2281    void reportResumedActivityLocked(ActivityRecord r) {
2282        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2283        updateUsageStats(r, true);
2284    }
2285
2286    private void dispatchProcessesChanged() {
2287        int N;
2288        synchronized (this) {
2289            N = mPendingProcessChanges.size();
2290            if (mActiveProcessChanges.length < N) {
2291                mActiveProcessChanges = new ProcessChangeItem[N];
2292            }
2293            mPendingProcessChanges.toArray(mActiveProcessChanges);
2294            mAvailProcessChanges.addAll(mPendingProcessChanges);
2295            mPendingProcessChanges.clear();
2296            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2297        }
2298        int i = mProcessObservers.beginBroadcast();
2299        while (i > 0) {
2300            i--;
2301            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2302            if (observer != null) {
2303                try {
2304                    for (int j=0; j<N; j++) {
2305                        ProcessChangeItem item = mActiveProcessChanges[j];
2306                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2307                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2308                                    + item.pid + " uid=" + item.uid + ": "
2309                                    + item.foregroundActivities);
2310                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2311                                    item.foregroundActivities);
2312                        }
2313                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2314                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2315                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2316                            observer.onImportanceChanged(item.pid, item.uid,
2317                                    item.importance);
2318                        }
2319                    }
2320                } catch (RemoteException e) {
2321                }
2322            }
2323        }
2324        mProcessObservers.finishBroadcast();
2325    }
2326
2327    private void dispatchProcessDied(int pid, int uid) {
2328        int i = mProcessObservers.beginBroadcast();
2329        while (i > 0) {
2330            i--;
2331            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2332            if (observer != null) {
2333                try {
2334                    observer.onProcessDied(pid, uid);
2335                } catch (RemoteException e) {
2336                }
2337            }
2338        }
2339        mProcessObservers.finishBroadcast();
2340    }
2341
2342    final void doPendingActivityLaunchesLocked(boolean doResume) {
2343        final int N = mPendingActivityLaunches.size();
2344        if (N <= 0) {
2345            return;
2346        }
2347        for (int i=0; i<N; i++) {
2348            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2349            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2350                    pal.startFlags, doResume && i == (N-1), null);
2351        }
2352        mPendingActivityLaunches.clear();
2353    }
2354
2355    public final int startActivity(IApplicationThread caller,
2356            Intent intent, String resolvedType, IBinder resultTo,
2357            String resultWho, int requestCode, int startFlags,
2358            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2359        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2360                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2361    }
2362
2363    public final int startActivityAsUser(IApplicationThread caller,
2364            Intent intent, String resolvedType, IBinder resultTo,
2365            String resultWho, int requestCode, int startFlags,
2366            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2367        enforceNotIsolatedCaller("startActivity");
2368        if (userId != UserHandle.getCallingUserId()) {
2369            userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2370                    false, true, "startActivity", null);
2371        } else {
2372            if (intent.getCategories() != null
2373                    && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2374                // Requesting home, set the identity to the current user
2375                // HACK!
2376                userId = mCurrentUserId;
2377            }
2378        }
2379        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2380                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2381                null, null, options, userId);
2382    }
2383
2384    public final WaitResult startActivityAndWait(IApplicationThread caller,
2385            Intent intent, String resolvedType, IBinder resultTo,
2386            String resultWho, int requestCode, int startFlags, String profileFile,
2387            ParcelFileDescriptor profileFd, Bundle options) {
2388        enforceNotIsolatedCaller("startActivityAndWait");
2389        WaitResult res = new WaitResult();
2390        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2391                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2392                res, null, options, UserHandle.getCallingUserId());
2393        return res;
2394    }
2395
2396    public final int startActivityWithConfig(IApplicationThread caller,
2397            Intent intent, String resolvedType, IBinder resultTo,
2398            String resultWho, int requestCode, int startFlags, Configuration config,
2399            Bundle options, int userId) {
2400        enforceNotIsolatedCaller("startActivityWithConfig");
2401        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2402                false, true, "startActivityWithConfig", null);
2403        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2404                resultTo, resultWho, requestCode, startFlags,
2405                null, null, null, config, options, userId);
2406        return ret;
2407    }
2408
2409    public int startActivityIntentSender(IApplicationThread caller,
2410            IntentSender intent, Intent fillInIntent, String resolvedType,
2411            IBinder resultTo, String resultWho, int requestCode,
2412            int flagsMask, int flagsValues, Bundle options) {
2413        enforceNotIsolatedCaller("startActivityIntentSender");
2414        // Refuse possible leaked file descriptors
2415        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2416            throw new IllegalArgumentException("File descriptors passed in Intent");
2417        }
2418
2419        IIntentSender sender = intent.getTarget();
2420        if (!(sender instanceof PendingIntentRecord)) {
2421            throw new IllegalArgumentException("Bad PendingIntent object");
2422        }
2423
2424        PendingIntentRecord pir = (PendingIntentRecord)sender;
2425
2426        synchronized (this) {
2427            // If this is coming from the currently resumed activity, it is
2428            // effectively saying that app switches are allowed at this point.
2429            if (mMainStack.mResumedActivity != null
2430                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2431                            Binder.getCallingUid()) {
2432                mAppSwitchesAllowedTime = 0;
2433            }
2434        }
2435        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2436                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2437        return ret;
2438    }
2439
2440    public boolean startNextMatchingActivity(IBinder callingActivity,
2441            Intent intent, Bundle options) {
2442        // Refuse possible leaked file descriptors
2443        if (intent != null && intent.hasFileDescriptors() == true) {
2444            throw new IllegalArgumentException("File descriptors passed in Intent");
2445        }
2446
2447        synchronized (this) {
2448            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2449            if (r == null) {
2450                ActivityOptions.abort(options);
2451                return false;
2452            }
2453            if (r.app == null || r.app.thread == null) {
2454                // The caller is not running...  d'oh!
2455                ActivityOptions.abort(options);
2456                return false;
2457            }
2458            intent = new Intent(intent);
2459            // The caller is not allowed to change the data.
2460            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2461            // And we are resetting to find the next component...
2462            intent.setComponent(null);
2463
2464            ActivityInfo aInfo = null;
2465            try {
2466                List<ResolveInfo> resolves =
2467                    AppGlobals.getPackageManager().queryIntentActivities(
2468                            intent, r.resolvedType,
2469                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2470                            UserHandle.getCallingUserId());
2471
2472                // Look for the original activity in the list...
2473                final int N = resolves != null ? resolves.size() : 0;
2474                for (int i=0; i<N; i++) {
2475                    ResolveInfo rInfo = resolves.get(i);
2476                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2477                            && rInfo.activityInfo.name.equals(r.info.name)) {
2478                        // We found the current one...  the next matching is
2479                        // after it.
2480                        i++;
2481                        if (i<N) {
2482                            aInfo = resolves.get(i).activityInfo;
2483                        }
2484                        break;
2485                    }
2486                }
2487            } catch (RemoteException e) {
2488            }
2489
2490            if (aInfo == null) {
2491                // Nobody who is next!
2492                ActivityOptions.abort(options);
2493                return false;
2494            }
2495
2496            intent.setComponent(new ComponentName(
2497                    aInfo.applicationInfo.packageName, aInfo.name));
2498            intent.setFlags(intent.getFlags()&~(
2499                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2500                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2501                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2502                    Intent.FLAG_ACTIVITY_NEW_TASK));
2503
2504            // Okay now we need to start the new activity, replacing the
2505            // currently running activity.  This is a little tricky because
2506            // we want to start the new one as if the current one is finished,
2507            // but not finish the current one first so that there is no flicker.
2508            // And thus...
2509            final boolean wasFinishing = r.finishing;
2510            r.finishing = true;
2511
2512            // Propagate reply information over to the new activity.
2513            final ActivityRecord resultTo = r.resultTo;
2514            final String resultWho = r.resultWho;
2515            final int requestCode = r.requestCode;
2516            r.resultTo = null;
2517            if (resultTo != null) {
2518                resultTo.removeResultsLocked(r, resultWho, requestCode);
2519            }
2520
2521            final long origId = Binder.clearCallingIdentity();
2522            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2523                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2524                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2525                    options, false, null);
2526            Binder.restoreCallingIdentity(origId);
2527
2528            r.finishing = wasFinishing;
2529            if (res != ActivityManager.START_SUCCESS) {
2530                return false;
2531            }
2532            return true;
2533        }
2534    }
2535
2536    final int startActivityInPackage(int uid,
2537            Intent intent, String resolvedType, IBinder resultTo,
2538            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2539
2540        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2541                false, true, "startActivityInPackage", null);
2542
2543        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2544                resultTo, resultWho, requestCode, startFlags,
2545                null, null, null, null, options, userId);
2546        return ret;
2547    }
2548
2549    public final int startActivities(IApplicationThread caller,
2550            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2551        enforceNotIsolatedCaller("startActivities");
2552        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2553                options, UserHandle.getCallingUserId());
2554        return ret;
2555    }
2556
2557    final int startActivitiesInPackage(int uid,
2558            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2559            Bundle options, int userId) {
2560
2561        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2562                false, true, "startActivityInPackage", null);
2563        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2564                options, userId);
2565        return ret;
2566    }
2567
2568    final void addRecentTaskLocked(TaskRecord task) {
2569        int N = mRecentTasks.size();
2570        // Quick case: check if the top-most recent task is the same.
2571        if (N > 0 && mRecentTasks.get(0) == task) {
2572            return;
2573        }
2574        // Remove any existing entries that are the same kind of task.
2575        for (int i=0; i<N; i++) {
2576            TaskRecord tr = mRecentTasks.get(i);
2577            if (task.userId == tr.userId
2578                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2579                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2580                mRecentTasks.remove(i);
2581                i--;
2582                N--;
2583                if (task.intent == null) {
2584                    // If the new recent task we are adding is not fully
2585                    // specified, then replace it with the existing recent task.
2586                    task = tr;
2587                }
2588            }
2589        }
2590        if (N >= MAX_RECENT_TASKS) {
2591            mRecentTasks.remove(N-1);
2592        }
2593        mRecentTasks.add(0, task);
2594    }
2595
2596    public void setRequestedOrientation(IBinder token,
2597            int requestedOrientation) {
2598        synchronized (this) {
2599            ActivityRecord r = mMainStack.isInStackLocked(token);
2600            if (r == null) {
2601                return;
2602            }
2603            final long origId = Binder.clearCallingIdentity();
2604            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2605            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2606                    mConfiguration,
2607                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2608            if (config != null) {
2609                r.frozenBeforeDestroy = true;
2610                if (!updateConfigurationLocked(config, r, false, false)) {
2611                    mMainStack.resumeTopActivityLocked(null);
2612                }
2613            }
2614            Binder.restoreCallingIdentity(origId);
2615        }
2616    }
2617
2618    public int getRequestedOrientation(IBinder token) {
2619        synchronized (this) {
2620            ActivityRecord r = mMainStack.isInStackLocked(token);
2621            if (r == null) {
2622                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2623            }
2624            return mWindowManager.getAppOrientation(r.appToken);
2625        }
2626    }
2627
2628    /**
2629     * This is the internal entry point for handling Activity.finish().
2630     *
2631     * @param token The Binder token referencing the Activity we want to finish.
2632     * @param resultCode Result code, if any, from this Activity.
2633     * @param resultData Result data (Intent), if any, from this Activity.
2634     *
2635     * @return Returns true if the activity successfully finished, or false if it is still running.
2636     */
2637    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2638        // Refuse possible leaked file descriptors
2639        if (resultData != null && resultData.hasFileDescriptors() == true) {
2640            throw new IllegalArgumentException("File descriptors passed in Intent");
2641        }
2642
2643        synchronized(this) {
2644            if (mController != null) {
2645                // Find the first activity that is not finishing.
2646                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2647                if (next != null) {
2648                    // ask watcher if this is allowed
2649                    boolean resumeOK = true;
2650                    try {
2651                        resumeOK = mController.activityResuming(next.packageName);
2652                    } catch (RemoteException e) {
2653                        mController = null;
2654                    }
2655
2656                    if (!resumeOK) {
2657                        return false;
2658                    }
2659                }
2660            }
2661            final long origId = Binder.clearCallingIdentity();
2662            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2663                    resultData, "app-request");
2664            Binder.restoreCallingIdentity(origId);
2665            return res;
2666        }
2667    }
2668
2669    public final void finishHeavyWeightApp() {
2670        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2671                != PackageManager.PERMISSION_GRANTED) {
2672            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2673                    + Binder.getCallingPid()
2674                    + ", uid=" + Binder.getCallingUid()
2675                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2676            Slog.w(TAG, msg);
2677            throw new SecurityException(msg);
2678        }
2679
2680        synchronized(this) {
2681            if (mHeavyWeightProcess == null) {
2682                return;
2683            }
2684
2685            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2686                    mHeavyWeightProcess.activities);
2687            for (int i=0; i<activities.size(); i++) {
2688                ActivityRecord r = activities.get(i);
2689                if (!r.finishing) {
2690                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2691                    if (index >= 0) {
2692                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2693                                null, "finish-heavy");
2694                    }
2695                }
2696            }
2697
2698            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2699                    mHeavyWeightProcess.userId, 0));
2700            mHeavyWeightProcess = null;
2701        }
2702    }
2703
2704    public void crashApplication(int uid, int initialPid, String packageName,
2705            String message) {
2706        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2707                != PackageManager.PERMISSION_GRANTED) {
2708            String msg = "Permission Denial: crashApplication() from pid="
2709                    + Binder.getCallingPid()
2710                    + ", uid=" + Binder.getCallingUid()
2711                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2712            Slog.w(TAG, msg);
2713            throw new SecurityException(msg);
2714        }
2715
2716        synchronized(this) {
2717            ProcessRecord proc = null;
2718
2719            // Figure out which process to kill.  We don't trust that initialPid
2720            // still has any relation to current pids, so must scan through the
2721            // list.
2722            synchronized (mPidsSelfLocked) {
2723                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2724                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2725                    if (p.uid != uid) {
2726                        continue;
2727                    }
2728                    if (p.pid == initialPid) {
2729                        proc = p;
2730                        break;
2731                    }
2732                    for (String str : p.pkgList) {
2733                        if (str.equals(packageName)) {
2734                            proc = p;
2735                        }
2736                    }
2737                }
2738            }
2739
2740            if (proc == null) {
2741                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2742                        + " initialPid=" + initialPid
2743                        + " packageName=" + packageName);
2744                return;
2745            }
2746
2747            if (proc.thread != null) {
2748                if (proc.pid == Process.myPid()) {
2749                    Log.w(TAG, "crashApplication: trying to crash self!");
2750                    return;
2751                }
2752                long ident = Binder.clearCallingIdentity();
2753                try {
2754                    proc.thread.scheduleCrash(message);
2755                } catch (RemoteException e) {
2756                }
2757                Binder.restoreCallingIdentity(ident);
2758            }
2759        }
2760    }
2761
2762    public final void finishSubActivity(IBinder token, String resultWho,
2763            int requestCode) {
2764        synchronized(this) {
2765            final long origId = Binder.clearCallingIdentity();
2766            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2767            Binder.restoreCallingIdentity(origId);
2768        }
2769    }
2770
2771    public boolean finishActivityAffinity(IBinder token) {
2772        synchronized(this) {
2773            final long origId = Binder.clearCallingIdentity();
2774            boolean res = mMainStack.finishActivityAffinityLocked(token);
2775            Binder.restoreCallingIdentity(origId);
2776            return res;
2777        }
2778    }
2779
2780    public boolean willActivityBeVisible(IBinder token) {
2781        synchronized(this) {
2782            int i;
2783            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2784                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2785                if (r.appToken == token) {
2786                    return true;
2787                }
2788                if (r.fullscreen && !r.finishing) {
2789                    return false;
2790                }
2791            }
2792            return true;
2793        }
2794    }
2795
2796    public void overridePendingTransition(IBinder token, String packageName,
2797            int enterAnim, int exitAnim) {
2798        synchronized(this) {
2799            ActivityRecord self = mMainStack.isInStackLocked(token);
2800            if (self == null) {
2801                return;
2802            }
2803
2804            final long origId = Binder.clearCallingIdentity();
2805
2806            if (self.state == ActivityState.RESUMED
2807                    || self.state == ActivityState.PAUSING) {
2808                mWindowManager.overridePendingAppTransition(packageName,
2809                        enterAnim, exitAnim, null);
2810            }
2811
2812            Binder.restoreCallingIdentity(origId);
2813        }
2814    }
2815
2816    /**
2817     * Main function for removing an existing process from the activity manager
2818     * as a result of that process going away.  Clears out all connections
2819     * to the process.
2820     */
2821    private final void handleAppDiedLocked(ProcessRecord app,
2822            boolean restarting, boolean allowRestart) {
2823        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2824        if (!restarting) {
2825            mLruProcesses.remove(app);
2826        }
2827
2828        if (mProfileProc == app) {
2829            clearProfilerLocked();
2830        }
2831
2832        // Just in case...
2833        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2834            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2835            mMainStack.mPausingActivity = null;
2836        }
2837        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2838            mMainStack.mLastPausedActivity = null;
2839        }
2840
2841        // Remove this application's activities from active lists.
2842        mMainStack.removeHistoryRecordsForAppLocked(app);
2843
2844        boolean atTop = true;
2845        boolean hasVisibleActivities = false;
2846
2847        // Clean out the history list.
2848        int i = mMainStack.mHistory.size();
2849        if (localLOGV) Slog.v(
2850            TAG, "Removing app " + app + " from history with " + i + " entries");
2851        while (i > 0) {
2852            i--;
2853            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2854            if (localLOGV) Slog.v(
2855                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2856            if (r.app == app) {
2857                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2858                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2859                        RuntimeException here = new RuntimeException("here");
2860                        here.fillInStackTrace();
2861                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2862                                + ": haveState=" + r.haveState
2863                                + " stateNotNeeded=" + r.stateNotNeeded
2864                                + " finishing=" + r.finishing
2865                                + " state=" + r.state, here);
2866                    }
2867                    if (!r.finishing) {
2868                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2869                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2870                                System.identityHashCode(r),
2871                                r.task.taskId, r.shortComponentName,
2872                                "proc died without state saved");
2873                    }
2874                    mMainStack.removeActivityFromHistoryLocked(r);
2875
2876                } else {
2877                    // We have the current state for this activity, so
2878                    // it can be restarted later when needed.
2879                    if (localLOGV) Slog.v(
2880                        TAG, "Keeping entry, setting app to null");
2881                    if (r.visible) {
2882                        hasVisibleActivities = true;
2883                    }
2884                    r.app = null;
2885                    r.nowVisible = false;
2886                    if (!r.haveState) {
2887                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2888                                "App died, clearing saved state of " + r);
2889                        r.icicle = null;
2890                    }
2891                }
2892
2893                r.stack.cleanUpActivityLocked(r, true, true);
2894            }
2895            atTop = false;
2896        }
2897
2898        app.activities.clear();
2899
2900        if (app.instrumentationClass != null) {
2901            Slog.w(TAG, "Crash of app " + app.processName
2902                  + " running instrumentation " + app.instrumentationClass);
2903            Bundle info = new Bundle();
2904            info.putString("shortMsg", "Process crashed.");
2905            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2906        }
2907
2908        if (!restarting) {
2909            if (!mMainStack.resumeTopActivityLocked(null)) {
2910                // If there was nothing to resume, and we are not already
2911                // restarting this process, but there is a visible activity that
2912                // is hosted by the process...  then make sure all visible
2913                // activities are running, taking care of restarting this
2914                // process.
2915                if (hasVisibleActivities) {
2916                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2917                }
2918            }
2919        }
2920    }
2921
2922    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2923        IBinder threadBinder = thread.asBinder();
2924        // Find the application record.
2925        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2926            ProcessRecord rec = mLruProcesses.get(i);
2927            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2928                return i;
2929            }
2930        }
2931        return -1;
2932    }
2933
2934    final ProcessRecord getRecordForAppLocked(
2935            IApplicationThread thread) {
2936        if (thread == null) {
2937            return null;
2938        }
2939
2940        int appIndex = getLRURecordIndexForAppLocked(thread);
2941        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2942    }
2943
2944    final void appDiedLocked(ProcessRecord app, int pid,
2945            IApplicationThread thread) {
2946
2947        mProcDeaths[0]++;
2948
2949        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2950        synchronized (stats) {
2951            stats.noteProcessDiedLocked(app.info.uid, pid);
2952        }
2953
2954        // Clean up already done if the process has been re-started.
2955        if (app.pid == pid && app.thread != null &&
2956                app.thread.asBinder() == thread.asBinder()) {
2957            if (!app.killedBackground) {
2958                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2959                        + ") has died.");
2960            }
2961            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2962            if (localLOGV) Slog.v(
2963                TAG, "Dying app: " + app + ", pid: " + pid
2964                + ", thread: " + thread.asBinder());
2965            boolean doLowMem = app.instrumentationClass == null;
2966            handleAppDiedLocked(app, false, true);
2967
2968            if (doLowMem) {
2969                // If there are no longer any background processes running,
2970                // and the app that died was not running instrumentation,
2971                // then tell everyone we are now low on memory.
2972                boolean haveBg = false;
2973                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2974                    ProcessRecord rec = mLruProcesses.get(i);
2975                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2976                        haveBg = true;
2977                        break;
2978                    }
2979                }
2980
2981                if (!haveBg) {
2982                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2983                    long now = SystemClock.uptimeMillis();
2984                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2985                        ProcessRecord rec = mLruProcesses.get(i);
2986                        if (rec != app && rec.thread != null &&
2987                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2988                            // The low memory report is overriding any current
2989                            // state for a GC request.  Make sure to do
2990                            // heavy/important/visible/foreground processes first.
2991                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
2992                                rec.lastRequestedGc = 0;
2993                            } else {
2994                                rec.lastRequestedGc = rec.lastLowMemory;
2995                            }
2996                            rec.reportLowMemory = true;
2997                            rec.lastLowMemory = now;
2998                            mProcessesToGc.remove(rec);
2999                            addProcessToGcListLocked(rec);
3000                        }
3001                    }
3002                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3003                    scheduleAppGcsLocked();
3004                }
3005            }
3006        } else if (app.pid != pid) {
3007            // A new process has already been started.
3008            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3009                    + ") has died and restarted (pid " + app.pid + ").");
3010            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3011        } else if (DEBUG_PROCESSES) {
3012            Slog.d(TAG, "Received spurious death notification for thread "
3013                    + thread.asBinder());
3014        }
3015    }
3016
3017    /**
3018     * If a stack trace dump file is configured, dump process stack traces.
3019     * @param clearTraces causes the dump file to be erased prior to the new
3020     *    traces being written, if true; when false, the new traces will be
3021     *    appended to any existing file content.
3022     * @param firstPids of dalvik VM processes to dump stack traces for first
3023     * @param lastPids of dalvik VM processes to dump stack traces for last
3024     * @param nativeProcs optional list of native process names to dump stack crawls
3025     * @return file containing stack traces, or null if no dump file is configured
3026     */
3027    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3028            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3029        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3030        if (tracesPath == null || tracesPath.length() == 0) {
3031            return null;
3032        }
3033
3034        File tracesFile = new File(tracesPath);
3035        try {
3036            File tracesDir = tracesFile.getParentFile();
3037            if (!tracesDir.exists()) {
3038                tracesFile.mkdirs();
3039                if (!SELinux.restorecon(tracesDir)) {
3040                    return null;
3041                }
3042            }
3043            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3044
3045            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3046            tracesFile.createNewFile();
3047            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3048        } catch (IOException e) {
3049            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3050            return null;
3051        }
3052
3053        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3054        return tracesFile;
3055    }
3056
3057    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3058            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3059        // Use a FileObserver to detect when traces finish writing.
3060        // The order of traces is considered important to maintain for legibility.
3061        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3062            public synchronized void onEvent(int event, String path) { notify(); }
3063        };
3064
3065        try {
3066            observer.startWatching();
3067
3068            // First collect all of the stacks of the most important pids.
3069            if (firstPids != null) {
3070                try {
3071                    int num = firstPids.size();
3072                    for (int i = 0; i < num; i++) {
3073                        synchronized (observer) {
3074                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3075                            observer.wait(200);  // Wait for write-close, give up after 200msec
3076                        }
3077                    }
3078                } catch (InterruptedException e) {
3079                    Log.wtf(TAG, e);
3080                }
3081            }
3082
3083            // Next measure CPU usage.
3084            if (processStats != null) {
3085                processStats.init();
3086                System.gc();
3087                processStats.update();
3088                try {
3089                    synchronized (processStats) {
3090                        processStats.wait(500); // measure over 1/2 second.
3091                    }
3092                } catch (InterruptedException e) {
3093                }
3094                processStats.update();
3095
3096                // We'll take the stack crawls of just the top apps using CPU.
3097                final int N = processStats.countWorkingStats();
3098                int numProcs = 0;
3099                for (int i=0; i<N && numProcs<5; i++) {
3100                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3101                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3102                        numProcs++;
3103                        try {
3104                            synchronized (observer) {
3105                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3106                                observer.wait(200);  // Wait for write-close, give up after 200msec
3107                            }
3108                        } catch (InterruptedException e) {
3109                            Log.wtf(TAG, e);
3110                        }
3111
3112                    }
3113                }
3114            }
3115
3116        } finally {
3117            observer.stopWatching();
3118        }
3119
3120        if (nativeProcs != null) {
3121            int[] pids = Process.getPidsForCommands(nativeProcs);
3122            if (pids != null) {
3123                for (int pid : pids) {
3124                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3125                }
3126            }
3127        }
3128    }
3129
3130    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3131        if (true || IS_USER_BUILD) {
3132            return;
3133        }
3134        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3135        if (tracesPath == null || tracesPath.length() == 0) {
3136            return;
3137        }
3138
3139        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3140        StrictMode.allowThreadDiskWrites();
3141        try {
3142            final File tracesFile = new File(tracesPath);
3143            final File tracesDir = tracesFile.getParentFile();
3144            final File tracesTmp = new File(tracesDir, "__tmp__");
3145            try {
3146                if (!tracesDir.exists()) {
3147                    tracesFile.mkdirs();
3148                    if (!SELinux.restorecon(tracesDir.getPath())) {
3149                        return;
3150                    }
3151                }
3152                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3153
3154                if (tracesFile.exists()) {
3155                    tracesTmp.delete();
3156                    tracesFile.renameTo(tracesTmp);
3157                }
3158                StringBuilder sb = new StringBuilder();
3159                Time tobj = new Time();
3160                tobj.set(System.currentTimeMillis());
3161                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3162                sb.append(": ");
3163                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3164                sb.append(" since ");
3165                sb.append(msg);
3166                FileOutputStream fos = new FileOutputStream(tracesFile);
3167                fos.write(sb.toString().getBytes());
3168                if (app == null) {
3169                    fos.write("\n*** No application process!".getBytes());
3170                }
3171                fos.close();
3172                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3173            } catch (IOException e) {
3174                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3175                return;
3176            }
3177
3178            if (app != null) {
3179                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3180                firstPids.add(app.pid);
3181                dumpStackTraces(tracesPath, firstPids, null, null, null);
3182            }
3183
3184            File lastTracesFile = null;
3185            File curTracesFile = null;
3186            for (int i=9; i>=0; i--) {
3187                String name = String.format("slow%02d.txt", i);
3188                curTracesFile = new File(tracesDir, name);
3189                if (curTracesFile.exists()) {
3190                    if (lastTracesFile != null) {
3191                        curTracesFile.renameTo(lastTracesFile);
3192                    } else {
3193                        curTracesFile.delete();
3194                    }
3195                }
3196                lastTracesFile = curTracesFile;
3197            }
3198            tracesFile.renameTo(curTracesFile);
3199            if (tracesTmp.exists()) {
3200                tracesTmp.renameTo(tracesFile);
3201            }
3202        } finally {
3203            StrictMode.setThreadPolicy(oldPolicy);
3204        }
3205    }
3206
3207    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3208            ActivityRecord parent, final String annotation) {
3209        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3210        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3211
3212        if (mController != null) {
3213            try {
3214                // 0 == continue, -1 = kill process immediately
3215                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3216                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3217            } catch (RemoteException e) {
3218                mController = null;
3219            }
3220        }
3221
3222        long anrTime = SystemClock.uptimeMillis();
3223        if (MONITOR_CPU_USAGE) {
3224            updateCpuStatsNow();
3225        }
3226
3227        synchronized (this) {
3228            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3229            if (mShuttingDown) {
3230                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3231                return;
3232            } else if (app.notResponding) {
3233                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3234                return;
3235            } else if (app.crashing) {
3236                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3237                return;
3238            }
3239
3240            // In case we come through here for the same app before completing
3241            // this one, mark as anring now so we will bail out.
3242            app.notResponding = true;
3243
3244            // Log the ANR to the event log.
3245            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3246                    annotation);
3247
3248            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3249            firstPids.add(app.pid);
3250
3251            int parentPid = app.pid;
3252            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3253            if (parentPid != app.pid) firstPids.add(parentPid);
3254
3255            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3256
3257            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3258                ProcessRecord r = mLruProcesses.get(i);
3259                if (r != null && r.thread != null) {
3260                    int pid = r.pid;
3261                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3262                        if (r.persistent) {
3263                            firstPids.add(pid);
3264                        } else {
3265                            lastPids.put(pid, Boolean.TRUE);
3266                        }
3267                    }
3268                }
3269            }
3270        }
3271
3272        // Log the ANR to the main log.
3273        StringBuilder info = new StringBuilder();
3274        info.setLength(0);
3275        info.append("ANR in ").append(app.processName);
3276        if (activity != null && activity.shortComponentName != null) {
3277            info.append(" (").append(activity.shortComponentName).append(")");
3278        }
3279        info.append("\n");
3280        if (annotation != null) {
3281            info.append("Reason: ").append(annotation).append("\n");
3282        }
3283        if (parent != null && parent != activity) {
3284            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3285        }
3286
3287        final ProcessStats processStats = new ProcessStats(true);
3288
3289        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3290
3291        String cpuInfo = null;
3292        if (MONITOR_CPU_USAGE) {
3293            updateCpuStatsNow();
3294            synchronized (mProcessStatsThread) {
3295                cpuInfo = mProcessStats.printCurrentState(anrTime);
3296            }
3297            info.append(processStats.printCurrentLoad());
3298            info.append(cpuInfo);
3299        }
3300
3301        info.append(processStats.printCurrentState(anrTime));
3302
3303        Slog.e(TAG, info.toString());
3304        if (tracesFile == null) {
3305            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3306            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3307        }
3308
3309        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3310                cpuInfo, tracesFile, null);
3311
3312        if (mController != null) {
3313            try {
3314                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3315                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3316                if (res != 0) {
3317                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3318                    return;
3319                }
3320            } catch (RemoteException e) {
3321                mController = null;
3322            }
3323        }
3324
3325        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3326        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3327                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3328
3329        synchronized (this) {
3330            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3331                Slog.w(TAG, "Killing " + app + ": background ANR");
3332                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3333                        app.processName, app.setAdj, "background ANR");
3334                Process.killProcessQuiet(app.pid);
3335                return;
3336            }
3337
3338            // Set the app's notResponding state, and look up the errorReportReceiver
3339            makeAppNotRespondingLocked(app,
3340                    activity != null ? activity.shortComponentName : null,
3341                    annotation != null ? "ANR " + annotation : "ANR",
3342                    info.toString());
3343
3344            // Bring up the infamous App Not Responding dialog
3345            Message msg = Message.obtain();
3346            HashMap map = new HashMap();
3347            msg.what = SHOW_NOT_RESPONDING_MSG;
3348            msg.obj = map;
3349            map.put("app", app);
3350            if (activity != null) {
3351                map.put("activity", activity);
3352            }
3353
3354            mHandler.sendMessage(msg);
3355        }
3356    }
3357
3358    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3359        if (!mLaunchWarningShown) {
3360            mLaunchWarningShown = true;
3361            mHandler.post(new Runnable() {
3362                @Override
3363                public void run() {
3364                    synchronized (ActivityManagerService.this) {
3365                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3366                        d.show();
3367                        mHandler.postDelayed(new Runnable() {
3368                            @Override
3369                            public void run() {
3370                                synchronized (ActivityManagerService.this) {
3371                                    d.dismiss();
3372                                    mLaunchWarningShown = false;
3373                                }
3374                            }
3375                        }, 4000);
3376                    }
3377                }
3378            });
3379        }
3380    }
3381
3382    public boolean clearApplicationUserData(final String packageName,
3383            final IPackageDataObserver observer, final int userId) {
3384        enforceNotIsolatedCaller("clearApplicationUserData");
3385        int uid = Binder.getCallingUid();
3386        int pid = Binder.getCallingPid();
3387        long callingId = Binder.clearCallingIdentity();
3388        try {
3389            IPackageManager pm = AppGlobals.getPackageManager();
3390            int pkgUid = -1;
3391            synchronized(this) {
3392                try {
3393                    pkgUid = pm.getPackageUid(packageName, userId);
3394                } catch (RemoteException e) {
3395                }
3396                if (pkgUid == -1) {
3397                    Slog.w(TAG, "Invalid packageName:" + packageName);
3398                    return false;
3399                }
3400                if (uid == pkgUid || checkComponentPermission(
3401                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3402                        pid, uid, -1, true)
3403                        == PackageManager.PERMISSION_GRANTED) {
3404                    forceStopPackageLocked(packageName, pkgUid);
3405                } else {
3406                    throw new SecurityException(pid+" does not have permission:"+
3407                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3408                                    "for process:"+packageName);
3409                }
3410            }
3411
3412            try {
3413                //clear application user data
3414                pm.clearApplicationUserData(packageName, observer, userId);
3415                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3416                        Uri.fromParts("package", packageName, null));
3417                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3418                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3419                        null, null, 0, null, null, null, false, false, userId);
3420            } catch (RemoteException e) {
3421            }
3422        } finally {
3423            Binder.restoreCallingIdentity(callingId);
3424        }
3425        return true;
3426    }
3427
3428    public void killBackgroundProcesses(final String packageName) {
3429        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3430                != PackageManager.PERMISSION_GRANTED &&
3431                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3432                        != PackageManager.PERMISSION_GRANTED) {
3433            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3434                    + Binder.getCallingPid()
3435                    + ", uid=" + Binder.getCallingUid()
3436                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3437            Slog.w(TAG, msg);
3438            throw new SecurityException(msg);
3439        }
3440
3441        int userId = UserHandle.getCallingUserId();
3442        long callingId = Binder.clearCallingIdentity();
3443        try {
3444            IPackageManager pm = AppGlobals.getPackageManager();
3445            int pkgUid = -1;
3446            synchronized(this) {
3447                try {
3448                    pkgUid = pm.getPackageUid(packageName, userId);
3449                } catch (RemoteException e) {
3450                }
3451                if (pkgUid == -1) {
3452                    Slog.w(TAG, "Invalid packageName: " + packageName);
3453                    return;
3454                }
3455                killPackageProcessesLocked(packageName, pkgUid, -1,
3456                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3457            }
3458        } finally {
3459            Binder.restoreCallingIdentity(callingId);
3460        }
3461    }
3462
3463    public void killAllBackgroundProcesses() {
3464        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3465                != PackageManager.PERMISSION_GRANTED) {
3466            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3467                    + Binder.getCallingPid()
3468                    + ", uid=" + Binder.getCallingUid()
3469                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3470            Slog.w(TAG, msg);
3471            throw new SecurityException(msg);
3472        }
3473
3474        long callingId = Binder.clearCallingIdentity();
3475        try {
3476            synchronized(this) {
3477                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3478                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3479                    final int NA = apps.size();
3480                    for (int ia=0; ia<NA; ia++) {
3481                        ProcessRecord app = apps.valueAt(ia);
3482                        if (app.persistent) {
3483                            // we don't kill persistent processes
3484                            continue;
3485                        }
3486                        if (app.removed) {
3487                            procs.add(app);
3488                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3489                            app.removed = true;
3490                            procs.add(app);
3491                        }
3492                    }
3493                }
3494
3495                int N = procs.size();
3496                for (int i=0; i<N; i++) {
3497                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3498                }
3499            }
3500        } finally {
3501            Binder.restoreCallingIdentity(callingId);
3502        }
3503    }
3504
3505    public void forceStopPackage(final String packageName) {
3506        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3507                != PackageManager.PERMISSION_GRANTED) {
3508            String msg = "Permission Denial: forceStopPackage() from pid="
3509                    + Binder.getCallingPid()
3510                    + ", uid=" + Binder.getCallingUid()
3511                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3512            Slog.w(TAG, msg);
3513            throw new SecurityException(msg);
3514        }
3515        final int userId = UserHandle.getCallingUserId();
3516        long callingId = Binder.clearCallingIdentity();
3517        try {
3518            IPackageManager pm = AppGlobals.getPackageManager();
3519            int pkgUid = -1;
3520            synchronized(this) {
3521                try {
3522                    pkgUid = pm.getPackageUid(packageName, userId);
3523                } catch (RemoteException e) {
3524                }
3525                if (pkgUid == -1) {
3526                    Slog.w(TAG, "Invalid packageName: " + packageName);
3527                    return;
3528                }
3529                forceStopPackageLocked(packageName, pkgUid);
3530                try {
3531                    pm.setPackageStoppedState(packageName, true, userId);
3532                } catch (RemoteException e) {
3533                } catch (IllegalArgumentException e) {
3534                    Slog.w(TAG, "Failed trying to unstop package "
3535                            + packageName + ": " + e);
3536                }
3537            }
3538        } finally {
3539            Binder.restoreCallingIdentity(callingId);
3540        }
3541    }
3542
3543    /*
3544     * The pkg name and uid have to be specified.
3545     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3546     */
3547    public void killApplicationWithUid(String pkg, int uid) {
3548        if (pkg == null) {
3549            return;
3550        }
3551        // Make sure the uid is valid.
3552        if (uid < 0) {
3553            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3554            return;
3555        }
3556        int callerUid = Binder.getCallingUid();
3557        // Only the system server can kill an application
3558        if (callerUid == Process.SYSTEM_UID) {
3559            // Post an aysnc message to kill the application
3560            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3561            msg.arg1 = uid;
3562            msg.arg2 = 0;
3563            msg.obj = pkg;
3564            mHandler.sendMessage(msg);
3565        } else {
3566            throw new SecurityException(callerUid + " cannot kill pkg: " +
3567                    pkg);
3568        }
3569    }
3570
3571    public void closeSystemDialogs(String reason) {
3572        enforceNotIsolatedCaller("closeSystemDialogs");
3573
3574        final int uid = Binder.getCallingUid();
3575        final long origId = Binder.clearCallingIdentity();
3576        synchronized (this) {
3577            closeSystemDialogsLocked(uid, reason);
3578        }
3579        Binder.restoreCallingIdentity(origId);
3580    }
3581
3582    void closeSystemDialogsLocked(int callingUid, String reason) {
3583        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3584        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3585        if (reason != null) {
3586            intent.putExtra("reason", reason);
3587        }
3588        mWindowManager.closeSystemDialogs(reason);
3589
3590        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3591            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3592            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3593                r.stack.finishActivityLocked(r, i,
3594                        Activity.RESULT_CANCELED, null, "close-sys");
3595            }
3596        }
3597
3598        final long origId = Binder.clearCallingIdentity();
3599        try {
3600            broadcastIntentLocked(null, null, intent, null,
3601                    null, 0, null, null, null, false, false, -1,
3602                    callingUid, UserHandle.USER_ALL);
3603        } finally {
3604            Binder.restoreCallingIdentity(origId);
3605        }
3606    }
3607
3608    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3609            throws RemoteException {
3610        enforceNotIsolatedCaller("getProcessMemoryInfo");
3611        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3612        for (int i=pids.length-1; i>=0; i--) {
3613            infos[i] = new Debug.MemoryInfo();
3614            Debug.getMemoryInfo(pids[i], infos[i]);
3615        }
3616        return infos;
3617    }
3618
3619    public long[] getProcessPss(int[] pids) throws RemoteException {
3620        enforceNotIsolatedCaller("getProcessPss");
3621        long[] pss = new long[pids.length];
3622        for (int i=pids.length-1; i>=0; i--) {
3623            pss[i] = Debug.getPss(pids[i]);
3624        }
3625        return pss;
3626    }
3627
3628    public void killApplicationProcess(String processName, int uid) {
3629        if (processName == null) {
3630            return;
3631        }
3632
3633        int callerUid = Binder.getCallingUid();
3634        // Only the system server can kill an application
3635        if (callerUid == Process.SYSTEM_UID) {
3636            synchronized (this) {
3637                ProcessRecord app = getProcessRecordLocked(processName, uid);
3638                if (app != null && app.thread != null) {
3639                    try {
3640                        app.thread.scheduleSuicide();
3641                    } catch (RemoteException e) {
3642                        // If the other end already died, then our work here is done.
3643                    }
3644                } else {
3645                    Slog.w(TAG, "Process/uid not found attempting kill of "
3646                            + processName + " / " + uid);
3647                }
3648            }
3649        } else {
3650            throw new SecurityException(callerUid + " cannot kill app process: " +
3651                    processName);
3652        }
3653    }
3654
3655    private void forceStopPackageLocked(final String packageName, int uid) {
3656        forceStopPackageLocked(packageName, uid, false, false, true, false,
3657                UserHandle.getUserId(uid));
3658        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3659                Uri.fromParts("package", packageName, null));
3660        if (!mProcessesReady) {
3661            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3662        }
3663        intent.putExtra(Intent.EXTRA_UID, uid);
3664        broadcastIntentLocked(null, null, intent,
3665                null, null, 0, null, null, null,
3666                false, false,
3667                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3668    }
3669
3670    private void forceStopUserLocked(int userId) {
3671        forceStopPackageLocked(null, -1, false, false, true, false, userId);
3672        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3673        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3674        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3675        broadcastIntentLocked(null, null, intent,
3676                null, null, 0, null, null, null,
3677                false, false,
3678                MY_PID, Process.SYSTEM_UID, userId);
3679    }
3680
3681    private final boolean killPackageProcessesLocked(String packageName, int uid,
3682            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3683            boolean doit, boolean evenPersistent, String reason) {
3684        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3685
3686        // Remove all processes this package may have touched: all with the
3687        // same UID (except for the system or root user), and all whose name
3688        // matches the package name.
3689        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3690        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3691            final int NA = apps.size();
3692            for (int ia=0; ia<NA; ia++) {
3693                ProcessRecord app = apps.valueAt(ia);
3694                if (app.persistent && !evenPersistent) {
3695                    // we don't kill persistent processes
3696                    continue;
3697                }
3698                if (app.removed) {
3699                    if (doit) {
3700                        procs.add(app);
3701                    }
3702                // If no package is specified, we call all processes under the
3703                // give user id.
3704                } else if (packageName == null) {
3705                    if (app.userId == userId) {
3706                        if (app.setAdj >= minOomAdj) {
3707                            if (!doit) {
3708                                return true;
3709                            }
3710                            app.removed = true;
3711                            procs.add(app);
3712                        }
3713                    }
3714                // If uid is specified and the uid and process name match
3715                // Or, the uid is not specified and the process name matches
3716                } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3717                            || ((app.processName.equals(packageName)
3718                                 || app.processName.startsWith(procNamePrefix))
3719                                && uid < 0))) {
3720                    if (app.setAdj >= minOomAdj) {
3721                        if (!doit) {
3722                            return true;
3723                        }
3724                        app.removed = true;
3725                        procs.add(app);
3726                    }
3727                }
3728            }
3729        }
3730
3731        int N = procs.size();
3732        for (int i=0; i<N; i++) {
3733            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3734        }
3735        return N > 0;
3736    }
3737
3738    private final boolean forceStopPackageLocked(String name, int uid,
3739            boolean callerWillRestart, boolean purgeCache, boolean doit,
3740            boolean evenPersistent, int userId) {
3741        int i;
3742        int N;
3743
3744        if (uid < 0 && name != null) {
3745            try {
3746                uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
3747            } catch (RemoteException e) {
3748            }
3749        }
3750
3751        if (doit) {
3752            if (name != null) {
3753                Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3754            } else {
3755                Slog.i(TAG, "Force stopping user " + userId);
3756            }
3757
3758            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3759            while (badApps.hasNext()) {
3760                SparseArray<Long> ba = badApps.next();
3761                for (i=ba.size()-1; i>=0; i--) {
3762                    boolean remove = false;
3763                    final int entUid = ba.keyAt(i);
3764                    if (name != null) {
3765                        if (entUid == uid) {
3766                            remove = true;
3767                        }
3768                    } else if (UserHandle.getUserId(entUid) == userId) {
3769                        remove = true;
3770                    }
3771                    if (remove) {
3772                        ba.removeAt(i);
3773                    }
3774                }
3775                if (ba.size() == 0) {
3776                    badApps.remove();
3777                }
3778            }
3779        }
3780
3781        boolean didSomething = killPackageProcessesLocked(name, uid,
3782                name == null ? userId : -1 , -100, callerWillRestart, false,
3783                doit, evenPersistent,
3784                name == null ? ("force stop user " + userId) : ("force stop " + name));
3785
3786        TaskRecord lastTask = null;
3787        for (i=0; i<mMainStack.mHistory.size(); i++) {
3788            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3789            final boolean samePackage = r.packageName.equals(name)
3790                    || (name == null && r.userId == userId);
3791            if (r.userId == userId
3792                    && (samePackage || r.task == lastTask)
3793                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3794                if (!doit) {
3795                    if (r.finishing) {
3796                        // If this activity is just finishing, then it is not
3797                        // interesting as far as something to stop.
3798                        continue;
3799                    }
3800                    return true;
3801                }
3802                didSomething = true;
3803                Slog.i(TAG, "  Force finishing activity " + r);
3804                if (samePackage) {
3805                    if (r.app != null) {
3806                        r.app.removed = true;
3807                    }
3808                    r.app = null;
3809                }
3810                lastTask = r.task;
3811                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3812                        null, "force-stop", true)) {
3813                    i--;
3814                }
3815            }
3816        }
3817
3818        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3819            if (!doit) {
3820                return true;
3821            }
3822            didSomething = true;
3823        }
3824
3825        if (name == null) {
3826            // Remove all sticky broadcasts from this user.
3827            mStickyBroadcasts.remove(userId);
3828        }
3829
3830        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3831        for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
3832            if ((name == null || provider.info.packageName.equals(name))
3833                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3834                if (!doit) {
3835                    return true;
3836                }
3837                didSomething = true;
3838                providers.add(provider);
3839            }
3840        }
3841
3842        N = providers.size();
3843        for (i=0; i<N; i++) {
3844            removeDyingProviderLocked(null, providers.get(i), true);
3845        }
3846
3847        if (doit) {
3848            if (purgeCache && name != null) {
3849                AttributeCache ac = AttributeCache.instance();
3850                if (ac != null) {
3851                    ac.removePackage(name);
3852                }
3853            }
3854            if (mBooted) {
3855                mMainStack.resumeTopActivityLocked(null);
3856                mMainStack.scheduleIdleLocked();
3857            }
3858        }
3859
3860        return didSomething;
3861    }
3862
3863    private final boolean removeProcessLocked(ProcessRecord app,
3864            boolean callerWillRestart, boolean allowRestart, String reason) {
3865        final String name = app.processName;
3866        final int uid = app.uid;
3867        if (DEBUG_PROCESSES) Slog.d(
3868            TAG, "Force removing proc " + app.toShortString() + " (" + name
3869            + "/" + uid + ")");
3870
3871        mProcessNames.remove(name, uid);
3872        mIsolatedProcesses.remove(app.uid);
3873        if (mHeavyWeightProcess == app) {
3874            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3875                    mHeavyWeightProcess.userId, 0));
3876            mHeavyWeightProcess = null;
3877        }
3878        boolean needRestart = false;
3879        if (app.pid > 0 && app.pid != MY_PID) {
3880            int pid = app.pid;
3881            synchronized (mPidsSelfLocked) {
3882                mPidsSelfLocked.remove(pid);
3883                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3884            }
3885            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3886            handleAppDiedLocked(app, true, allowRestart);
3887            mLruProcesses.remove(app);
3888            Process.killProcessQuiet(pid);
3889
3890            if (app.persistent && !app.isolated) {
3891                if (!callerWillRestart) {
3892                    addAppLocked(app.info, false);
3893                } else {
3894                    needRestart = true;
3895                }
3896            }
3897        } else {
3898            mRemovedProcesses.add(app);
3899        }
3900
3901        return needRestart;
3902    }
3903
3904    private final void processStartTimedOutLocked(ProcessRecord app) {
3905        final int pid = app.pid;
3906        boolean gone = false;
3907        synchronized (mPidsSelfLocked) {
3908            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3909            if (knownApp != null && knownApp.thread == null) {
3910                mPidsSelfLocked.remove(pid);
3911                gone = true;
3912            }
3913        }
3914
3915        if (gone) {
3916            Slog.w(TAG, "Process " + app + " failed to attach");
3917            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
3918                    app.processName);
3919            mProcessNames.remove(app.processName, app.uid);
3920            mIsolatedProcesses.remove(app.uid);
3921            if (mHeavyWeightProcess == app) {
3922                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3923                        mHeavyWeightProcess.userId, 0));
3924                mHeavyWeightProcess = null;
3925            }
3926            // Take care of any launching providers waiting for this process.
3927            checkAppInLaunchingProvidersLocked(app, true);
3928            // Take care of any services that are waiting for the process.
3929            mServices.processStartTimedOutLocked(app);
3930            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3931                    app.processName, app.setAdj, "start timeout");
3932            Process.killProcessQuiet(pid);
3933            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3934                Slog.w(TAG, "Unattached app died before backup, skipping");
3935                try {
3936                    IBackupManager bm = IBackupManager.Stub.asInterface(
3937                            ServiceManager.getService(Context.BACKUP_SERVICE));
3938                    bm.agentDisconnected(app.info.packageName);
3939                } catch (RemoteException e) {
3940                    // Can't happen; the backup manager is local
3941                }
3942            }
3943            if (isPendingBroadcastProcessLocked(pid)) {
3944                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3945                skipPendingBroadcastLocked(pid);
3946            }
3947        } else {
3948            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3949        }
3950    }
3951
3952    private final boolean attachApplicationLocked(IApplicationThread thread,
3953            int pid) {
3954
3955        // Find the application record that is being attached...  either via
3956        // the pid if we are running in multiple processes, or just pull the
3957        // next app record if we are emulating process with anonymous threads.
3958        ProcessRecord app;
3959        if (pid != MY_PID && pid >= 0) {
3960            synchronized (mPidsSelfLocked) {
3961                app = mPidsSelfLocked.get(pid);
3962            }
3963        } else {
3964            app = null;
3965        }
3966
3967        if (app == null) {
3968            Slog.w(TAG, "No pending application record for pid " + pid
3969                    + " (IApplicationThread " + thread + "); dropping process");
3970            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3971            if (pid > 0 && pid != MY_PID) {
3972                Process.killProcessQuiet(pid);
3973            } else {
3974                try {
3975                    thread.scheduleExit();
3976                } catch (Exception e) {
3977                    // Ignore exceptions.
3978                }
3979            }
3980            return false;
3981        }
3982
3983        // If this application record is still attached to a previous
3984        // process, clean it up now.
3985        if (app.thread != null) {
3986            handleAppDiedLocked(app, true, true);
3987        }
3988
3989        // Tell the process all about itself.
3990
3991        if (localLOGV) Slog.v(
3992                TAG, "Binding process pid " + pid + " to record " + app);
3993
3994        String processName = app.processName;
3995        try {
3996            AppDeathRecipient adr = new AppDeathRecipient(
3997                    app, pid, thread);
3998            thread.asBinder().linkToDeath(adr, 0);
3999            app.deathRecipient = adr;
4000        } catch (RemoteException e) {
4001            app.resetPackageList();
4002            startProcessLocked(app, "link fail", processName);
4003            return false;
4004        }
4005
4006        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
4007
4008        app.thread = thread;
4009        app.curAdj = app.setAdj = -100;
4010        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4011        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4012        app.forcingToForeground = null;
4013        app.foregroundServices = false;
4014        app.hasShownUi = false;
4015        app.debugging = false;
4016
4017        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4018
4019        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4020        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4021
4022        if (!normalMode) {
4023            Slog.i(TAG, "Launching preboot mode app: " + app);
4024        }
4025
4026        if (localLOGV) Slog.v(
4027            TAG, "New app record " + app
4028            + " thread=" + thread.asBinder() + " pid=" + pid);
4029        try {
4030            int testMode = IApplicationThread.DEBUG_OFF;
4031            if (mDebugApp != null && mDebugApp.equals(processName)) {
4032                testMode = mWaitForDebugger
4033                    ? IApplicationThread.DEBUG_WAIT
4034                    : IApplicationThread.DEBUG_ON;
4035                app.debugging = true;
4036                if (mDebugTransient) {
4037                    mDebugApp = mOrigDebugApp;
4038                    mWaitForDebugger = mOrigWaitForDebugger;
4039                }
4040            }
4041            String profileFile = app.instrumentationProfileFile;
4042            ParcelFileDescriptor profileFd = null;
4043            boolean profileAutoStop = false;
4044            if (mProfileApp != null && mProfileApp.equals(processName)) {
4045                mProfileProc = app;
4046                profileFile = mProfileFile;
4047                profileFd = mProfileFd;
4048                profileAutoStop = mAutoStopProfiler;
4049            }
4050            boolean enableOpenGlTrace = false;
4051            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4052                enableOpenGlTrace = true;
4053                mOpenGlTraceApp = null;
4054            }
4055
4056            // If the app is being launched for restore or full backup, set it up specially
4057            boolean isRestrictedBackupMode = false;
4058            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4059                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4060                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4061                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4062            }
4063
4064            ensurePackageDexOpt(app.instrumentationInfo != null
4065                    ? app.instrumentationInfo.packageName
4066                    : app.info.packageName);
4067            if (app.instrumentationClass != null) {
4068                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4069            }
4070            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4071                    + processName + " with config " + mConfiguration);
4072            ApplicationInfo appInfo = app.instrumentationInfo != null
4073                    ? app.instrumentationInfo : app.info;
4074            app.compat = compatibilityInfoForPackageLocked(appInfo);
4075            if (profileFd != null) {
4076                profileFd = profileFd.dup();
4077            }
4078            thread.bindApplication(processName, appInfo, providers,
4079                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4080                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4081                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4082                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4083                    mCoreSettingsObserver.getCoreSettingsLocked());
4084            updateLruProcessLocked(app, false, true);
4085            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4086        } catch (Exception e) {
4087            // todo: Yikes!  What should we do?  For now we will try to
4088            // start another process, but that could easily get us in
4089            // an infinite loop of restarting processes...
4090            Slog.w(TAG, "Exception thrown during bind!", e);
4091
4092            app.resetPackageList();
4093            app.unlinkDeathRecipient();
4094            startProcessLocked(app, "bind fail", processName);
4095            return false;
4096        }
4097
4098        // Remove this record from the list of starting applications.
4099        mPersistentStartingProcesses.remove(app);
4100        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4101                "Attach application locked removing on hold: " + app);
4102        mProcessesOnHold.remove(app);
4103
4104        boolean badApp = false;
4105        boolean didSomething = false;
4106
4107        // See if the top visible activity is waiting to run in this process...
4108        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4109        if (hr != null && normalMode) {
4110            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4111                    && processName.equals(hr.processName)) {
4112                try {
4113                    if (mHeadless) {
4114                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4115                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4116                        didSomething = true;
4117                    }
4118                } catch (Exception e) {
4119                    Slog.w(TAG, "Exception in new application when starting activity "
4120                          + hr.intent.getComponent().flattenToShortString(), e);
4121                    badApp = true;
4122                }
4123            } else {
4124                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4125            }
4126        }
4127
4128        // Find any services that should be running in this process...
4129        if (!badApp) {
4130            try {
4131                didSomething |= mServices.attachApplicationLocked(app, processName);
4132            } catch (Exception e) {
4133                badApp = true;
4134            }
4135        }
4136
4137        // Check if a next-broadcast receiver is in this process...
4138        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4139            try {
4140                didSomething = sendPendingBroadcastsLocked(app);
4141            } catch (Exception e) {
4142                // If the app died trying to launch the receiver we declare it 'bad'
4143                badApp = true;
4144            }
4145        }
4146
4147        // Check whether the next backup agent is in this process...
4148        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4149            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4150            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4151            try {
4152                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4153                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4154                        mBackupTarget.backupMode);
4155            } catch (Exception e) {
4156                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4157                e.printStackTrace();
4158            }
4159        }
4160
4161        if (badApp) {
4162            // todo: Also need to kill application to deal with all
4163            // kinds of exceptions.
4164            handleAppDiedLocked(app, false, true);
4165            return false;
4166        }
4167
4168        if (!didSomething) {
4169            updateOomAdjLocked();
4170        }
4171
4172        return true;
4173    }
4174
4175    public final void attachApplication(IApplicationThread thread) {
4176        synchronized (this) {
4177            int callingPid = Binder.getCallingPid();
4178            final long origId = Binder.clearCallingIdentity();
4179            attachApplicationLocked(thread, callingPid);
4180            Binder.restoreCallingIdentity(origId);
4181        }
4182    }
4183
4184    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4185        final long origId = Binder.clearCallingIdentity();
4186        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4187        if (stopProfiling) {
4188            synchronized (this) {
4189                if (mProfileProc == r.app) {
4190                    if (mProfileFd != null) {
4191                        try {
4192                            mProfileFd.close();
4193                        } catch (IOException e) {
4194                        }
4195                        clearProfilerLocked();
4196                    }
4197                }
4198            }
4199        }
4200        Binder.restoreCallingIdentity(origId);
4201    }
4202
4203    void enableScreenAfterBoot() {
4204        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4205                SystemClock.uptimeMillis());
4206        mWindowManager.enableScreenAfterBoot();
4207
4208        synchronized (this) {
4209            updateEventDispatchingLocked();
4210        }
4211    }
4212
4213    public void showBootMessage(final CharSequence msg, final boolean always) {
4214        enforceNotIsolatedCaller("showBootMessage");
4215        mWindowManager.showBootMessage(msg, always);
4216    }
4217
4218    public void dismissKeyguardOnNextActivity() {
4219        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4220        final long token = Binder.clearCallingIdentity();
4221        try {
4222            synchronized (this) {
4223                if (mLockScreenShown) {
4224                    mLockScreenShown = false;
4225                    comeOutOfSleepIfNeededLocked();
4226                }
4227                mMainStack.dismissKeyguardOnNextActivityLocked();
4228            }
4229        } finally {
4230            Binder.restoreCallingIdentity(token);
4231        }
4232    }
4233
4234    final void finishBooting() {
4235        IntentFilter pkgFilter = new IntentFilter();
4236        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4237        pkgFilter.addDataScheme("package");
4238        mContext.registerReceiver(new BroadcastReceiver() {
4239            @Override
4240            public void onReceive(Context context, Intent intent) {
4241                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4242                if (pkgs != null) {
4243                    for (String pkg : pkgs) {
4244                        synchronized (ActivityManagerService.this) {
4245                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4246                                setResultCode(Activity.RESULT_OK);
4247                                return;
4248                            }
4249                        }
4250                    }
4251                }
4252            }
4253        }, pkgFilter);
4254
4255        synchronized (this) {
4256            // Ensure that any processes we had put on hold are now started
4257            // up.
4258            final int NP = mProcessesOnHold.size();
4259            if (NP > 0) {
4260                ArrayList<ProcessRecord> procs =
4261                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4262                for (int ip=0; ip<NP; ip++) {
4263                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4264                            + procs.get(ip));
4265                    startProcessLocked(procs.get(ip), "on-hold", null);
4266                }
4267            }
4268
4269            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4270                // Start looking for apps that are abusing wake locks.
4271                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4272                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4273                // Tell anyone interested that we are done booting!
4274                SystemProperties.set("sys.boot_completed", "1");
4275                SystemProperties.set("dev.bootcomplete", "1");
4276                for (int i=0; i<mStartedUsers.size(); i++) {
4277                    UserStartedState uss = mStartedUsers.valueAt(i);
4278                    if (uss.mState == UserStartedState.STATE_BOOTING) {
4279                        uss.mState = UserStartedState.STATE_RUNNING;
4280                        final int userId = mStartedUsers.keyAt(i);
4281                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4282                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4283                        broadcastIntentLocked(null, null, intent,
4284                                null, null, 0, null, null,
4285                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4286                                false, false, MY_PID, Process.SYSTEM_UID, userId);
4287                    }
4288                }
4289            }
4290        }
4291    }
4292
4293    final void ensureBootCompleted() {
4294        boolean booting;
4295        boolean enableScreen;
4296        synchronized (this) {
4297            booting = mBooting;
4298            mBooting = false;
4299            enableScreen = !mBooted;
4300            mBooted = true;
4301        }
4302
4303        if (booting) {
4304            finishBooting();
4305        }
4306
4307        if (enableScreen) {
4308            enableScreenAfterBoot();
4309        }
4310    }
4311
4312    public final void activityPaused(IBinder token) {
4313        final long origId = Binder.clearCallingIdentity();
4314        mMainStack.activityPaused(token, false);
4315        Binder.restoreCallingIdentity(origId);
4316    }
4317
4318    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4319            CharSequence description) {
4320        if (localLOGV) Slog.v(
4321            TAG, "Activity stopped: token=" + token);
4322
4323        // Refuse possible leaked file descriptors
4324        if (icicle != null && icicle.hasFileDescriptors()) {
4325            throw new IllegalArgumentException("File descriptors passed in Bundle");
4326        }
4327
4328        ActivityRecord r = null;
4329
4330        final long origId = Binder.clearCallingIdentity();
4331
4332        synchronized (this) {
4333            r = mMainStack.isInStackLocked(token);
4334            if (r != null) {
4335                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4336            }
4337        }
4338
4339        if (r != null) {
4340            sendPendingThumbnail(r, null, null, null, false);
4341        }
4342
4343        trimApplications();
4344
4345        Binder.restoreCallingIdentity(origId);
4346    }
4347
4348    public final void activityDestroyed(IBinder token) {
4349        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4350        mMainStack.activityDestroyed(token);
4351    }
4352
4353    public String getCallingPackage(IBinder token) {
4354        synchronized (this) {
4355            ActivityRecord r = getCallingRecordLocked(token);
4356            return r != null && r.app != null ? r.info.packageName : null;
4357        }
4358    }
4359
4360    public ComponentName getCallingActivity(IBinder token) {
4361        synchronized (this) {
4362            ActivityRecord r = getCallingRecordLocked(token);
4363            return r != null ? r.intent.getComponent() : null;
4364        }
4365    }
4366
4367    private ActivityRecord getCallingRecordLocked(IBinder token) {
4368        ActivityRecord r = mMainStack.isInStackLocked(token);
4369        if (r == null) {
4370            return null;
4371        }
4372        return r.resultTo;
4373    }
4374
4375    public ComponentName getActivityClassForToken(IBinder token) {
4376        synchronized(this) {
4377            ActivityRecord r = mMainStack.isInStackLocked(token);
4378            if (r == null) {
4379                return null;
4380            }
4381            return r.intent.getComponent();
4382        }
4383    }
4384
4385    public String getPackageForToken(IBinder token) {
4386        synchronized(this) {
4387            ActivityRecord r = mMainStack.isInStackLocked(token);
4388            if (r == null) {
4389                return null;
4390            }
4391            return r.packageName;
4392        }
4393    }
4394
4395    public IIntentSender getIntentSender(int type,
4396            String packageName, IBinder token, String resultWho,
4397            int requestCode, Intent[] intents, String[] resolvedTypes,
4398            int flags, Bundle options, int userId) {
4399        enforceNotIsolatedCaller("getIntentSender");
4400        // Refuse possible leaked file descriptors
4401        if (intents != null) {
4402            if (intents.length < 1) {
4403                throw new IllegalArgumentException("Intents array length must be >= 1");
4404            }
4405            for (int i=0; i<intents.length; i++) {
4406                Intent intent = intents[i];
4407                if (intent != null) {
4408                    if (intent.hasFileDescriptors()) {
4409                        throw new IllegalArgumentException("File descriptors passed in Intent");
4410                    }
4411                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4412                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4413                        throw new IllegalArgumentException(
4414                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4415                    }
4416                    intents[i] = new Intent(intent);
4417                }
4418            }
4419            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4420                throw new IllegalArgumentException(
4421                        "Intent array length does not match resolvedTypes length");
4422            }
4423        }
4424        if (options != null) {
4425            if (options.hasFileDescriptors()) {
4426                throw new IllegalArgumentException("File descriptors passed in options");
4427            }
4428        }
4429
4430        synchronized(this) {
4431            int callingUid = Binder.getCallingUid();
4432            userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId,
4433                    false, true, "getIntentSender", null);
4434            try {
4435                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4436                    int uid = AppGlobals.getPackageManager()
4437                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4438                    if (!UserHandle.isSameApp(callingUid, uid)) {
4439                        String msg = "Permission Denial: getIntentSender() from pid="
4440                            + Binder.getCallingPid()
4441                            + ", uid=" + Binder.getCallingUid()
4442                            + ", (need uid=" + uid + ")"
4443                            + " is not allowed to send as package " + packageName;
4444                        Slog.w(TAG, msg);
4445                        throw new SecurityException(msg);
4446                    }
4447                }
4448
4449                return getIntentSenderLocked(type, packageName, callingUid, userId,
4450                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4451
4452            } catch (RemoteException e) {
4453                throw new SecurityException(e);
4454            }
4455        }
4456    }
4457
4458    IIntentSender getIntentSenderLocked(int type, String packageName,
4459            int callingUid, int userId, IBinder token, String resultWho,
4460            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4461            Bundle options) {
4462        if (DEBUG_MU)
4463            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4464        ActivityRecord activity = null;
4465        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4466            activity = mMainStack.isInStackLocked(token);
4467            if (activity == null) {
4468                return null;
4469            }
4470            if (activity.finishing) {
4471                return null;
4472            }
4473        }
4474
4475        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4476        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4477        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4478        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4479                |PendingIntent.FLAG_UPDATE_CURRENT);
4480
4481        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4482                type, packageName, activity, resultWho,
4483                requestCode, intents, resolvedTypes, flags, options, userId);
4484        WeakReference<PendingIntentRecord> ref;
4485        ref = mIntentSenderRecords.get(key);
4486        PendingIntentRecord rec = ref != null ? ref.get() : null;
4487        if (rec != null) {
4488            if (!cancelCurrent) {
4489                if (updateCurrent) {
4490                    if (rec.key.requestIntent != null) {
4491                        rec.key.requestIntent.replaceExtras(intents != null ?
4492                                intents[intents.length - 1] : null);
4493                    }
4494                    if (intents != null) {
4495                        intents[intents.length-1] = rec.key.requestIntent;
4496                        rec.key.allIntents = intents;
4497                        rec.key.allResolvedTypes = resolvedTypes;
4498                    } else {
4499                        rec.key.allIntents = null;
4500                        rec.key.allResolvedTypes = null;
4501                    }
4502                }
4503                return rec;
4504            }
4505            rec.canceled = true;
4506            mIntentSenderRecords.remove(key);
4507        }
4508        if (noCreate) {
4509            return rec;
4510        }
4511        rec = new PendingIntentRecord(this, key, callingUid);
4512        mIntentSenderRecords.put(key, rec.ref);
4513        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4514            if (activity.pendingResults == null) {
4515                activity.pendingResults
4516                        = new HashSet<WeakReference<PendingIntentRecord>>();
4517            }
4518            activity.pendingResults.add(rec.ref);
4519        }
4520        return rec;
4521    }
4522
4523    public void cancelIntentSender(IIntentSender sender) {
4524        if (!(sender instanceof PendingIntentRecord)) {
4525            return;
4526        }
4527        synchronized(this) {
4528            PendingIntentRecord rec = (PendingIntentRecord)sender;
4529            try {
4530                int uid = AppGlobals.getPackageManager()
4531                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4532                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4533                    String msg = "Permission Denial: cancelIntentSender() from pid="
4534                        + Binder.getCallingPid()
4535                        + ", uid=" + Binder.getCallingUid()
4536                        + " is not allowed to cancel packges "
4537                        + rec.key.packageName;
4538                    Slog.w(TAG, msg);
4539                    throw new SecurityException(msg);
4540                }
4541            } catch (RemoteException e) {
4542                throw new SecurityException(e);
4543            }
4544            cancelIntentSenderLocked(rec, true);
4545        }
4546    }
4547
4548    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4549        rec.canceled = true;
4550        mIntentSenderRecords.remove(rec.key);
4551        if (cleanActivity && rec.key.activity != null) {
4552            rec.key.activity.pendingResults.remove(rec.ref);
4553        }
4554    }
4555
4556    public String getPackageForIntentSender(IIntentSender pendingResult) {
4557        if (!(pendingResult instanceof PendingIntentRecord)) {
4558            return null;
4559        }
4560        try {
4561            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4562            return res.key.packageName;
4563        } catch (ClassCastException e) {
4564        }
4565        return null;
4566    }
4567
4568    public int getUidForIntentSender(IIntentSender sender) {
4569        if (sender instanceof PendingIntentRecord) {
4570            try {
4571                PendingIntentRecord res = (PendingIntentRecord)sender;
4572                return res.uid;
4573            } catch (ClassCastException e) {
4574            }
4575        }
4576        return -1;
4577    }
4578
4579    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4580        if (!(pendingResult instanceof PendingIntentRecord)) {
4581            return false;
4582        }
4583        try {
4584            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4585            if (res.key.allIntents == null) {
4586                return false;
4587            }
4588            for (int i=0; i<res.key.allIntents.length; i++) {
4589                Intent intent = res.key.allIntents[i];
4590                if (intent.getPackage() != null && intent.getComponent() != null) {
4591                    return false;
4592                }
4593            }
4594            return true;
4595        } catch (ClassCastException e) {
4596        }
4597        return false;
4598    }
4599
4600    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4601        if (!(pendingResult instanceof PendingIntentRecord)) {
4602            return false;
4603        }
4604        try {
4605            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4606            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4607                return true;
4608            }
4609            return false;
4610        } catch (ClassCastException e) {
4611        }
4612        return false;
4613    }
4614
4615    public void setProcessLimit(int max) {
4616        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4617                "setProcessLimit()");
4618        synchronized (this) {
4619            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4620            mProcessLimitOverride = max;
4621        }
4622        trimApplications();
4623    }
4624
4625    public int getProcessLimit() {
4626        synchronized (this) {
4627            return mProcessLimitOverride;
4628        }
4629    }
4630
4631    void foregroundTokenDied(ForegroundToken token) {
4632        synchronized (ActivityManagerService.this) {
4633            synchronized (mPidsSelfLocked) {
4634                ForegroundToken cur
4635                    = mForegroundProcesses.get(token.pid);
4636                if (cur != token) {
4637                    return;
4638                }
4639                mForegroundProcesses.remove(token.pid);
4640                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4641                if (pr == null) {
4642                    return;
4643                }
4644                pr.forcingToForeground = null;
4645                pr.foregroundServices = false;
4646            }
4647            updateOomAdjLocked();
4648        }
4649    }
4650
4651    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4652        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4653                "setProcessForeground()");
4654        synchronized(this) {
4655            boolean changed = false;
4656
4657            synchronized (mPidsSelfLocked) {
4658                ProcessRecord pr = mPidsSelfLocked.get(pid);
4659                if (pr == null && isForeground) {
4660                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4661                    return;
4662                }
4663                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4664                if (oldToken != null) {
4665                    oldToken.token.unlinkToDeath(oldToken, 0);
4666                    mForegroundProcesses.remove(pid);
4667                    if (pr != null) {
4668                        pr.forcingToForeground = null;
4669                    }
4670                    changed = true;
4671                }
4672                if (isForeground && token != null) {
4673                    ForegroundToken newToken = new ForegroundToken() {
4674                        public void binderDied() {
4675                            foregroundTokenDied(this);
4676                        }
4677                    };
4678                    newToken.pid = pid;
4679                    newToken.token = token;
4680                    try {
4681                        token.linkToDeath(newToken, 0);
4682                        mForegroundProcesses.put(pid, newToken);
4683                        pr.forcingToForeground = token;
4684                        changed = true;
4685                    } catch (RemoteException e) {
4686                        // If the process died while doing this, we will later
4687                        // do the cleanup with the process death link.
4688                    }
4689                }
4690            }
4691
4692            if (changed) {
4693                updateOomAdjLocked();
4694            }
4695        }
4696    }
4697
4698    // =========================================================
4699    // PERMISSIONS
4700    // =========================================================
4701
4702    static class PermissionController extends IPermissionController.Stub {
4703        ActivityManagerService mActivityManagerService;
4704        PermissionController(ActivityManagerService activityManagerService) {
4705            mActivityManagerService = activityManagerService;
4706        }
4707
4708        public boolean checkPermission(String permission, int pid, int uid) {
4709            return mActivityManagerService.checkPermission(permission, pid,
4710                    uid) == PackageManager.PERMISSION_GRANTED;
4711        }
4712    }
4713
4714    /**
4715     * This can be called with or without the global lock held.
4716     */
4717    int checkComponentPermission(String permission, int pid, int uid,
4718            int owningUid, boolean exported) {
4719        // We might be performing an operation on behalf of an indirect binder
4720        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4721        // client identity accordingly before proceeding.
4722        Identity tlsIdentity = sCallerIdentity.get();
4723        if (tlsIdentity != null) {
4724            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4725                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4726            uid = tlsIdentity.uid;
4727            pid = tlsIdentity.pid;
4728        }
4729
4730        if (pid == MY_PID) {
4731            return PackageManager.PERMISSION_GRANTED;
4732        }
4733
4734        return ActivityManager.checkComponentPermission(permission, uid,
4735                owningUid, exported);
4736    }
4737
4738    /**
4739     * As the only public entry point for permissions checking, this method
4740     * can enforce the semantic that requesting a check on a null global
4741     * permission is automatically denied.  (Internally a null permission
4742     * string is used when calling {@link #checkComponentPermission} in cases
4743     * when only uid-based security is needed.)
4744     *
4745     * This can be called with or without the global lock held.
4746     */
4747    public int checkPermission(String permission, int pid, int uid) {
4748        if (permission == null) {
4749            return PackageManager.PERMISSION_DENIED;
4750        }
4751        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4752    }
4753
4754    /**
4755     * Binder IPC calls go through the public entry point.
4756     * This can be called with or without the global lock held.
4757     */
4758    int checkCallingPermission(String permission) {
4759        return checkPermission(permission,
4760                Binder.getCallingPid(),
4761                UserHandle.getAppId(Binder.getCallingUid()));
4762    }
4763
4764    /**
4765     * This can be called with or without the global lock held.
4766     */
4767    void enforceCallingPermission(String permission, String func) {
4768        if (checkCallingPermission(permission)
4769                == PackageManager.PERMISSION_GRANTED) {
4770            return;
4771        }
4772
4773        String msg = "Permission Denial: " + func + " from pid="
4774                + Binder.getCallingPid()
4775                + ", uid=" + Binder.getCallingUid()
4776                + " requires " + permission;
4777        Slog.w(TAG, msg);
4778        throw new SecurityException(msg);
4779    }
4780
4781    /**
4782     * Determine if UID is holding permissions required to access {@link Uri} in
4783     * the given {@link ProviderInfo}. Final permission checking is always done
4784     * in {@link ContentProvider}.
4785     */
4786    private final boolean checkHoldingPermissionsLocked(
4787            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4788        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4789                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4790
4791        if (pi.applicationInfo.uid == uid) {
4792            return true;
4793        } else if (!pi.exported) {
4794            return false;
4795        }
4796
4797        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4798        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4799        try {
4800            // check if target holds top-level <provider> permissions
4801            if (!readMet && pi.readPermission != null
4802                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4803                readMet = true;
4804            }
4805            if (!writeMet && pi.writePermission != null
4806                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4807                writeMet = true;
4808            }
4809
4810            // track if unprotected read/write is allowed; any denied
4811            // <path-permission> below removes this ability
4812            boolean allowDefaultRead = pi.readPermission == null;
4813            boolean allowDefaultWrite = pi.writePermission == null;
4814
4815            // check if target holds any <path-permission> that match uri
4816            final PathPermission[] pps = pi.pathPermissions;
4817            if (pps != null) {
4818                final String path = uri.getPath();
4819                int i = pps.length;
4820                while (i > 0 && (!readMet || !writeMet)) {
4821                    i--;
4822                    PathPermission pp = pps[i];
4823                    if (pp.match(path)) {
4824                        if (!readMet) {
4825                            final String pprperm = pp.getReadPermission();
4826                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4827                                    + pprperm + " for " + pp.getPath()
4828                                    + ": match=" + pp.match(path)
4829                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4830                            if (pprperm != null) {
4831                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4832                                    readMet = true;
4833                                } else {
4834                                    allowDefaultRead = false;
4835                                }
4836                            }
4837                        }
4838                        if (!writeMet) {
4839                            final String ppwperm = pp.getWritePermission();
4840                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4841                                    + ppwperm + " for " + pp.getPath()
4842                                    + ": match=" + pp.match(path)
4843                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4844                            if (ppwperm != null) {
4845                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4846                                    writeMet = true;
4847                                } else {
4848                                    allowDefaultWrite = false;
4849                                }
4850                            }
4851                        }
4852                    }
4853                }
4854            }
4855
4856            // grant unprotected <provider> read/write, if not blocked by
4857            // <path-permission> above
4858            if (allowDefaultRead) readMet = true;
4859            if (allowDefaultWrite) writeMet = true;
4860
4861        } catch (RemoteException e) {
4862            return false;
4863        }
4864
4865        return readMet && writeMet;
4866    }
4867
4868    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4869            int modeFlags) {
4870        // Root gets to do everything.
4871        if (uid == 0) {
4872            return true;
4873        }
4874        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4875        if (perms == null) return false;
4876        UriPermission perm = perms.get(uri);
4877        if (perm == null) return false;
4878        return (modeFlags&perm.modeFlags) == modeFlags;
4879    }
4880
4881    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4882        enforceNotIsolatedCaller("checkUriPermission");
4883
4884        // Another redirected-binder-call permissions check as in
4885        // {@link checkComponentPermission}.
4886        Identity tlsIdentity = sCallerIdentity.get();
4887        if (tlsIdentity != null) {
4888            uid = tlsIdentity.uid;
4889            pid = tlsIdentity.pid;
4890        }
4891
4892        uid = UserHandle.getAppId(uid);
4893        // Our own process gets to do everything.
4894        if (pid == MY_PID) {
4895            return PackageManager.PERMISSION_GRANTED;
4896        }
4897        synchronized(this) {
4898            return checkUriPermissionLocked(uri, uid, modeFlags)
4899                    ? PackageManager.PERMISSION_GRANTED
4900                    : PackageManager.PERMISSION_DENIED;
4901        }
4902    }
4903
4904    /**
4905     * Check if the targetPkg can be granted permission to access uri by
4906     * the callingUid using the given modeFlags.  Throws a security exception
4907     * if callingUid is not allowed to do this.  Returns the uid of the target
4908     * if the URI permission grant should be performed; returns -1 if it is not
4909     * needed (for example targetPkg already has permission to access the URI).
4910     * If you already know the uid of the target, you can supply it in
4911     * lastTargetUid else set that to -1.
4912     */
4913    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4914            Uri uri, int modeFlags, int lastTargetUid) {
4915        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4916                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4917        if (modeFlags == 0) {
4918            return -1;
4919        }
4920
4921        if (targetPkg != null) {
4922            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4923                    "Checking grant " + targetPkg + " permission to " + uri);
4924        }
4925
4926        final IPackageManager pm = AppGlobals.getPackageManager();
4927
4928        // If this is not a content: uri, we can't do anything with it.
4929        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4930            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4931                    "Can't grant URI permission for non-content URI: " + uri);
4932            return -1;
4933        }
4934
4935        String name = uri.getAuthority();
4936        ProviderInfo pi = null;
4937        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4938                UserHandle.getUserId(callingUid));
4939        if (cpr != null) {
4940            pi = cpr.info;
4941        } else {
4942            try {
4943                pi = pm.resolveContentProvider(name,
4944                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid));
4945            } catch (RemoteException ex) {
4946            }
4947        }
4948        if (pi == null) {
4949            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4950            return -1;
4951        }
4952
4953        int targetUid = lastTargetUid;
4954        if (targetUid < 0 && targetPkg != null) {
4955            try {
4956                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
4957                if (targetUid < 0) {
4958                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4959                            "Can't grant URI permission no uid for: " + targetPkg);
4960                    return -1;
4961                }
4962            } catch (RemoteException ex) {
4963                return -1;
4964            }
4965        }
4966
4967        if (targetUid >= 0) {
4968            // First...  does the target actually need this permission?
4969            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4970                // No need to grant the target this permission.
4971                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4972                        "Target " + targetPkg + " already has full permission to " + uri);
4973                return -1;
4974            }
4975        } else {
4976            // First...  there is no target package, so can anyone access it?
4977            boolean allowed = pi.exported;
4978            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4979                if (pi.readPermission != null) {
4980                    allowed = false;
4981                }
4982            }
4983            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4984                if (pi.writePermission != null) {
4985                    allowed = false;
4986                }
4987            }
4988            if (allowed) {
4989                return -1;
4990            }
4991        }
4992
4993        // Second...  is the provider allowing granting of URI permissions?
4994        if (!pi.grantUriPermissions) {
4995            throw new SecurityException("Provider " + pi.packageName
4996                    + "/" + pi.name
4997                    + " does not allow granting of Uri permissions (uri "
4998                    + uri + ")");
4999        }
5000        if (pi.uriPermissionPatterns != null) {
5001            final int N = pi.uriPermissionPatterns.length;
5002            boolean allowed = false;
5003            for (int i=0; i<N; i++) {
5004                if (pi.uriPermissionPatterns[i] != null
5005                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5006                    allowed = true;
5007                    break;
5008                }
5009            }
5010            if (!allowed) {
5011                throw new SecurityException("Provider " + pi.packageName
5012                        + "/" + pi.name
5013                        + " does not allow granting of permission to path of Uri "
5014                        + uri);
5015            }
5016        }
5017
5018        // Third...  does the caller itself have permission to access
5019        // this uri?
5020        if (callingUid != Process.myUid()) {
5021            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5022                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5023                    throw new SecurityException("Uid " + callingUid
5024                            + " does not have permission to uri " + uri);
5025                }
5026            }
5027        }
5028
5029        return targetUid;
5030    }
5031
5032    public int checkGrantUriPermission(int callingUid, String targetPkg,
5033            Uri uri, int modeFlags) {
5034        enforceNotIsolatedCaller("checkGrantUriPermission");
5035        synchronized(this) {
5036            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5037        }
5038    }
5039
5040    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5041            Uri uri, int modeFlags, UriPermissionOwner owner) {
5042        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5043                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5044        if (modeFlags == 0) {
5045            return;
5046        }
5047
5048        // So here we are: the caller has the assumed permission
5049        // to the uri, and the target doesn't.  Let's now give this to
5050        // the target.
5051
5052        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5053                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5054
5055        HashMap<Uri, UriPermission> targetUris
5056                = mGrantedUriPermissions.get(targetUid);
5057        if (targetUris == null) {
5058            targetUris = new HashMap<Uri, UriPermission>();
5059            mGrantedUriPermissions.put(targetUid, targetUris);
5060        }
5061
5062        UriPermission perm = targetUris.get(uri);
5063        if (perm == null) {
5064            perm = new UriPermission(targetUid, uri);
5065            targetUris.put(uri, perm);
5066        }
5067
5068        perm.modeFlags |= modeFlags;
5069        if (owner == null) {
5070            perm.globalModeFlags |= modeFlags;
5071        } else {
5072            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5073                 perm.readOwners.add(owner);
5074                 owner.addReadPermission(perm);
5075            }
5076            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5077                 perm.writeOwners.add(owner);
5078                 owner.addWritePermission(perm);
5079            }
5080        }
5081    }
5082
5083    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5084            int modeFlags, UriPermissionOwner owner) {
5085        if (targetPkg == null) {
5086            throw new NullPointerException("targetPkg");
5087        }
5088
5089        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5090        if (targetUid < 0) {
5091            return;
5092        }
5093
5094        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5095    }
5096
5097    static class NeededUriGrants extends ArrayList<Uri> {
5098        final String targetPkg;
5099        final int targetUid;
5100        final int flags;
5101
5102        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5103            targetPkg = _targetPkg;
5104            targetUid = _targetUid;
5105            flags = _flags;
5106        }
5107    }
5108
5109    /**
5110     * Like checkGrantUriPermissionLocked, but takes an Intent.
5111     */
5112    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5113            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5114        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5115                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5116                + " clip=" + (intent != null ? intent.getClipData() : null)
5117                + " from " + intent + "; flags=0x"
5118                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5119
5120        if (targetPkg == null) {
5121            throw new NullPointerException("targetPkg");
5122        }
5123
5124        if (intent == null) {
5125            return null;
5126        }
5127        Uri data = intent.getData();
5128        ClipData clip = intent.getClipData();
5129        if (data == null && clip == null) {
5130            return null;
5131        }
5132        if (data != null) {
5133            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5134                mode, needed != null ? needed.targetUid : -1);
5135            if (target > 0) {
5136                if (needed == null) {
5137                    needed = new NeededUriGrants(targetPkg, target, mode);
5138                }
5139                needed.add(data);
5140            }
5141        }
5142        if (clip != null) {
5143            for (int i=0; i<clip.getItemCount(); i++) {
5144                Uri uri = clip.getItemAt(i).getUri();
5145                if (uri != null) {
5146                    int target = -1;
5147                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5148                            mode, needed != null ? needed.targetUid : -1);
5149                    if (target > 0) {
5150                        if (needed == null) {
5151                            needed = new NeededUriGrants(targetPkg, target, mode);
5152                        }
5153                        needed.add(uri);
5154                    }
5155                } else {
5156                    Intent clipIntent = clip.getItemAt(i).getIntent();
5157                    if (clipIntent != null) {
5158                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5159                                callingUid, targetPkg, clipIntent, mode, needed);
5160                        if (newNeeded != null) {
5161                            needed = newNeeded;
5162                        }
5163                    }
5164                }
5165            }
5166        }
5167
5168        return needed;
5169    }
5170
5171    /**
5172     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5173     */
5174    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5175            UriPermissionOwner owner) {
5176        if (needed != null) {
5177            for (int i=0; i<needed.size(); i++) {
5178                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5179                        needed.get(i), needed.flags, owner);
5180            }
5181        }
5182    }
5183
5184    void grantUriPermissionFromIntentLocked(int callingUid,
5185            String targetPkg, Intent intent, UriPermissionOwner owner) {
5186        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5187                intent, intent != null ? intent.getFlags() : 0, null);
5188        if (needed == null) {
5189            return;
5190        }
5191
5192        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5193    }
5194
5195    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5196            Uri uri, int modeFlags) {
5197        enforceNotIsolatedCaller("grantUriPermission");
5198        synchronized(this) {
5199            final ProcessRecord r = getRecordForAppLocked(caller);
5200            if (r == null) {
5201                throw new SecurityException("Unable to find app for caller "
5202                        + caller
5203                        + " when granting permission to uri " + uri);
5204            }
5205            if (targetPkg == null) {
5206                throw new IllegalArgumentException("null target");
5207            }
5208            if (uri == null) {
5209                throw new IllegalArgumentException("null uri");
5210            }
5211
5212            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5213                    null);
5214        }
5215    }
5216
5217    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5218        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5219                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5220            HashMap<Uri, UriPermission> perms
5221                    = mGrantedUriPermissions.get(perm.uid);
5222            if (perms != null) {
5223                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5224                        "Removing " + perm.uid + " permission to " + perm.uri);
5225                perms.remove(perm.uri);
5226                if (perms.size() == 0) {
5227                    mGrantedUriPermissions.remove(perm.uid);
5228                }
5229            }
5230        }
5231    }
5232
5233    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5234            int modeFlags) {
5235        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5236                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5237        if (modeFlags == 0) {
5238            return;
5239        }
5240
5241        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5242                "Revoking all granted permissions to " + uri);
5243
5244        final IPackageManager pm = AppGlobals.getPackageManager();
5245
5246        final String authority = uri.getAuthority();
5247        ProviderInfo pi = null;
5248        int userId = UserHandle.getUserId(callingUid);
5249        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5250        if (cpr != null) {
5251            pi = cpr.info;
5252        } else {
5253            try {
5254                pi = pm.resolveContentProvider(authority,
5255                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5256            } catch (RemoteException ex) {
5257            }
5258        }
5259        if (pi == null) {
5260            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5261            return;
5262        }
5263
5264        // Does the caller have this permission on the URI?
5265        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5266            // Right now, if you are not the original owner of the permission,
5267            // you are not allowed to revoke it.
5268            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5269                throw new SecurityException("Uid " + callingUid
5270                        + " does not have permission to uri " + uri);
5271            //}
5272        }
5273
5274        // Go through all of the permissions and remove any that match.
5275        final List<String> SEGMENTS = uri.getPathSegments();
5276        if (SEGMENTS != null) {
5277            final int NS = SEGMENTS.size();
5278            int N = mGrantedUriPermissions.size();
5279            for (int i=0; i<N; i++) {
5280                HashMap<Uri, UriPermission> perms
5281                        = mGrantedUriPermissions.valueAt(i);
5282                Iterator<UriPermission> it = perms.values().iterator();
5283            toploop:
5284                while (it.hasNext()) {
5285                    UriPermission perm = it.next();
5286                    Uri targetUri = perm.uri;
5287                    if (!authority.equals(targetUri.getAuthority())) {
5288                        continue;
5289                    }
5290                    List<String> targetSegments = targetUri.getPathSegments();
5291                    if (targetSegments == null) {
5292                        continue;
5293                    }
5294                    if (targetSegments.size() < NS) {
5295                        continue;
5296                    }
5297                    for (int j=0; j<NS; j++) {
5298                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5299                            continue toploop;
5300                        }
5301                    }
5302                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5303                            "Revoking " + perm.uid + " permission to " + perm.uri);
5304                    perm.clearModes(modeFlags);
5305                    if (perm.modeFlags == 0) {
5306                        it.remove();
5307                    }
5308                }
5309                if (perms.size() == 0) {
5310                    mGrantedUriPermissions.remove(
5311                            mGrantedUriPermissions.keyAt(i));
5312                    N--;
5313                    i--;
5314                }
5315            }
5316        }
5317    }
5318
5319    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5320            int modeFlags) {
5321        enforceNotIsolatedCaller("revokeUriPermission");
5322        synchronized(this) {
5323            final ProcessRecord r = getRecordForAppLocked(caller);
5324            if (r == null) {
5325                throw new SecurityException("Unable to find app for caller "
5326                        + caller
5327                        + " when revoking permission to uri " + uri);
5328            }
5329            if (uri == null) {
5330                Slog.w(TAG, "revokeUriPermission: null uri");
5331                return;
5332            }
5333
5334            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5335                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5336            if (modeFlags == 0) {
5337                return;
5338            }
5339
5340            final IPackageManager pm = AppGlobals.getPackageManager();
5341
5342            final String authority = uri.getAuthority();
5343            ProviderInfo pi = null;
5344            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5345            if (cpr != null) {
5346                pi = cpr.info;
5347            } else {
5348                try {
5349                    pi = pm.resolveContentProvider(authority,
5350                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5351                } catch (RemoteException ex) {
5352                }
5353            }
5354            if (pi == null) {
5355                Slog.w(TAG, "No content provider found for permission revoke: "
5356                        + uri.toSafeString());
5357                return;
5358            }
5359
5360            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5361        }
5362    }
5363
5364    @Override
5365    public IBinder newUriPermissionOwner(String name) {
5366        enforceNotIsolatedCaller("newUriPermissionOwner");
5367        synchronized(this) {
5368            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5369            return owner.getExternalTokenLocked();
5370        }
5371    }
5372
5373    @Override
5374    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5375            Uri uri, int modeFlags) {
5376        synchronized(this) {
5377            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5378            if (owner == null) {
5379                throw new IllegalArgumentException("Unknown owner: " + token);
5380            }
5381            if (fromUid != Binder.getCallingUid()) {
5382                if (Binder.getCallingUid() != Process.myUid()) {
5383                    // Only system code can grant URI permissions on behalf
5384                    // of other users.
5385                    throw new SecurityException("nice try");
5386                }
5387            }
5388            if (targetPkg == null) {
5389                throw new IllegalArgumentException("null target");
5390            }
5391            if (uri == null) {
5392                throw new IllegalArgumentException("null uri");
5393            }
5394
5395            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5396        }
5397    }
5398
5399    @Override
5400    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5401        synchronized(this) {
5402            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5403            if (owner == null) {
5404                throw new IllegalArgumentException("Unknown owner: " + token);
5405            }
5406
5407            if (uri == null) {
5408                owner.removeUriPermissionsLocked(mode);
5409            } else {
5410                owner.removeUriPermissionLocked(uri, mode);
5411            }
5412        }
5413    }
5414
5415    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5416        synchronized (this) {
5417            ProcessRecord app =
5418                who != null ? getRecordForAppLocked(who) : null;
5419            if (app == null) return;
5420
5421            Message msg = Message.obtain();
5422            msg.what = WAIT_FOR_DEBUGGER_MSG;
5423            msg.obj = app;
5424            msg.arg1 = waiting ? 1 : 0;
5425            mHandler.sendMessage(msg);
5426        }
5427    }
5428
5429    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5430        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5431        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5432        outInfo.availMem = Process.getFreeMemory();
5433        outInfo.totalMem = Process.getTotalMemory();
5434        outInfo.threshold = homeAppMem;
5435        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5436        outInfo.hiddenAppThreshold = hiddenAppMem;
5437        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5438                ProcessList.SERVICE_ADJ);
5439        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5440                ProcessList.VISIBLE_APP_ADJ);
5441        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5442                ProcessList.FOREGROUND_APP_ADJ);
5443    }
5444
5445    // =========================================================
5446    // TASK MANAGEMENT
5447    // =========================================================
5448
5449    public List getTasks(int maxNum, int flags,
5450                         IThumbnailReceiver receiver) {
5451        ArrayList list = new ArrayList();
5452
5453        PendingThumbnailsRecord pending = null;
5454        IApplicationThread topThumbnail = null;
5455        ActivityRecord topRecord = null;
5456
5457        synchronized(this) {
5458            if (localLOGV) Slog.v(
5459                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5460                + ", receiver=" + receiver);
5461
5462            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5463                    != PackageManager.PERMISSION_GRANTED) {
5464                if (receiver != null) {
5465                    // If the caller wants to wait for pending thumbnails,
5466                    // it ain't gonna get them.
5467                    try {
5468                        receiver.finished();
5469                    } catch (RemoteException ex) {
5470                    }
5471                }
5472                String msg = "Permission Denial: getTasks() from pid="
5473                        + Binder.getCallingPid()
5474                        + ", uid=" + Binder.getCallingUid()
5475                        + " requires " + android.Manifest.permission.GET_TASKS;
5476                Slog.w(TAG, msg);
5477                throw new SecurityException(msg);
5478            }
5479
5480            int pos = mMainStack.mHistory.size()-1;
5481            ActivityRecord next =
5482                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5483            ActivityRecord top = null;
5484            TaskRecord curTask = null;
5485            int numActivities = 0;
5486            int numRunning = 0;
5487            while (pos >= 0 && maxNum > 0) {
5488                final ActivityRecord r = next;
5489                pos--;
5490                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5491
5492                // Initialize state for next task if needed.
5493                if (top == null ||
5494                        (top.state == ActivityState.INITIALIZING
5495                            && top.task == r.task)) {
5496                    top = r;
5497                    curTask = r.task;
5498                    numActivities = numRunning = 0;
5499                }
5500
5501                // Add 'r' into the current task.
5502                numActivities++;
5503                if (r.app != null && r.app.thread != null) {
5504                    numRunning++;
5505                }
5506
5507                if (localLOGV) Slog.v(
5508                    TAG, r.intent.getComponent().flattenToShortString()
5509                    + ": task=" + r.task);
5510
5511                // If the next one is a different task, generate a new
5512                // TaskInfo entry for what we have.
5513                if (next == null || next.task != curTask) {
5514                    ActivityManager.RunningTaskInfo ci
5515                            = new ActivityManager.RunningTaskInfo();
5516                    ci.id = curTask.taskId;
5517                    ci.baseActivity = r.intent.getComponent();
5518                    ci.topActivity = top.intent.getComponent();
5519                    if (top.thumbHolder != null) {
5520                        ci.description = top.thumbHolder.lastDescription;
5521                    }
5522                    ci.numActivities = numActivities;
5523                    ci.numRunning = numRunning;
5524                    //System.out.println(
5525                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5526                    if (ci.thumbnail == null && receiver != null) {
5527                        if (localLOGV) Slog.v(
5528                            TAG, "State=" + top.state + "Idle=" + top.idle
5529                            + " app=" + top.app
5530                            + " thr=" + (top.app != null ? top.app.thread : null));
5531                        if (top.state == ActivityState.RESUMED
5532                                || top.state == ActivityState.PAUSING) {
5533                            if (top.idle && top.app != null
5534                                && top.app.thread != null) {
5535                                topRecord = top;
5536                                topThumbnail = top.app.thread;
5537                            } else {
5538                                top.thumbnailNeeded = true;
5539                            }
5540                        }
5541                        if (pending == null) {
5542                            pending = new PendingThumbnailsRecord(receiver);
5543                        }
5544                        pending.pendingRecords.add(top);
5545                    }
5546                    list.add(ci);
5547                    maxNum--;
5548                    top = null;
5549                }
5550            }
5551
5552            if (pending != null) {
5553                mPendingThumbnails.add(pending);
5554            }
5555        }
5556
5557        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5558
5559        if (topThumbnail != null) {
5560            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5561            try {
5562                topThumbnail.requestThumbnail(topRecord.appToken);
5563            } catch (Exception e) {
5564                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5565                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5566            }
5567        }
5568
5569        if (pending == null && receiver != null) {
5570            // In this case all thumbnails were available and the client
5571            // is being asked to be told when the remaining ones come in...
5572            // which is unusually, since the top-most currently running
5573            // activity should never have a canned thumbnail!  Oh well.
5574            try {
5575                receiver.finished();
5576            } catch (RemoteException ex) {
5577            }
5578        }
5579
5580        return list;
5581    }
5582
5583    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5584            int flags, int userId) {
5585        final int callingUid = Binder.getCallingUid();
5586        if (userId != UserHandle.getCallingUserId()) {
5587            // Check if the caller is holding permissions for cross-user requests.
5588            if (checkComponentPermission(
5589                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5590                    Binder.getCallingPid(), callingUid, -1, true)
5591                    != PackageManager.PERMISSION_GRANTED) {
5592                String msg = "Permission Denial: "
5593                        + "Request to get recent tasks for user " + userId
5594                        + " but is calling from user " + UserHandle.getUserId(callingUid)
5595                        + "; this requires "
5596                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5597                Slog.w(TAG, msg);
5598                throw new SecurityException(msg);
5599            } else {
5600                if (userId == UserHandle.USER_CURRENT) {
5601                    userId = mCurrentUserId;
5602                }
5603            }
5604        }
5605
5606        synchronized (this) {
5607            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5608                    "getRecentTasks()");
5609            final boolean detailed = checkCallingPermission(
5610                    android.Manifest.permission.GET_DETAILED_TASKS)
5611                    == PackageManager.PERMISSION_GRANTED;
5612
5613            IPackageManager pm = AppGlobals.getPackageManager();
5614
5615            final int N = mRecentTasks.size();
5616            ArrayList<ActivityManager.RecentTaskInfo> res
5617                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5618                            maxNum < N ? maxNum : N);
5619            for (int i=0; i<N && maxNum > 0; i++) {
5620                TaskRecord tr = mRecentTasks.get(i);
5621                // Only add calling user's recent tasks
5622                if (tr.userId != userId) continue;
5623                // Return the entry if desired by the caller.  We always return
5624                // the first entry, because callers always expect this to be the
5625                // foreground app.  We may filter others if the caller has
5626                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5627                // we should exclude the entry.
5628
5629                if (i == 0
5630                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5631                        || (tr.intent == null)
5632                        || ((tr.intent.getFlags()
5633                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5634                    ActivityManager.RecentTaskInfo rti
5635                            = new ActivityManager.RecentTaskInfo();
5636                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5637                    rti.persistentId = tr.taskId;
5638                    rti.baseIntent = new Intent(
5639                            tr.intent != null ? tr.intent : tr.affinityIntent);
5640                    if (!detailed) {
5641                        rti.baseIntent.replaceExtras((Bundle)null);
5642                    }
5643                    rti.origActivity = tr.origActivity;
5644                    rti.description = tr.lastDescription;
5645
5646                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5647                        // Check whether this activity is currently available.
5648                        try {
5649                            if (rti.origActivity != null) {
5650                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5651                                        == null) {
5652                                    continue;
5653                                }
5654                            } else if (rti.baseIntent != null) {
5655                                if (pm.queryIntentActivities(rti.baseIntent,
5656                                        null, 0, userId) == null) {
5657                                    continue;
5658                                }
5659                            }
5660                        } catch (RemoteException e) {
5661                            // Will never happen.
5662                        }
5663                    }
5664
5665                    res.add(rti);
5666                    maxNum--;
5667                }
5668            }
5669            return res;
5670        }
5671    }
5672
5673    private TaskRecord taskForIdLocked(int id) {
5674        final int N = mRecentTasks.size();
5675        for (int i=0; i<N; i++) {
5676            TaskRecord tr = mRecentTasks.get(i);
5677            if (tr.taskId == id) {
5678                return tr;
5679            }
5680        }
5681        return null;
5682    }
5683
5684    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5685        synchronized (this) {
5686            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5687                    "getTaskThumbnails()");
5688            TaskRecord tr = taskForIdLocked(id);
5689            if (tr != null) {
5690                return mMainStack.getTaskThumbnailsLocked(tr);
5691            }
5692        }
5693        return null;
5694    }
5695
5696    public boolean removeSubTask(int taskId, int subTaskIndex) {
5697        synchronized (this) {
5698            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5699                    "removeSubTask()");
5700            long ident = Binder.clearCallingIdentity();
5701            try {
5702                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5703                        true) != null;
5704            } finally {
5705                Binder.restoreCallingIdentity(ident);
5706            }
5707        }
5708    }
5709
5710    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5711        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5712        Intent baseIntent = new Intent(
5713                tr.intent != null ? tr.intent : tr.affinityIntent);
5714        ComponentName component = baseIntent.getComponent();
5715        if (component == null) {
5716            Slog.w(TAG, "Now component for base intent of task: " + tr);
5717            return;
5718        }
5719
5720        // Find any running services associated with this app.
5721        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5722
5723        if (killProcesses) {
5724            // Find any running processes associated with this app.
5725            final String pkg = component.getPackageName();
5726            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5727            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5728            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5729                for (int i=0; i<uids.size(); i++) {
5730                    ProcessRecord proc = uids.valueAt(i);
5731                    if (proc.userId != tr.userId) {
5732                        continue;
5733                    }
5734                    if (!proc.pkgList.contains(pkg)) {
5735                        continue;
5736                    }
5737                    procs.add(proc);
5738                }
5739            }
5740
5741            // Kill the running processes.
5742            for (int i=0; i<procs.size(); i++) {
5743                ProcessRecord pr = procs.get(i);
5744                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5745                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5746                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5747                            pr.processName, pr.setAdj, "remove task");
5748                    pr.killedBackground = true;
5749                    Process.killProcessQuiet(pr.pid);
5750                } else {
5751                    pr.waitingToKill = "remove task";
5752                }
5753            }
5754        }
5755    }
5756
5757    public boolean removeTask(int taskId, int flags) {
5758        synchronized (this) {
5759            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5760                    "removeTask()");
5761            long ident = Binder.clearCallingIdentity();
5762            try {
5763                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5764                        false);
5765                if (r != null) {
5766                    mRecentTasks.remove(r.task);
5767                    cleanUpRemovedTaskLocked(r.task, flags);
5768                    return true;
5769                } else {
5770                    TaskRecord tr = null;
5771                    int i=0;
5772                    while (i < mRecentTasks.size()) {
5773                        TaskRecord t = mRecentTasks.get(i);
5774                        if (t.taskId == taskId) {
5775                            tr = t;
5776                            break;
5777                        }
5778                        i++;
5779                    }
5780                    if (tr != null) {
5781                        if (tr.numActivities <= 0) {
5782                            // Caller is just removing a recent task that is
5783                            // not actively running.  That is easy!
5784                            mRecentTasks.remove(i);
5785                            cleanUpRemovedTaskLocked(tr, flags);
5786                            return true;
5787                        } else {
5788                            Slog.w(TAG, "removeTask: task " + taskId
5789                                    + " does not have activities to remove, "
5790                                    + " but numActivities=" + tr.numActivities
5791                                    + ": " + tr);
5792                        }
5793                    }
5794                }
5795            } finally {
5796                Binder.restoreCallingIdentity(ident);
5797            }
5798        }
5799        return false;
5800    }
5801
5802    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5803        int j;
5804        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5805        TaskRecord jt = startTask;
5806
5807        // First look backwards
5808        for (j=startIndex-1; j>=0; j--) {
5809            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5810            if (r.task != jt) {
5811                jt = r.task;
5812                if (affinity.equals(jt.affinity)) {
5813                    return j;
5814                }
5815            }
5816        }
5817
5818        // Now look forwards
5819        final int N = mMainStack.mHistory.size();
5820        jt = startTask;
5821        for (j=startIndex+1; j<N; j++) {
5822            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5823            if (r.task != jt) {
5824                if (affinity.equals(jt.affinity)) {
5825                    return j;
5826                }
5827                jt = r.task;
5828            }
5829        }
5830
5831        // Might it be at the top?
5832        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5833            return N-1;
5834        }
5835
5836        return -1;
5837    }
5838
5839    /**
5840     * TODO: Add mController hook
5841     */
5842    public void moveTaskToFront(int task, int flags, Bundle options) {
5843        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5844                "moveTaskToFront()");
5845
5846        synchronized(this) {
5847            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5848                    Binder.getCallingUid(), "Task to front")) {
5849                ActivityOptions.abort(options);
5850                return;
5851            }
5852            final long origId = Binder.clearCallingIdentity();
5853            try {
5854                TaskRecord tr = taskForIdLocked(task);
5855                if (tr != null) {
5856                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5857                        mMainStack.mUserLeaving = true;
5858                    }
5859                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5860                        // Caller wants the home activity moved with it.  To accomplish this,
5861                        // we'll just move the home task to the top first.
5862                        mMainStack.moveHomeToFrontLocked();
5863                    }
5864                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5865                    return;
5866                }
5867                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5868                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5869                    if (hr.task.taskId == task) {
5870                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5871                            mMainStack.mUserLeaving = true;
5872                        }
5873                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5874                            // Caller wants the home activity moved with it.  To accomplish this,
5875                            // we'll just move the home task to the top first.
5876                            mMainStack.moveHomeToFrontLocked();
5877                        }
5878                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5879                        return;
5880                    }
5881                }
5882            } finally {
5883                Binder.restoreCallingIdentity(origId);
5884            }
5885            ActivityOptions.abort(options);
5886        }
5887    }
5888
5889    public void moveTaskToBack(int task) {
5890        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5891                "moveTaskToBack()");
5892
5893        synchronized(this) {
5894            if (mMainStack.mResumedActivity != null
5895                    && mMainStack.mResumedActivity.task.taskId == task) {
5896                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5897                        Binder.getCallingUid(), "Task to back")) {
5898                    return;
5899                }
5900            }
5901            final long origId = Binder.clearCallingIdentity();
5902            mMainStack.moveTaskToBackLocked(task, null);
5903            Binder.restoreCallingIdentity(origId);
5904        }
5905    }
5906
5907    /**
5908     * Moves an activity, and all of the other activities within the same task, to the bottom
5909     * of the history stack.  The activity's order within the task is unchanged.
5910     *
5911     * @param token A reference to the activity we wish to move
5912     * @param nonRoot If false then this only works if the activity is the root
5913     *                of a task; if true it will work for any activity in a task.
5914     * @return Returns true if the move completed, false if not.
5915     */
5916    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5917        enforceNotIsolatedCaller("moveActivityTaskToBack");
5918        synchronized(this) {
5919            final long origId = Binder.clearCallingIdentity();
5920            int taskId = getTaskForActivityLocked(token, !nonRoot);
5921            if (taskId >= 0) {
5922                return mMainStack.moveTaskToBackLocked(taskId, null);
5923            }
5924            Binder.restoreCallingIdentity(origId);
5925        }
5926        return false;
5927    }
5928
5929    public void moveTaskBackwards(int task) {
5930        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5931                "moveTaskBackwards()");
5932
5933        synchronized(this) {
5934            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5935                    Binder.getCallingUid(), "Task backwards")) {
5936                return;
5937            }
5938            final long origId = Binder.clearCallingIdentity();
5939            moveTaskBackwardsLocked(task);
5940            Binder.restoreCallingIdentity(origId);
5941        }
5942    }
5943
5944    private final void moveTaskBackwardsLocked(int task) {
5945        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5946    }
5947
5948    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5949        synchronized(this) {
5950            return getTaskForActivityLocked(token, onlyRoot);
5951        }
5952    }
5953
5954    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5955        final int N = mMainStack.mHistory.size();
5956        TaskRecord lastTask = null;
5957        for (int i=0; i<N; i++) {
5958            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5959            if (r.appToken == token) {
5960                if (!onlyRoot || lastTask != r.task) {
5961                    return r.task.taskId;
5962                }
5963                return -1;
5964            }
5965            lastTask = r.task;
5966        }
5967
5968        return -1;
5969    }
5970
5971    // =========================================================
5972    // THUMBNAILS
5973    // =========================================================
5974
5975    public void reportThumbnail(IBinder token,
5976            Bitmap thumbnail, CharSequence description) {
5977        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5978        final long origId = Binder.clearCallingIdentity();
5979        sendPendingThumbnail(null, token, thumbnail, description, true);
5980        Binder.restoreCallingIdentity(origId);
5981    }
5982
5983    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5984            Bitmap thumbnail, CharSequence description, boolean always) {
5985        TaskRecord task = null;
5986        ArrayList receivers = null;
5987
5988        //System.out.println("Send pending thumbnail: " + r);
5989
5990        synchronized(this) {
5991            if (r == null) {
5992                r = mMainStack.isInStackLocked(token);
5993                if (r == null) {
5994                    return;
5995                }
5996            }
5997            if (thumbnail == null && r.thumbHolder != null) {
5998                thumbnail = r.thumbHolder.lastThumbnail;
5999                description = r.thumbHolder.lastDescription;
6000            }
6001            if (thumbnail == null && !always) {
6002                // If there is no thumbnail, and this entry is not actually
6003                // going away, then abort for now and pick up the next
6004                // thumbnail we get.
6005                return;
6006            }
6007            task = r.task;
6008
6009            int N = mPendingThumbnails.size();
6010            int i=0;
6011            while (i<N) {
6012                PendingThumbnailsRecord pr =
6013                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6014                //System.out.println("Looking in " + pr.pendingRecords);
6015                if (pr.pendingRecords.remove(r)) {
6016                    if (receivers == null) {
6017                        receivers = new ArrayList();
6018                    }
6019                    receivers.add(pr);
6020                    if (pr.pendingRecords.size() == 0) {
6021                        pr.finished = true;
6022                        mPendingThumbnails.remove(i);
6023                        N--;
6024                        continue;
6025                    }
6026                }
6027                i++;
6028            }
6029        }
6030
6031        if (receivers != null) {
6032            final int N = receivers.size();
6033            for (int i=0; i<N; i++) {
6034                try {
6035                    PendingThumbnailsRecord pr =
6036                        (PendingThumbnailsRecord)receivers.get(i);
6037                    pr.receiver.newThumbnail(
6038                        task != null ? task.taskId : -1, thumbnail, description);
6039                    if (pr.finished) {
6040                        pr.receiver.finished();
6041                    }
6042                } catch (Exception e) {
6043                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6044                }
6045            }
6046        }
6047    }
6048
6049    // =========================================================
6050    // CONTENT PROVIDERS
6051    // =========================================================
6052
6053    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6054        List<ProviderInfo> providers = null;
6055        try {
6056            providers = AppGlobals.getPackageManager().
6057                queryContentProviders(app.processName, app.uid,
6058                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6059        } catch (RemoteException ex) {
6060        }
6061        if (DEBUG_MU)
6062            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6063        int userId = app.userId;
6064        if (providers != null) {
6065            int N = providers.size();
6066            for (int i=0; i<N; i++) {
6067                ProviderInfo cpi =
6068                    (ProviderInfo)providers.get(i);
6069                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6070                        cpi.name, cpi.flags);
6071                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6072                    // This is a singleton provider, but a user besides the
6073                    // default user is asking to initialize a process it runs
6074                    // in...  well, no, it doesn't actually run in this process,
6075                    // it runs in the process of the default user.  Get rid of it.
6076                    providers.remove(i);
6077                    N--;
6078                    continue;
6079                }
6080
6081                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6082                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6083                if (cpr == null) {
6084                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6085                    mProviderMap.putProviderByClass(comp, cpr);
6086                }
6087                if (DEBUG_MU)
6088                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6089                app.pubProviders.put(cpi.name, cpr);
6090                app.addPackage(cpi.applicationInfo.packageName);
6091                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6092            }
6093        }
6094        return providers;
6095    }
6096
6097    /**
6098     * Check if {@link ProcessRecord} has a possible chance at accessing the
6099     * given {@link ProviderInfo}. Final permission checking is always done
6100     * in {@link ContentProvider}.
6101     */
6102    private final String checkContentProviderPermissionLocked(
6103            ProviderInfo cpi, ProcessRecord r) {
6104        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6105        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6106        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6107                cpi.applicationInfo.uid, cpi.exported)
6108                == PackageManager.PERMISSION_GRANTED) {
6109            return null;
6110        }
6111        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6112                cpi.applicationInfo.uid, cpi.exported)
6113                == PackageManager.PERMISSION_GRANTED) {
6114            return null;
6115        }
6116
6117        PathPermission[] pps = cpi.pathPermissions;
6118        if (pps != null) {
6119            int i = pps.length;
6120            while (i > 0) {
6121                i--;
6122                PathPermission pp = pps[i];
6123                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6124                        cpi.applicationInfo.uid, cpi.exported)
6125                        == PackageManager.PERMISSION_GRANTED) {
6126                    return null;
6127                }
6128                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6129                        cpi.applicationInfo.uid, cpi.exported)
6130                        == PackageManager.PERMISSION_GRANTED) {
6131                    return null;
6132                }
6133            }
6134        }
6135
6136        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6137        if (perms != null) {
6138            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6139                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6140                    return null;
6141                }
6142            }
6143        }
6144
6145        String msg;
6146        if (!cpi.exported) {
6147            msg = "Permission Denial: opening provider " + cpi.name
6148                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6149                    + ", uid=" + callingUid + ") that is not exported from uid "
6150                    + cpi.applicationInfo.uid;
6151        } else {
6152            msg = "Permission Denial: opening provider " + cpi.name
6153                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6154                    + ", uid=" + callingUid + ") requires "
6155                    + cpi.readPermission + " or " + cpi.writePermission;
6156        }
6157        Slog.w(TAG, msg);
6158        return msg;
6159    }
6160
6161    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6162            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6163        if (r != null) {
6164            for (int i=0; i<r.conProviders.size(); i++) {
6165                ContentProviderConnection conn = r.conProviders.get(i);
6166                if (conn.provider == cpr) {
6167                    if (DEBUG_PROVIDER) Slog.v(TAG,
6168                            "Adding provider requested by "
6169                            + r.processName + " from process "
6170                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6171                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6172                    if (stable) {
6173                        conn.stableCount++;
6174                        conn.numStableIncs++;
6175                    } else {
6176                        conn.unstableCount++;
6177                        conn.numUnstableIncs++;
6178                    }
6179                    return conn;
6180                }
6181            }
6182            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6183            if (stable) {
6184                conn.stableCount = 1;
6185                conn.numStableIncs = 1;
6186            } else {
6187                conn.unstableCount = 1;
6188                conn.numUnstableIncs = 1;
6189            }
6190            cpr.connections.add(conn);
6191            r.conProviders.add(conn);
6192            return conn;
6193        }
6194        cpr.addExternalProcessHandleLocked(externalProcessToken);
6195        return null;
6196    }
6197
6198    boolean decProviderCountLocked(ContentProviderConnection conn,
6199            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6200        if (conn != null) {
6201            cpr = conn.provider;
6202            if (DEBUG_PROVIDER) Slog.v(TAG,
6203                    "Removing provider requested by "
6204                    + conn.client.processName + " from process "
6205                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6206                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6207            if (stable) {
6208                conn.stableCount--;
6209            } else {
6210                conn.unstableCount--;
6211            }
6212            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6213                cpr.connections.remove(conn);
6214                conn.client.conProviders.remove(conn);
6215                return true;
6216            }
6217            return false;
6218        }
6219        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6220        return false;
6221    }
6222
6223    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6224            String name, IBinder token, boolean stable, int userId) {
6225        ContentProviderRecord cpr;
6226        ContentProviderConnection conn = null;
6227        ProviderInfo cpi = null;
6228
6229        synchronized(this) {
6230            ProcessRecord r = null;
6231            if (caller != null) {
6232                r = getRecordForAppLocked(caller);
6233                if (r == null) {
6234                    throw new SecurityException(
6235                            "Unable to find app for caller " + caller
6236                          + " (pid=" + Binder.getCallingPid()
6237                          + ") when getting content provider " + name);
6238                }
6239                if (r.userId != userId) {
6240                    throw new SecurityException("Calling requested user " + userId
6241                            + " but app is user " + r.userId);
6242                }
6243            }
6244
6245            // First check if this content provider has been published...
6246            cpr = mProviderMap.getProviderByName(name, userId);
6247            boolean providerRunning = cpr != null;
6248            if (providerRunning) {
6249                cpi = cpr.info;
6250                String msg;
6251                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6252                    throw new SecurityException(msg);
6253                }
6254
6255                if (r != null && cpr.canRunHere(r)) {
6256                    // This provider has been published or is in the process
6257                    // of being published...  but it is also allowed to run
6258                    // in the caller's process, so don't make a connection
6259                    // and just let the caller instantiate its own instance.
6260                    ContentProviderHolder holder = cpr.newHolder(null);
6261                    // don't give caller the provider object, it needs
6262                    // to make its own.
6263                    holder.provider = null;
6264                    return holder;
6265                }
6266
6267                final long origId = Binder.clearCallingIdentity();
6268
6269                // In this case the provider instance already exists, so we can
6270                // return it right away.
6271                conn = incProviderCountLocked(r, cpr, token, stable);
6272                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6273                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6274                        // If this is a perceptible app accessing the provider,
6275                        // make sure to count it as being accessed and thus
6276                        // back up on the LRU list.  This is good because
6277                        // content providers are often expensive to start.
6278                        updateLruProcessLocked(cpr.proc, false, true);
6279                    }
6280                }
6281
6282                if (cpr.proc != null) {
6283                    if (false) {
6284                        if (cpr.name.flattenToShortString().equals(
6285                                "com.android.providers.calendar/.CalendarProvider2")) {
6286                            Slog.v(TAG, "****************** KILLING "
6287                                + cpr.name.flattenToShortString());
6288                            Process.killProcess(cpr.proc.pid);
6289                        }
6290                    }
6291                    boolean success = updateOomAdjLocked(cpr.proc);
6292                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6293                    // NOTE: there is still a race here where a signal could be
6294                    // pending on the process even though we managed to update its
6295                    // adj level.  Not sure what to do about this, but at least
6296                    // the race is now smaller.
6297                    if (!success) {
6298                        // Uh oh...  it looks like the provider's process
6299                        // has been killed on us.  We need to wait for a new
6300                        // process to be started, and make sure its death
6301                        // doesn't kill our process.
6302                        Slog.i(TAG,
6303                                "Existing provider " + cpr.name.flattenToShortString()
6304                                + " is crashing; detaching " + r);
6305                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6306                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6307                        if (!lastRef) {
6308                            // This wasn't the last ref our process had on
6309                            // the provider...  we have now been killed, bail.
6310                            return null;
6311                        }
6312                        providerRunning = false;
6313                        conn = null;
6314                    }
6315                }
6316
6317                Binder.restoreCallingIdentity(origId);
6318            }
6319
6320            boolean singleton;
6321            if (!providerRunning) {
6322                try {
6323                    cpi = AppGlobals.getPackageManager().
6324                        resolveContentProvider(name,
6325                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6326                } catch (RemoteException ex) {
6327                }
6328                if (cpi == null) {
6329                    return null;
6330                }
6331                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6332                        cpi.name, cpi.flags);
6333                if (singleton) {
6334                    userId = 0;
6335                }
6336                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6337
6338                String msg;
6339                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6340                    throw new SecurityException(msg);
6341                }
6342
6343                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6344                        && !cpi.processName.equals("system")) {
6345                    // If this content provider does not run in the system
6346                    // process, and the system is not yet ready to run other
6347                    // processes, then fail fast instead of hanging.
6348                    throw new IllegalArgumentException(
6349                            "Attempt to launch content provider before system ready");
6350                }
6351
6352                // Make sure that the user who owns this provider is started.  If not,
6353                // we don't want to allow it to run.
6354                if (mStartedUsers.get(userId) == null) {
6355                    Slog.w(TAG, "Unable to launch app "
6356                            + cpi.applicationInfo.packageName + "/"
6357                            + cpi.applicationInfo.uid + " for provider "
6358                            + name + ": user " + userId + " is stopped");
6359                    return null;
6360                }
6361
6362                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6363                cpr = mProviderMap.getProviderByClass(comp, userId);
6364                final boolean firstClass = cpr == null;
6365                if (firstClass) {
6366                    try {
6367                        ApplicationInfo ai =
6368                            AppGlobals.getPackageManager().
6369                                getApplicationInfo(
6370                                        cpi.applicationInfo.packageName,
6371                                        STOCK_PM_FLAGS, userId);
6372                        if (ai == null) {
6373                            Slog.w(TAG, "No package info for content provider "
6374                                    + cpi.name);
6375                            return null;
6376                        }
6377                        ai = getAppInfoForUser(ai, userId);
6378                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6379                    } catch (RemoteException ex) {
6380                        // pm is in same process, this will never happen.
6381                    }
6382                }
6383
6384                if (r != null && cpr.canRunHere(r)) {
6385                    // If this is a multiprocess provider, then just return its
6386                    // info and allow the caller to instantiate it.  Only do
6387                    // this if the provider is the same user as the caller's
6388                    // process, or can run as root (so can be in any process).
6389                    return cpr.newHolder(null);
6390                }
6391
6392                if (DEBUG_PROVIDER) {
6393                    RuntimeException e = new RuntimeException("here");
6394                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6395                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6396                }
6397
6398                // This is single process, and our app is now connecting to it.
6399                // See if we are already in the process of launching this
6400                // provider.
6401                final int N = mLaunchingProviders.size();
6402                int i;
6403                for (i=0; i<N; i++) {
6404                    if (mLaunchingProviders.get(i) == cpr) {
6405                        break;
6406                    }
6407                }
6408
6409                // If the provider is not already being launched, then get it
6410                // started.
6411                if (i >= N) {
6412                    final long origId = Binder.clearCallingIdentity();
6413
6414                    try {
6415                        // Content provider is now in use, its package can't be stopped.
6416                        try {
6417                            AppGlobals.getPackageManager().setPackageStoppedState(
6418                                    cpr.appInfo.packageName, false, userId);
6419                        } catch (RemoteException e) {
6420                        } catch (IllegalArgumentException e) {
6421                            Slog.w(TAG, "Failed trying to unstop package "
6422                                    + cpr.appInfo.packageName + ": " + e);
6423                        }
6424
6425                        ProcessRecord proc = startProcessLocked(cpi.processName,
6426                                cpr.appInfo, false, 0, "content provider",
6427                                new ComponentName(cpi.applicationInfo.packageName,
6428                                        cpi.name), false, false);
6429                        if (proc == null) {
6430                            Slog.w(TAG, "Unable to launch app "
6431                                    + cpi.applicationInfo.packageName + "/"
6432                                    + cpi.applicationInfo.uid + " for provider "
6433                                    + name + ": process is bad");
6434                            return null;
6435                        }
6436                        cpr.launchingApp = proc;
6437                        mLaunchingProviders.add(cpr);
6438                    } finally {
6439                        Binder.restoreCallingIdentity(origId);
6440                    }
6441                }
6442
6443                // Make sure the provider is published (the same provider class
6444                // may be published under multiple names).
6445                if (firstClass) {
6446                    mProviderMap.putProviderByClass(comp, cpr);
6447                }
6448
6449                mProviderMap.putProviderByName(name, cpr);
6450                conn = incProviderCountLocked(r, cpr, token, stable);
6451                if (conn != null) {
6452                    conn.waiting = true;
6453                }
6454            }
6455        }
6456
6457        // Wait for the provider to be published...
6458        synchronized (cpr) {
6459            while (cpr.provider == null) {
6460                if (cpr.launchingApp == null) {
6461                    Slog.w(TAG, "Unable to launch app "
6462                            + cpi.applicationInfo.packageName + "/"
6463                            + cpi.applicationInfo.uid + " for provider "
6464                            + name + ": launching app became null");
6465                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6466                            cpi.applicationInfo.packageName,
6467                            cpi.applicationInfo.uid, name);
6468                    return null;
6469                }
6470                try {
6471                    if (DEBUG_MU) {
6472                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6473                                + cpr.launchingApp);
6474                    }
6475                    if (conn != null) {
6476                        conn.waiting = true;
6477                    }
6478                    cpr.wait();
6479                } catch (InterruptedException ex) {
6480                } finally {
6481                    if (conn != null) {
6482                        conn.waiting = false;
6483                    }
6484                }
6485            }
6486        }
6487        return cpr != null ? cpr.newHolder(conn) : null;
6488    }
6489
6490    public final ContentProviderHolder getContentProvider(
6491            IApplicationThread caller, String name, boolean stable) {
6492        enforceNotIsolatedCaller("getContentProvider");
6493        if (caller == null) {
6494            String msg = "null IApplicationThread when getting content provider "
6495                    + name;
6496            Slog.w(TAG, msg);
6497            throw new SecurityException(msg);
6498        }
6499
6500        return getContentProviderImpl(caller, name, null, stable,
6501                UserHandle.getCallingUserId());
6502    }
6503
6504    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6505        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6506            "Do not have permission in call getContentProviderExternal()");
6507        return getContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6508    }
6509
6510    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6511            IBinder token, int userId) {
6512        return getContentProviderImpl(null, name, token, true, userId);
6513    }
6514
6515    /**
6516     * Drop a content provider from a ProcessRecord's bookkeeping
6517     * @param cpr
6518     */
6519    public void removeContentProvider(IBinder connection, boolean stable) {
6520        enforceNotIsolatedCaller("removeContentProvider");
6521        synchronized (this) {
6522            ContentProviderConnection conn;
6523            try {
6524                conn = (ContentProviderConnection)connection;
6525            } catch (ClassCastException e) {
6526                String msg ="removeContentProvider: " + connection
6527                        + " not a ContentProviderConnection";
6528                Slog.w(TAG, msg);
6529                throw new IllegalArgumentException(msg);
6530            }
6531            if (conn == null) {
6532                throw new NullPointerException("connection is null");
6533            }
6534            if (decProviderCountLocked(conn, null, null, stable)) {
6535                updateOomAdjLocked();
6536            }
6537        }
6538    }
6539
6540    public void removeContentProviderExternal(String name, IBinder token) {
6541        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6542            "Do not have permission in call removeContentProviderExternal()");
6543        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6544    }
6545
6546    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6547        synchronized (this) {
6548            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6549            if(cpr == null) {
6550                //remove from mProvidersByClass
6551                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6552                return;
6553            }
6554
6555            //update content provider record entry info
6556            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6557            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6558            if (localCpr.hasExternalProcessHandles()) {
6559                if (localCpr.removeExternalProcessHandleLocked(token)) {
6560                    updateOomAdjLocked();
6561                } else {
6562                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6563                            + " with no external reference for token: "
6564                            + token + ".");
6565                }
6566            } else {
6567                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6568                        + " with no external references.");
6569            }
6570        }
6571    }
6572
6573    public final void publishContentProviders(IApplicationThread caller,
6574            List<ContentProviderHolder> providers) {
6575        if (providers == null) {
6576            return;
6577        }
6578
6579        enforceNotIsolatedCaller("publishContentProviders");
6580        synchronized (this) {
6581            final ProcessRecord r = getRecordForAppLocked(caller);
6582            if (DEBUG_MU)
6583                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6584            if (r == null) {
6585                throw new SecurityException(
6586                        "Unable to find app for caller " + caller
6587                      + " (pid=" + Binder.getCallingPid()
6588                      + ") when publishing content providers");
6589            }
6590
6591            final long origId = Binder.clearCallingIdentity();
6592
6593            final int N = providers.size();
6594            for (int i=0; i<N; i++) {
6595                ContentProviderHolder src = providers.get(i);
6596                if (src == null || src.info == null || src.provider == null) {
6597                    continue;
6598                }
6599                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6600                if (DEBUG_MU)
6601                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6602                if (dst != null) {
6603                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6604                    mProviderMap.putProviderByClass(comp, dst);
6605                    String names[] = dst.info.authority.split(";");
6606                    for (int j = 0; j < names.length; j++) {
6607                        mProviderMap.putProviderByName(names[j], dst);
6608                    }
6609
6610                    int NL = mLaunchingProviders.size();
6611                    int j;
6612                    for (j=0; j<NL; j++) {
6613                        if (mLaunchingProviders.get(j) == dst) {
6614                            mLaunchingProviders.remove(j);
6615                            j--;
6616                            NL--;
6617                        }
6618                    }
6619                    synchronized (dst) {
6620                        dst.provider = src.provider;
6621                        dst.proc = r;
6622                        dst.notifyAll();
6623                    }
6624                    updateOomAdjLocked(r);
6625                }
6626            }
6627
6628            Binder.restoreCallingIdentity(origId);
6629        }
6630    }
6631
6632    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6633        ContentProviderConnection conn;
6634        try {
6635            conn = (ContentProviderConnection)connection;
6636        } catch (ClassCastException e) {
6637            String msg ="refContentProvider: " + connection
6638                    + " not a ContentProviderConnection";
6639            Slog.w(TAG, msg);
6640            throw new IllegalArgumentException(msg);
6641        }
6642        if (conn == null) {
6643            throw new NullPointerException("connection is null");
6644        }
6645
6646        synchronized (this) {
6647            if (stable > 0) {
6648                conn.numStableIncs += stable;
6649            }
6650            stable = conn.stableCount + stable;
6651            if (stable < 0) {
6652                throw new IllegalStateException("stableCount < 0: " + stable);
6653            }
6654
6655            if (unstable > 0) {
6656                conn.numUnstableIncs += unstable;
6657            }
6658            unstable = conn.unstableCount + unstable;
6659            if (unstable < 0) {
6660                throw new IllegalStateException("unstableCount < 0: " + unstable);
6661            }
6662
6663            if ((stable+unstable) <= 0) {
6664                throw new IllegalStateException("ref counts can't go to zero here: stable="
6665                        + stable + " unstable=" + unstable);
6666            }
6667            conn.stableCount = stable;
6668            conn.unstableCount = unstable;
6669            return !conn.dead;
6670        }
6671    }
6672
6673    public void unstableProviderDied(IBinder connection) {
6674        ContentProviderConnection conn;
6675        try {
6676            conn = (ContentProviderConnection)connection;
6677        } catch (ClassCastException e) {
6678            String msg ="refContentProvider: " + connection
6679                    + " not a ContentProviderConnection";
6680            Slog.w(TAG, msg);
6681            throw new IllegalArgumentException(msg);
6682        }
6683        if (conn == null) {
6684            throw new NullPointerException("connection is null");
6685        }
6686
6687        // Safely retrieve the content provider associated with the connection.
6688        IContentProvider provider;
6689        synchronized (this) {
6690            provider = conn.provider.provider;
6691        }
6692
6693        if (provider == null) {
6694            // Um, yeah, we're way ahead of you.
6695            return;
6696        }
6697
6698        // Make sure the caller is being honest with us.
6699        if (provider.asBinder().pingBinder()) {
6700            // Er, no, still looks good to us.
6701            synchronized (this) {
6702                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6703                        + " says " + conn + " died, but we don't agree");
6704                return;
6705            }
6706        }
6707
6708        // Well look at that!  It's dead!
6709        synchronized (this) {
6710            if (conn.provider.provider != provider) {
6711                // But something changed...  good enough.
6712                return;
6713            }
6714
6715            ProcessRecord proc = conn.provider.proc;
6716            if (proc == null || proc.thread == null) {
6717                // Seems like the process is already cleaned up.
6718                return;
6719            }
6720
6721            // As far as we're concerned, this is just like receiving a
6722            // death notification...  just a bit prematurely.
6723            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6724                    + ") early provider death");
6725            final long ident = Binder.clearCallingIdentity();
6726            try {
6727                appDiedLocked(proc, proc.pid, proc.thread);
6728            } finally {
6729                Binder.restoreCallingIdentity(ident);
6730            }
6731        }
6732    }
6733
6734    public static final void installSystemProviders() {
6735        List<ProviderInfo> providers;
6736        synchronized (mSelf) {
6737            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6738            providers = mSelf.generateApplicationProvidersLocked(app);
6739            if (providers != null) {
6740                for (int i=providers.size()-1; i>=0; i--) {
6741                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6742                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6743                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6744                                + ": not system .apk");
6745                        providers.remove(i);
6746                    }
6747                }
6748            }
6749        }
6750        if (providers != null) {
6751            mSystemThread.installSystemProviders(providers);
6752        }
6753
6754        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6755
6756        mSelf.mUsageStatsService.monitorPackages();
6757    }
6758
6759    /**
6760     * Allows app to retrieve the MIME type of a URI without having permission
6761     * to access its content provider.
6762     *
6763     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6764     *
6765     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6766     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6767     */
6768    public String getProviderMimeType(Uri uri) {
6769        enforceNotIsolatedCaller("getProviderMimeType");
6770        final String name = uri.getAuthority();
6771        final int userId = UserHandle.getCallingUserId();
6772        final long ident = Binder.clearCallingIdentity();
6773        ContentProviderHolder holder = null;
6774
6775        try {
6776            holder = getContentProviderExternalUnchecked(name, null, userId);
6777            if (holder != null) {
6778                return holder.provider.getType(uri);
6779            }
6780        } catch (RemoteException e) {
6781            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6782            return null;
6783        } finally {
6784            if (holder != null) {
6785                removeContentProviderExternalUnchecked(name, null, userId);
6786            }
6787            Binder.restoreCallingIdentity(ident);
6788        }
6789
6790        return null;
6791    }
6792
6793    // =========================================================
6794    // GLOBAL MANAGEMENT
6795    // =========================================================
6796
6797    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6798            ApplicationInfo info, String customProcess, boolean isolated) {
6799        String proc = customProcess != null ? customProcess : info.processName;
6800        BatteryStatsImpl.Uid.Proc ps = null;
6801        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6802        int uid = info.uid;
6803        if (isolated) {
6804            int userId = UserHandle.getUserId(uid);
6805            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6806            uid = 0;
6807            while (true) {
6808                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6809                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6810                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6811                }
6812                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6813                mNextIsolatedProcessUid++;
6814                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6815                    // No process for this uid, use it.
6816                    break;
6817                }
6818                stepsLeft--;
6819                if (stepsLeft <= 0) {
6820                    return null;
6821                }
6822            }
6823        }
6824        synchronized (stats) {
6825            ps = stats.getProcessStatsLocked(info.uid, proc);
6826        }
6827        return new ProcessRecord(ps, thread, info, proc, uid);
6828    }
6829
6830    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6831        ProcessRecord app;
6832        if (!isolated) {
6833            app = getProcessRecordLocked(info.processName, info.uid);
6834        } else {
6835            app = null;
6836        }
6837
6838        if (app == null) {
6839            app = newProcessRecordLocked(null, info, null, isolated);
6840            mProcessNames.put(info.processName, app.uid, app);
6841            if (isolated) {
6842                mIsolatedProcesses.put(app.uid, app);
6843            }
6844            updateLruProcessLocked(app, true, true);
6845        }
6846
6847        // This package really, really can not be stopped.
6848        try {
6849            AppGlobals.getPackageManager().setPackageStoppedState(
6850                    info.packageName, false, UserHandle.getUserId(app.uid));
6851        } catch (RemoteException e) {
6852        } catch (IllegalArgumentException e) {
6853            Slog.w(TAG, "Failed trying to unstop package "
6854                    + info.packageName + ": " + e);
6855        }
6856
6857        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6858                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6859            app.persistent = true;
6860            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6861        }
6862        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6863            mPersistentStartingProcesses.add(app);
6864            startProcessLocked(app, "added application", app.processName);
6865        }
6866
6867        return app;
6868    }
6869
6870    public void unhandledBack() {
6871        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6872                "unhandledBack()");
6873
6874        synchronized(this) {
6875            int count = mMainStack.mHistory.size();
6876            if (DEBUG_SWITCH) Slog.d(
6877                TAG, "Performing unhandledBack(): stack size = " + count);
6878            if (count > 1) {
6879                final long origId = Binder.clearCallingIdentity();
6880                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6881                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6882                Binder.restoreCallingIdentity(origId);
6883            }
6884        }
6885    }
6886
6887    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6888        enforceNotIsolatedCaller("openContentUri");
6889        final int userId = UserHandle.getCallingUserId();
6890        String name = uri.getAuthority();
6891        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
6892        ParcelFileDescriptor pfd = null;
6893        if (cph != null) {
6894            // We record the binder invoker's uid in thread-local storage before
6895            // going to the content provider to open the file.  Later, in the code
6896            // that handles all permissions checks, we look for this uid and use
6897            // that rather than the Activity Manager's own uid.  The effect is that
6898            // we do the check against the caller's permissions even though it looks
6899            // to the content provider like the Activity Manager itself is making
6900            // the request.
6901            sCallerIdentity.set(new Identity(
6902                    Binder.getCallingPid(), Binder.getCallingUid()));
6903            try {
6904                pfd = cph.provider.openFile(uri, "r");
6905            } catch (FileNotFoundException e) {
6906                // do nothing; pfd will be returned null
6907            } finally {
6908                // Ensure that whatever happens, we clean up the identity state
6909                sCallerIdentity.remove();
6910            }
6911
6912            // We've got the fd now, so we're done with the provider.
6913            removeContentProviderExternalUnchecked(name, null, userId);
6914        } else {
6915            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6916        }
6917        return pfd;
6918    }
6919
6920    // Actually is sleeping or shutting down or whatever else in the future
6921    // is an inactive state.
6922    public boolean isSleeping() {
6923        return mSleeping || mShuttingDown;
6924    }
6925
6926    public void goingToSleep() {
6927        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6928                != PackageManager.PERMISSION_GRANTED) {
6929            throw new SecurityException("Requires permission "
6930                    + android.Manifest.permission.DEVICE_POWER);
6931        }
6932
6933        synchronized(this) {
6934            mWentToSleep = true;
6935            updateEventDispatchingLocked();
6936
6937            if (!mSleeping) {
6938                mSleeping = true;
6939                mMainStack.stopIfSleepingLocked();
6940
6941                // Initialize the wake times of all processes.
6942                checkExcessivePowerUsageLocked(false);
6943                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6944                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6945                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6946            }
6947        }
6948    }
6949
6950    public boolean shutdown(int timeout) {
6951        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6952                != PackageManager.PERMISSION_GRANTED) {
6953            throw new SecurityException("Requires permission "
6954                    + android.Manifest.permission.SHUTDOWN);
6955        }
6956
6957        boolean timedout = false;
6958
6959        synchronized(this) {
6960            mShuttingDown = true;
6961            updateEventDispatchingLocked();
6962
6963            if (mMainStack.mResumedActivity != null) {
6964                mMainStack.stopIfSleepingLocked();
6965                final long endTime = System.currentTimeMillis() + timeout;
6966                while (mMainStack.mResumedActivity != null
6967                        || mMainStack.mPausingActivity != null) {
6968                    long delay = endTime - System.currentTimeMillis();
6969                    if (delay <= 0) {
6970                        Slog.w(TAG, "Activity manager shutdown timed out");
6971                        timedout = true;
6972                        break;
6973                    }
6974                    try {
6975                        this.wait();
6976                    } catch (InterruptedException e) {
6977                    }
6978                }
6979            }
6980        }
6981
6982        mUsageStatsService.shutdown();
6983        mBatteryStatsService.shutdown();
6984
6985        return timedout;
6986    }
6987
6988    public final void activitySlept(IBinder token) {
6989        if (localLOGV) Slog.v(
6990            TAG, "Activity slept: token=" + token);
6991
6992        ActivityRecord r = null;
6993
6994        final long origId = Binder.clearCallingIdentity();
6995
6996        synchronized (this) {
6997            r = mMainStack.isInStackLocked(token);
6998            if (r != null) {
6999                mMainStack.activitySleptLocked(r);
7000            }
7001        }
7002
7003        Binder.restoreCallingIdentity(origId);
7004    }
7005
7006    private void comeOutOfSleepIfNeededLocked() {
7007        if (!mWentToSleep && !mLockScreenShown) {
7008            if (mSleeping) {
7009                mSleeping = false;
7010                mMainStack.awakeFromSleepingLocked();
7011                mMainStack.resumeTopActivityLocked(null);
7012            }
7013        }
7014    }
7015
7016    public void wakingUp() {
7017        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7018                != PackageManager.PERMISSION_GRANTED) {
7019            throw new SecurityException("Requires permission "
7020                    + android.Manifest.permission.DEVICE_POWER);
7021        }
7022
7023        synchronized(this) {
7024            mWentToSleep = false;
7025            updateEventDispatchingLocked();
7026            comeOutOfSleepIfNeededLocked();
7027        }
7028    }
7029
7030    private void updateEventDispatchingLocked() {
7031        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7032    }
7033
7034    public void setLockScreenShown(boolean shown) {
7035        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7036                != PackageManager.PERMISSION_GRANTED) {
7037            throw new SecurityException("Requires permission "
7038                    + android.Manifest.permission.DEVICE_POWER);
7039        }
7040
7041        synchronized(this) {
7042            mLockScreenShown = shown;
7043            comeOutOfSleepIfNeededLocked();
7044        }
7045    }
7046
7047    public void stopAppSwitches() {
7048        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7049                != PackageManager.PERMISSION_GRANTED) {
7050            throw new SecurityException("Requires permission "
7051                    + android.Manifest.permission.STOP_APP_SWITCHES);
7052        }
7053
7054        synchronized(this) {
7055            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7056                    + APP_SWITCH_DELAY_TIME;
7057            mDidAppSwitch = false;
7058            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7059            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7060            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7061        }
7062    }
7063
7064    public void resumeAppSwitches() {
7065        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7066                != PackageManager.PERMISSION_GRANTED) {
7067            throw new SecurityException("Requires permission "
7068                    + android.Manifest.permission.STOP_APP_SWITCHES);
7069        }
7070
7071        synchronized(this) {
7072            // Note that we don't execute any pending app switches... we will
7073            // let those wait until either the timeout, or the next start
7074            // activity request.
7075            mAppSwitchesAllowedTime = 0;
7076        }
7077    }
7078
7079    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7080            String name) {
7081        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7082            return true;
7083        }
7084
7085        final int perm = checkComponentPermission(
7086                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7087                callingUid, -1, true);
7088        if (perm == PackageManager.PERMISSION_GRANTED) {
7089            return true;
7090        }
7091
7092        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7093        return false;
7094    }
7095
7096    public void setDebugApp(String packageName, boolean waitForDebugger,
7097            boolean persistent) {
7098        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7099                "setDebugApp()");
7100
7101        // Note that this is not really thread safe if there are multiple
7102        // callers into it at the same time, but that's not a situation we
7103        // care about.
7104        if (persistent) {
7105            final ContentResolver resolver = mContext.getContentResolver();
7106            Settings.System.putString(
7107                resolver, Settings.System.DEBUG_APP,
7108                packageName);
7109            Settings.System.putInt(
7110                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7111                waitForDebugger ? 1 : 0);
7112        }
7113
7114        synchronized (this) {
7115            if (!persistent) {
7116                mOrigDebugApp = mDebugApp;
7117                mOrigWaitForDebugger = mWaitForDebugger;
7118            }
7119            mDebugApp = packageName;
7120            mWaitForDebugger = waitForDebugger;
7121            mDebugTransient = !persistent;
7122            if (packageName != null) {
7123                final long origId = Binder.clearCallingIdentity();
7124                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
7125                Binder.restoreCallingIdentity(origId);
7126            }
7127        }
7128    }
7129
7130    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7131        synchronized (this) {
7132            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7133            if (!isDebuggable) {
7134                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7135                    throw new SecurityException("Process not debuggable: " + app.packageName);
7136                }
7137            }
7138
7139            mOpenGlTraceApp = processName;
7140        }
7141    }
7142
7143    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7144            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7145        synchronized (this) {
7146            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7147            if (!isDebuggable) {
7148                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7149                    throw new SecurityException("Process not debuggable: " + app.packageName);
7150                }
7151            }
7152            mProfileApp = processName;
7153            mProfileFile = profileFile;
7154            if (mProfileFd != null) {
7155                try {
7156                    mProfileFd.close();
7157                } catch (IOException e) {
7158                }
7159                mProfileFd = null;
7160            }
7161            mProfileFd = profileFd;
7162            mProfileType = 0;
7163            mAutoStopProfiler = autoStopProfiler;
7164        }
7165    }
7166
7167    public void setAlwaysFinish(boolean enabled) {
7168        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7169                "setAlwaysFinish()");
7170
7171        Settings.System.putInt(
7172                mContext.getContentResolver(),
7173                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7174
7175        synchronized (this) {
7176            mAlwaysFinishActivities = enabled;
7177        }
7178    }
7179
7180    public void setActivityController(IActivityController controller) {
7181        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7182                "setActivityController()");
7183        synchronized (this) {
7184            mController = controller;
7185        }
7186    }
7187
7188    public boolean isUserAMonkey() {
7189        // For now the fact that there is a controller implies
7190        // we have a monkey.
7191        synchronized (this) {
7192            return mController != null;
7193        }
7194    }
7195
7196    public void registerProcessObserver(IProcessObserver observer) {
7197        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7198                "registerProcessObserver()");
7199        synchronized (this) {
7200            mProcessObservers.register(observer);
7201        }
7202    }
7203
7204    public void unregisterProcessObserver(IProcessObserver observer) {
7205        synchronized (this) {
7206            mProcessObservers.unregister(observer);
7207        }
7208    }
7209
7210    public void setImmersive(IBinder token, boolean immersive) {
7211        synchronized(this) {
7212            ActivityRecord r = mMainStack.isInStackLocked(token);
7213            if (r == null) {
7214                throw new IllegalArgumentException();
7215            }
7216            r.immersive = immersive;
7217        }
7218    }
7219
7220    public boolean isImmersive(IBinder token) {
7221        synchronized (this) {
7222            ActivityRecord r = mMainStack.isInStackLocked(token);
7223            if (r == null) {
7224                throw new IllegalArgumentException();
7225            }
7226            return r.immersive;
7227        }
7228    }
7229
7230    public boolean isTopActivityImmersive() {
7231        enforceNotIsolatedCaller("startActivity");
7232        synchronized (this) {
7233            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7234            return (r != null) ? r.immersive : false;
7235        }
7236    }
7237
7238    public final void enterSafeMode() {
7239        synchronized(this) {
7240            // It only makes sense to do this before the system is ready
7241            // and started launching other packages.
7242            if (!mSystemReady) {
7243                try {
7244                    AppGlobals.getPackageManager().enterSafeMode();
7245                } catch (RemoteException e) {
7246                }
7247            }
7248        }
7249    }
7250
7251    public final void showSafeModeOverlay() {
7252        View v = LayoutInflater.from(mContext).inflate(
7253                com.android.internal.R.layout.safe_mode, null);
7254        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7255        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7256        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7257        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7258        lp.gravity = Gravity.BOTTOM | Gravity.START;
7259        lp.format = v.getBackground().getOpacity();
7260        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7261                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7262        ((WindowManager)mContext.getSystemService(
7263                Context.WINDOW_SERVICE)).addView(v, lp);
7264    }
7265
7266    public void noteWakeupAlarm(IIntentSender sender) {
7267        if (!(sender instanceof PendingIntentRecord)) {
7268            return;
7269        }
7270        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7271        synchronized (stats) {
7272            if (mBatteryStatsService.isOnBattery()) {
7273                mBatteryStatsService.enforceCallingPermission();
7274                PendingIntentRecord rec = (PendingIntentRecord)sender;
7275                int MY_UID = Binder.getCallingUid();
7276                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7277                BatteryStatsImpl.Uid.Pkg pkg =
7278                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7279                pkg.incWakeupsLocked();
7280            }
7281        }
7282    }
7283
7284    public boolean killPids(int[] pids, String pReason, boolean secure) {
7285        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7286            throw new SecurityException("killPids only available to the system");
7287        }
7288        String reason = (pReason == null) ? "Unknown" : pReason;
7289        // XXX Note: don't acquire main activity lock here, because the window
7290        // manager calls in with its locks held.
7291
7292        boolean killed = false;
7293        synchronized (mPidsSelfLocked) {
7294            int[] types = new int[pids.length];
7295            int worstType = 0;
7296            for (int i=0; i<pids.length; i++) {
7297                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7298                if (proc != null) {
7299                    int type = proc.setAdj;
7300                    types[i] = type;
7301                    if (type > worstType) {
7302                        worstType = type;
7303                    }
7304                }
7305            }
7306
7307            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7308            // then constrain it so we will kill all hidden procs.
7309            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7310                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7311                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7312            }
7313
7314            // If this is not a secure call, don't let it kill processes that
7315            // are important.
7316            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7317                worstType = ProcessList.SERVICE_ADJ;
7318            }
7319
7320            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7321            for (int i=0; i<pids.length; i++) {
7322                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7323                if (proc == null) {
7324                    continue;
7325                }
7326                int adj = proc.setAdj;
7327                if (adj >= worstType && !proc.killedBackground) {
7328                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7329                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7330                            proc.processName, adj, reason);
7331                    killed = true;
7332                    proc.killedBackground = true;
7333                    Process.killProcessQuiet(pids[i]);
7334                }
7335            }
7336        }
7337        return killed;
7338    }
7339
7340    @Override
7341    public boolean killProcessesBelowForeground(String reason) {
7342        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7343            throw new SecurityException("killProcessesBelowForeground() only available to system");
7344        }
7345
7346        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7347    }
7348
7349    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7350        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7351            throw new SecurityException("killProcessesBelowAdj() only available to system");
7352        }
7353
7354        boolean killed = false;
7355        synchronized (mPidsSelfLocked) {
7356            final int size = mPidsSelfLocked.size();
7357            for (int i = 0; i < size; i++) {
7358                final int pid = mPidsSelfLocked.keyAt(i);
7359                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7360                if (proc == null) continue;
7361
7362                final int adj = proc.setAdj;
7363                if (adj > belowAdj && !proc.killedBackground) {
7364                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7365                    EventLog.writeEvent(
7366                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7367                    killed = true;
7368                    proc.killedBackground = true;
7369                    Process.killProcessQuiet(pid);
7370                }
7371            }
7372        }
7373        return killed;
7374    }
7375
7376    public final void startRunning(String pkg, String cls, String action,
7377            String data) {
7378        synchronized(this) {
7379            if (mStartRunning) {
7380                return;
7381            }
7382            mStartRunning = true;
7383            mTopComponent = pkg != null && cls != null
7384                    ? new ComponentName(pkg, cls) : null;
7385            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7386            mTopData = data;
7387            if (!mSystemReady) {
7388                return;
7389            }
7390        }
7391
7392        systemReady(null);
7393    }
7394
7395    private void retrieveSettings() {
7396        final ContentResolver resolver = mContext.getContentResolver();
7397        String debugApp = Settings.System.getString(
7398            resolver, Settings.System.DEBUG_APP);
7399        boolean waitForDebugger = Settings.System.getInt(
7400            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7401        boolean alwaysFinishActivities = Settings.System.getInt(
7402            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7403
7404        Configuration configuration = new Configuration();
7405        Settings.System.getConfiguration(resolver, configuration);
7406
7407        synchronized (this) {
7408            mDebugApp = mOrigDebugApp = debugApp;
7409            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7410            mAlwaysFinishActivities = alwaysFinishActivities;
7411            // This happens before any activities are started, so we can
7412            // change mConfiguration in-place.
7413            updateConfigurationLocked(configuration, null, false, true);
7414            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7415        }
7416    }
7417
7418    public boolean testIsSystemReady() {
7419        // no need to synchronize(this) just to read & return the value
7420        return mSystemReady;
7421    }
7422
7423    private static File getCalledPreBootReceiversFile() {
7424        File dataDir = Environment.getDataDirectory();
7425        File systemDir = new File(dataDir, "system");
7426        File fname = new File(systemDir, "called_pre_boots.dat");
7427        return fname;
7428    }
7429
7430    static final int LAST_DONE_VERSION = 10000;
7431
7432    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7433        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7434        File file = getCalledPreBootReceiversFile();
7435        FileInputStream fis = null;
7436        try {
7437            fis = new FileInputStream(file);
7438            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7439            int fvers = dis.readInt();
7440            if (fvers == LAST_DONE_VERSION) {
7441                String vers = dis.readUTF();
7442                String codename = dis.readUTF();
7443                String build = dis.readUTF();
7444                if (android.os.Build.VERSION.RELEASE.equals(vers)
7445                        && android.os.Build.VERSION.CODENAME.equals(codename)
7446                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7447                    int num = dis.readInt();
7448                    while (num > 0) {
7449                        num--;
7450                        String pkg = dis.readUTF();
7451                        String cls = dis.readUTF();
7452                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7453                    }
7454                }
7455            }
7456        } catch (FileNotFoundException e) {
7457        } catch (IOException e) {
7458            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7459        } finally {
7460            if (fis != null) {
7461                try {
7462                    fis.close();
7463                } catch (IOException e) {
7464                }
7465            }
7466        }
7467        return lastDoneReceivers;
7468    }
7469
7470    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7471        File file = getCalledPreBootReceiversFile();
7472        FileOutputStream fos = null;
7473        DataOutputStream dos = null;
7474        try {
7475            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7476            fos = new FileOutputStream(file);
7477            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7478            dos.writeInt(LAST_DONE_VERSION);
7479            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7480            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7481            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7482            dos.writeInt(list.size());
7483            for (int i=0; i<list.size(); i++) {
7484                dos.writeUTF(list.get(i).getPackageName());
7485                dos.writeUTF(list.get(i).getClassName());
7486            }
7487        } catch (IOException e) {
7488            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7489            file.delete();
7490        } finally {
7491            FileUtils.sync(fos);
7492            if (dos != null) {
7493                try {
7494                    dos.close();
7495                } catch (IOException e) {
7496                    // TODO Auto-generated catch block
7497                    e.printStackTrace();
7498                }
7499            }
7500        }
7501    }
7502
7503    public void systemReady(final Runnable goingCallback) {
7504        synchronized(this) {
7505            if (mSystemReady) {
7506                if (goingCallback != null) goingCallback.run();
7507                return;
7508            }
7509
7510            // Check to see if there are any update receivers to run.
7511            if (!mDidUpdate) {
7512                if (mWaitingUpdate) {
7513                    return;
7514                }
7515                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7516                List<ResolveInfo> ris = null;
7517                try {
7518                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7519                            intent, null, 0, 0);
7520                } catch (RemoteException e) {
7521                }
7522                if (ris != null) {
7523                    for (int i=ris.size()-1; i>=0; i--) {
7524                        if ((ris.get(i).activityInfo.applicationInfo.flags
7525                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7526                            ris.remove(i);
7527                        }
7528                    }
7529                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7530
7531                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7532
7533                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7534                    for (int i=0; i<ris.size(); i++) {
7535                        ActivityInfo ai = ris.get(i).activityInfo;
7536                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7537                        if (lastDoneReceivers.contains(comp)) {
7538                            ris.remove(i);
7539                            i--;
7540                        }
7541                    }
7542
7543                    for (int i=0; i<ris.size(); i++) {
7544                        ActivityInfo ai = ris.get(i).activityInfo;
7545                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7546                        doneReceivers.add(comp);
7547                        intent.setComponent(comp);
7548                        IIntentReceiver finisher = null;
7549                        if (i == ris.size()-1) {
7550                            finisher = new IIntentReceiver.Stub() {
7551                                public void performReceive(Intent intent, int resultCode,
7552                                        String data, Bundle extras, boolean ordered,
7553                                        boolean sticky, int sendingUser) {
7554                                    // The raw IIntentReceiver interface is called
7555                                    // with the AM lock held, so redispatch to
7556                                    // execute our code without the lock.
7557                                    mHandler.post(new Runnable() {
7558                                        public void run() {
7559                                            synchronized (ActivityManagerService.this) {
7560                                                mDidUpdate = true;
7561                                            }
7562                                            writeLastDonePreBootReceivers(doneReceivers);
7563                                            showBootMessage(mContext.getText(
7564                                                    R.string.android_upgrading_complete),
7565                                                    false);
7566                                            systemReady(goingCallback);
7567                                        }
7568                                    });
7569                                }
7570                            };
7571                        }
7572                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7573                        // XXX also need to send this to stopped users(!!!)
7574                        broadcastIntentLocked(null, null, intent, null, finisher,
7575                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7576                                UserHandle.USER_ALL);
7577                        if (finisher != null) {
7578                            mWaitingUpdate = true;
7579                        }
7580                    }
7581                }
7582                if (mWaitingUpdate) {
7583                    return;
7584                }
7585                mDidUpdate = true;
7586            }
7587
7588            mSystemReady = true;
7589            if (!mStartRunning) {
7590                return;
7591            }
7592        }
7593
7594        ArrayList<ProcessRecord> procsToKill = null;
7595        synchronized(mPidsSelfLocked) {
7596            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7597                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7598                if (!isAllowedWhileBooting(proc.info)){
7599                    if (procsToKill == null) {
7600                        procsToKill = new ArrayList<ProcessRecord>();
7601                    }
7602                    procsToKill.add(proc);
7603                }
7604            }
7605        }
7606
7607        synchronized(this) {
7608            if (procsToKill != null) {
7609                for (int i=procsToKill.size()-1; i>=0; i--) {
7610                    ProcessRecord proc = procsToKill.get(i);
7611                    Slog.i(TAG, "Removing system update proc: " + proc);
7612                    removeProcessLocked(proc, true, false, "system update done");
7613                }
7614            }
7615
7616            // Now that we have cleaned up any update processes, we
7617            // are ready to start launching real processes and know that
7618            // we won't trample on them any more.
7619            mProcessesReady = true;
7620        }
7621
7622        Slog.i(TAG, "System now ready");
7623        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7624            SystemClock.uptimeMillis());
7625
7626        synchronized(this) {
7627            // Make sure we have no pre-ready processes sitting around.
7628
7629            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7630                ResolveInfo ri = mContext.getPackageManager()
7631                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7632                                STOCK_PM_FLAGS);
7633                CharSequence errorMsg = null;
7634                if (ri != null) {
7635                    ActivityInfo ai = ri.activityInfo;
7636                    ApplicationInfo app = ai.applicationInfo;
7637                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7638                        mTopAction = Intent.ACTION_FACTORY_TEST;
7639                        mTopData = null;
7640                        mTopComponent = new ComponentName(app.packageName,
7641                                ai.name);
7642                    } else {
7643                        errorMsg = mContext.getResources().getText(
7644                                com.android.internal.R.string.factorytest_not_system);
7645                    }
7646                } else {
7647                    errorMsg = mContext.getResources().getText(
7648                            com.android.internal.R.string.factorytest_no_action);
7649                }
7650                if (errorMsg != null) {
7651                    mTopAction = null;
7652                    mTopData = null;
7653                    mTopComponent = null;
7654                    Message msg = Message.obtain();
7655                    msg.what = SHOW_FACTORY_ERROR_MSG;
7656                    msg.getData().putCharSequence("msg", errorMsg);
7657                    mHandler.sendMessage(msg);
7658                }
7659            }
7660        }
7661
7662        retrieveSettings();
7663
7664        if (goingCallback != null) goingCallback.run();
7665
7666        synchronized (this) {
7667            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7668                try {
7669                    List apps = AppGlobals.getPackageManager().
7670                        getPersistentApplications(STOCK_PM_FLAGS);
7671                    if (apps != null) {
7672                        int N = apps.size();
7673                        int i;
7674                        for (i=0; i<N; i++) {
7675                            ApplicationInfo info
7676                                = (ApplicationInfo)apps.get(i);
7677                            if (info != null &&
7678                                    !info.packageName.equals("android")) {
7679                                addAppLocked(info, false);
7680                            }
7681                        }
7682                    }
7683                } catch (RemoteException ex) {
7684                    // pm is in same process, this will never happen.
7685                }
7686            }
7687
7688            // Start up initial activity.
7689            mBooting = true;
7690
7691            try {
7692                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7693                    Message msg = Message.obtain();
7694                    msg.what = SHOW_UID_ERROR_MSG;
7695                    mHandler.sendMessage(msg);
7696                }
7697            } catch (RemoteException e) {
7698            }
7699
7700            mMainStack.resumeTopActivityLocked(null);
7701        }
7702    }
7703
7704    private boolean makeAppCrashingLocked(ProcessRecord app,
7705            String shortMsg, String longMsg, String stackTrace) {
7706        app.crashing = true;
7707        app.crashingReport = generateProcessError(app,
7708                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7709        startAppProblemLocked(app);
7710        app.stopFreezingAllLocked();
7711        return handleAppCrashLocked(app);
7712    }
7713
7714    private void makeAppNotRespondingLocked(ProcessRecord app,
7715            String activity, String shortMsg, String longMsg) {
7716        app.notResponding = true;
7717        app.notRespondingReport = generateProcessError(app,
7718                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7719                activity, shortMsg, longMsg, null);
7720        startAppProblemLocked(app);
7721        app.stopFreezingAllLocked();
7722    }
7723
7724    /**
7725     * Generate a process error record, suitable for attachment to a ProcessRecord.
7726     *
7727     * @param app The ProcessRecord in which the error occurred.
7728     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7729     *                      ActivityManager.AppErrorStateInfo
7730     * @param activity The activity associated with the crash, if known.
7731     * @param shortMsg Short message describing the crash.
7732     * @param longMsg Long message describing the crash.
7733     * @param stackTrace Full crash stack trace, may be null.
7734     *
7735     * @return Returns a fully-formed AppErrorStateInfo record.
7736     */
7737    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7738            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7739        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7740
7741        report.condition = condition;
7742        report.processName = app.processName;
7743        report.pid = app.pid;
7744        report.uid = app.info.uid;
7745        report.tag = activity;
7746        report.shortMsg = shortMsg;
7747        report.longMsg = longMsg;
7748        report.stackTrace = stackTrace;
7749
7750        return report;
7751    }
7752
7753    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7754        synchronized (this) {
7755            app.crashing = false;
7756            app.crashingReport = null;
7757            app.notResponding = false;
7758            app.notRespondingReport = null;
7759            if (app.anrDialog == fromDialog) {
7760                app.anrDialog = null;
7761            }
7762            if (app.waitDialog == fromDialog) {
7763                app.waitDialog = null;
7764            }
7765            if (app.pid > 0 && app.pid != MY_PID) {
7766                handleAppCrashLocked(app);
7767                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7768                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7769                        app.processName, app.setAdj, "user's request after error");
7770                Process.killProcessQuiet(app.pid);
7771            }
7772        }
7773    }
7774
7775    private boolean handleAppCrashLocked(ProcessRecord app) {
7776        if (mHeadless) {
7777            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7778            return false;
7779        }
7780        long now = SystemClock.uptimeMillis();
7781
7782        Long crashTime;
7783        if (!app.isolated) {
7784            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7785        } else {
7786            crashTime = null;
7787        }
7788        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7789            // This process loses!
7790            Slog.w(TAG, "Process " + app.info.processName
7791                    + " has crashed too many times: killing!");
7792            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7793                    app.info.processName, app.uid);
7794            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7795                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7796                if (r.app == app) {
7797                    Slog.w(TAG, "  Force finishing activity "
7798                        + r.intent.getComponent().flattenToShortString());
7799                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7800                }
7801            }
7802            if (!app.persistent) {
7803                // We don't want to start this process again until the user
7804                // explicitly does so...  but for persistent process, we really
7805                // need to keep it running.  If a persistent process is actually
7806                // repeatedly crashing, then badness for everyone.
7807                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7808                        app.info.processName);
7809                if (!app.isolated) {
7810                    // XXX We don't have a way to mark isolated processes
7811                    // as bad, since they don't have a peristent identity.
7812                    mBadProcesses.put(app.info.processName, app.uid, now);
7813                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7814                }
7815                app.bad = true;
7816                app.removed = true;
7817                // Don't let services in this process be restarted and potentially
7818                // annoy the user repeatedly.  Unless it is persistent, since those
7819                // processes run critical code.
7820                removeProcessLocked(app, false, false, "crash");
7821                mMainStack.resumeTopActivityLocked(null);
7822                return false;
7823            }
7824            mMainStack.resumeTopActivityLocked(null);
7825        } else {
7826            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7827            if (r != null && r.app == app) {
7828                // If the top running activity is from this crashing
7829                // process, then terminate it to avoid getting in a loop.
7830                Slog.w(TAG, "  Force finishing activity "
7831                        + r.intent.getComponent().flattenToShortString());
7832                int index = mMainStack.indexOfActivityLocked(r);
7833                r.stack.finishActivityLocked(r, index,
7834                        Activity.RESULT_CANCELED, null, "crashed");
7835                // Also terminate any activities below it that aren't yet
7836                // stopped, to avoid a situation where one will get
7837                // re-start our crashing activity once it gets resumed again.
7838                index--;
7839                if (index >= 0) {
7840                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7841                    if (r.state == ActivityState.RESUMED
7842                            || r.state == ActivityState.PAUSING
7843                            || r.state == ActivityState.PAUSED) {
7844                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7845                            Slog.w(TAG, "  Force finishing activity "
7846                                    + r.intent.getComponent().flattenToShortString());
7847                            r.stack.finishActivityLocked(r, index,
7848                                    Activity.RESULT_CANCELED, null, "crashed");
7849                        }
7850                    }
7851                }
7852            }
7853        }
7854
7855        // Bump up the crash count of any services currently running in the proc.
7856        if (app.services.size() != 0) {
7857            // Any services running in the application need to be placed
7858            // back in the pending list.
7859            Iterator<ServiceRecord> it = app.services.iterator();
7860            while (it.hasNext()) {
7861                ServiceRecord sr = it.next();
7862                sr.crashCount++;
7863            }
7864        }
7865
7866        // If the crashing process is what we consider to be the "home process" and it has been
7867        // replaced by a third-party app, clear the package preferred activities from packages
7868        // with a home activity running in the process to prevent a repeatedly crashing app
7869        // from blocking the user to manually clear the list.
7870        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7871                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7872            Iterator it = mHomeProcess.activities.iterator();
7873            while (it.hasNext()) {
7874                ActivityRecord r = (ActivityRecord)it.next();
7875                if (r.isHomeActivity) {
7876                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7877                    try {
7878                        ActivityThread.getPackageManager()
7879                                .clearPackagePreferredActivities(r.packageName);
7880                    } catch (RemoteException c) {
7881                        // pm is in same process, this will never happen.
7882                    }
7883                }
7884            }
7885        }
7886
7887        if (!app.isolated) {
7888            // XXX Can't keep track of crash times for isolated processes,
7889            // because they don't have a perisistent identity.
7890            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7891        }
7892
7893        return true;
7894    }
7895
7896    void startAppProblemLocked(ProcessRecord app) {
7897        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7898                mContext, app.info.packageName, app.info.flags);
7899        skipCurrentReceiverLocked(app);
7900    }
7901
7902    void skipCurrentReceiverLocked(ProcessRecord app) {
7903        for (BroadcastQueue queue : mBroadcastQueues) {
7904            queue.skipCurrentReceiverLocked(app);
7905        }
7906    }
7907
7908    /**
7909     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7910     * The application process will exit immediately after this call returns.
7911     * @param app object of the crashing app, null for the system server
7912     * @param crashInfo describing the exception
7913     */
7914    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7915        ProcessRecord r = findAppProcess(app, "Crash");
7916        final String processName = app == null ? "system_server"
7917                : (r == null ? "unknown" : r.processName);
7918
7919        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7920                processName,
7921                r == null ? -1 : r.info.flags,
7922                crashInfo.exceptionClassName,
7923                crashInfo.exceptionMessage,
7924                crashInfo.throwFileName,
7925                crashInfo.throwLineNumber);
7926
7927        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7928
7929        crashApplication(r, crashInfo);
7930    }
7931
7932    public void handleApplicationStrictModeViolation(
7933            IBinder app,
7934            int violationMask,
7935            StrictMode.ViolationInfo info) {
7936        ProcessRecord r = findAppProcess(app, "StrictMode");
7937        if (r == null) {
7938            return;
7939        }
7940
7941        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7942            Integer stackFingerprint = info.hashCode();
7943            boolean logIt = true;
7944            synchronized (mAlreadyLoggedViolatedStacks) {
7945                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7946                    logIt = false;
7947                    // TODO: sub-sample into EventLog for these, with
7948                    // the info.durationMillis?  Then we'd get
7949                    // the relative pain numbers, without logging all
7950                    // the stack traces repeatedly.  We'd want to do
7951                    // likewise in the client code, which also does
7952                    // dup suppression, before the Binder call.
7953                } else {
7954                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7955                        mAlreadyLoggedViolatedStacks.clear();
7956                    }
7957                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7958                }
7959            }
7960            if (logIt) {
7961                logStrictModeViolationToDropBox(r, info);
7962            }
7963        }
7964
7965        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7966            AppErrorResult result = new AppErrorResult();
7967            synchronized (this) {
7968                final long origId = Binder.clearCallingIdentity();
7969
7970                Message msg = Message.obtain();
7971                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7972                HashMap<String, Object> data = new HashMap<String, Object>();
7973                data.put("result", result);
7974                data.put("app", r);
7975                data.put("violationMask", violationMask);
7976                data.put("info", info);
7977                msg.obj = data;
7978                mHandler.sendMessage(msg);
7979
7980                Binder.restoreCallingIdentity(origId);
7981            }
7982            int res = result.get();
7983            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7984        }
7985    }
7986
7987    // Depending on the policy in effect, there could be a bunch of
7988    // these in quick succession so we try to batch these together to
7989    // minimize disk writes, number of dropbox entries, and maximize
7990    // compression, by having more fewer, larger records.
7991    private void logStrictModeViolationToDropBox(
7992            ProcessRecord process,
7993            StrictMode.ViolationInfo info) {
7994        if (info == null) {
7995            return;
7996        }
7997        final boolean isSystemApp = process == null ||
7998                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7999                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8000        final String processName = process == null ? "unknown" : process.processName;
8001        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8002        final DropBoxManager dbox = (DropBoxManager)
8003                mContext.getSystemService(Context.DROPBOX_SERVICE);
8004
8005        // Exit early if the dropbox isn't configured to accept this report type.
8006        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8007
8008        boolean bufferWasEmpty;
8009        boolean needsFlush;
8010        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8011        synchronized (sb) {
8012            bufferWasEmpty = sb.length() == 0;
8013            appendDropBoxProcessHeaders(process, processName, sb);
8014            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8015            sb.append("System-App: ").append(isSystemApp).append("\n");
8016            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8017            if (info.violationNumThisLoop != 0) {
8018                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8019            }
8020            if (info.numAnimationsRunning != 0) {
8021                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8022            }
8023            if (info.broadcastIntentAction != null) {
8024                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8025            }
8026            if (info.durationMillis != -1) {
8027                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8028            }
8029            if (info.numInstances != -1) {
8030                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8031            }
8032            if (info.tags != null) {
8033                for (String tag : info.tags) {
8034                    sb.append("Span-Tag: ").append(tag).append("\n");
8035                }
8036            }
8037            sb.append("\n");
8038            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8039                sb.append(info.crashInfo.stackTrace);
8040            }
8041            sb.append("\n");
8042
8043            // Only buffer up to ~64k.  Various logging bits truncate
8044            // things at 128k.
8045            needsFlush = (sb.length() > 64 * 1024);
8046        }
8047
8048        // Flush immediately if the buffer's grown too large, or this
8049        // is a non-system app.  Non-system apps are isolated with a
8050        // different tag & policy and not batched.
8051        //
8052        // Batching is useful during internal testing with
8053        // StrictMode settings turned up high.  Without batching,
8054        // thousands of separate files could be created on boot.
8055        if (!isSystemApp || needsFlush) {
8056            new Thread("Error dump: " + dropboxTag) {
8057                @Override
8058                public void run() {
8059                    String report;
8060                    synchronized (sb) {
8061                        report = sb.toString();
8062                        sb.delete(0, sb.length());
8063                        sb.trimToSize();
8064                    }
8065                    if (report.length() != 0) {
8066                        dbox.addText(dropboxTag, report);
8067                    }
8068                }
8069            }.start();
8070            return;
8071        }
8072
8073        // System app batching:
8074        if (!bufferWasEmpty) {
8075            // An existing dropbox-writing thread is outstanding, so
8076            // we don't need to start it up.  The existing thread will
8077            // catch the buffer appends we just did.
8078            return;
8079        }
8080
8081        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8082        // (After this point, we shouldn't access AMS internal data structures.)
8083        new Thread("Error dump: " + dropboxTag) {
8084            @Override
8085            public void run() {
8086                // 5 second sleep to let stacks arrive and be batched together
8087                try {
8088                    Thread.sleep(5000);  // 5 seconds
8089                } catch (InterruptedException e) {}
8090
8091                String errorReport;
8092                synchronized (mStrictModeBuffer) {
8093                    errorReport = mStrictModeBuffer.toString();
8094                    if (errorReport.length() == 0) {
8095                        return;
8096                    }
8097                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8098                    mStrictModeBuffer.trimToSize();
8099                }
8100                dbox.addText(dropboxTag, errorReport);
8101            }
8102        }.start();
8103    }
8104
8105    /**
8106     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8107     * @param app object of the crashing app, null for the system server
8108     * @param tag reported by the caller
8109     * @param crashInfo describing the context of the error
8110     * @return true if the process should exit immediately (WTF is fatal)
8111     */
8112    public boolean handleApplicationWtf(IBinder app, String tag,
8113            ApplicationErrorReport.CrashInfo crashInfo) {
8114        ProcessRecord r = findAppProcess(app, "WTF");
8115        final String processName = app == null ? "system_server"
8116                : (r == null ? "unknown" : r.processName);
8117
8118        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8119                processName,
8120                r == null ? -1 : r.info.flags,
8121                tag, crashInfo.exceptionMessage);
8122
8123        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8124
8125        if (r != null && r.pid != Process.myPid() &&
8126                Settings.Secure.getInt(mContext.getContentResolver(),
8127                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8128            crashApplication(r, crashInfo);
8129            return true;
8130        } else {
8131            return false;
8132        }
8133    }
8134
8135    /**
8136     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8137     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8138     */
8139    private ProcessRecord findAppProcess(IBinder app, String reason) {
8140        if (app == null) {
8141            return null;
8142        }
8143
8144        synchronized (this) {
8145            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8146                final int NA = apps.size();
8147                for (int ia=0; ia<NA; ia++) {
8148                    ProcessRecord p = apps.valueAt(ia);
8149                    if (p.thread != null && p.thread.asBinder() == app) {
8150                        return p;
8151                    }
8152                }
8153            }
8154
8155            Slog.w(TAG, "Can't find mystery application for " + reason
8156                    + " from pid=" + Binder.getCallingPid()
8157                    + " uid=" + Binder.getCallingUid() + ": " + app);
8158            return null;
8159        }
8160    }
8161
8162    /**
8163     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8164     * to append various headers to the dropbox log text.
8165     */
8166    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8167            StringBuilder sb) {
8168        // Watchdog thread ends up invoking this function (with
8169        // a null ProcessRecord) to add the stack file to dropbox.
8170        // Do not acquire a lock on this (am) in such cases, as it
8171        // could cause a potential deadlock, if and when watchdog
8172        // is invoked due to unavailability of lock on am and it
8173        // would prevent watchdog from killing system_server.
8174        if (process == null) {
8175            sb.append("Process: ").append(processName).append("\n");
8176            return;
8177        }
8178        // Note: ProcessRecord 'process' is guarded by the service
8179        // instance.  (notably process.pkgList, which could otherwise change
8180        // concurrently during execution of this method)
8181        synchronized (this) {
8182            sb.append("Process: ").append(processName).append("\n");
8183            int flags = process.info.flags;
8184            IPackageManager pm = AppGlobals.getPackageManager();
8185            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8186            for (String pkg : process.pkgList) {
8187                sb.append("Package: ").append(pkg);
8188                try {
8189                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8190                    if (pi != null) {
8191                        sb.append(" v").append(pi.versionCode);
8192                        if (pi.versionName != null) {
8193                            sb.append(" (").append(pi.versionName).append(")");
8194                        }
8195                    }
8196                } catch (RemoteException e) {
8197                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8198                }
8199                sb.append("\n");
8200            }
8201        }
8202    }
8203
8204    private static String processClass(ProcessRecord process) {
8205        if (process == null || process.pid == MY_PID) {
8206            return "system_server";
8207        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8208            return "system_app";
8209        } else {
8210            return "data_app";
8211        }
8212    }
8213
8214    /**
8215     * Write a description of an error (crash, WTF, ANR) to the drop box.
8216     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8217     * @param process which caused the error, null means the system server
8218     * @param activity which triggered the error, null if unknown
8219     * @param parent activity related to the error, null if unknown
8220     * @param subject line related to the error, null if absent
8221     * @param report in long form describing the error, null if absent
8222     * @param logFile to include in the report, null if none
8223     * @param crashInfo giving an application stack trace, null if absent
8224     */
8225    public void addErrorToDropBox(String eventType,
8226            ProcessRecord process, String processName, ActivityRecord activity,
8227            ActivityRecord parent, String subject,
8228            final String report, final File logFile,
8229            final ApplicationErrorReport.CrashInfo crashInfo) {
8230        // NOTE -- this must never acquire the ActivityManagerService lock,
8231        // otherwise the watchdog may be prevented from resetting the system.
8232
8233        final String dropboxTag = processClass(process) + "_" + eventType;
8234        final DropBoxManager dbox = (DropBoxManager)
8235                mContext.getSystemService(Context.DROPBOX_SERVICE);
8236
8237        // Exit early if the dropbox isn't configured to accept this report type.
8238        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8239
8240        final StringBuilder sb = new StringBuilder(1024);
8241        appendDropBoxProcessHeaders(process, processName, sb);
8242        if (activity != null) {
8243            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8244        }
8245        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8246            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8247        }
8248        if (parent != null && parent != activity) {
8249            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8250        }
8251        if (subject != null) {
8252            sb.append("Subject: ").append(subject).append("\n");
8253        }
8254        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8255        if (Debug.isDebuggerConnected()) {
8256            sb.append("Debugger: Connected\n");
8257        }
8258        sb.append("\n");
8259
8260        // Do the rest in a worker thread to avoid blocking the caller on I/O
8261        // (After this point, we shouldn't access AMS internal data structures.)
8262        Thread worker = new Thread("Error dump: " + dropboxTag) {
8263            @Override
8264            public void run() {
8265                if (report != null) {
8266                    sb.append(report);
8267                }
8268                if (logFile != null) {
8269                    try {
8270                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8271                    } catch (IOException e) {
8272                        Slog.e(TAG, "Error reading " + logFile, e);
8273                    }
8274                }
8275                if (crashInfo != null && crashInfo.stackTrace != null) {
8276                    sb.append(crashInfo.stackTrace);
8277                }
8278
8279                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8280                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8281                if (lines > 0) {
8282                    sb.append("\n");
8283
8284                    // Merge several logcat streams, and take the last N lines
8285                    InputStreamReader input = null;
8286                    try {
8287                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8288                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8289                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8290
8291                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8292                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8293                        input = new InputStreamReader(logcat.getInputStream());
8294
8295                        int num;
8296                        char[] buf = new char[8192];
8297                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8298                    } catch (IOException e) {
8299                        Slog.e(TAG, "Error running logcat", e);
8300                    } finally {
8301                        if (input != null) try { input.close(); } catch (IOException e) {}
8302                    }
8303                }
8304
8305                dbox.addText(dropboxTag, sb.toString());
8306            }
8307        };
8308
8309        if (process == null) {
8310            // If process is null, we are being called from some internal code
8311            // and may be about to die -- run this synchronously.
8312            worker.run();
8313        } else {
8314            worker.start();
8315        }
8316    }
8317
8318    /**
8319     * Bring up the "unexpected error" dialog box for a crashing app.
8320     * Deal with edge cases (intercepts from instrumented applications,
8321     * ActivityController, error intent receivers, that sort of thing).
8322     * @param r the application crashing
8323     * @param crashInfo describing the failure
8324     */
8325    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8326        long timeMillis = System.currentTimeMillis();
8327        String shortMsg = crashInfo.exceptionClassName;
8328        String longMsg = crashInfo.exceptionMessage;
8329        String stackTrace = crashInfo.stackTrace;
8330        if (shortMsg != null && longMsg != null) {
8331            longMsg = shortMsg + ": " + longMsg;
8332        } else if (shortMsg != null) {
8333            longMsg = shortMsg;
8334        }
8335
8336        AppErrorResult result = new AppErrorResult();
8337        synchronized (this) {
8338            if (mController != null) {
8339                try {
8340                    String name = r != null ? r.processName : null;
8341                    int pid = r != null ? r.pid : Binder.getCallingPid();
8342                    if (!mController.appCrashed(name, pid,
8343                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8344                        Slog.w(TAG, "Force-killing crashed app " + name
8345                                + " at watcher's request");
8346                        Process.killProcess(pid);
8347                        return;
8348                    }
8349                } catch (RemoteException e) {
8350                    mController = null;
8351                }
8352            }
8353
8354            final long origId = Binder.clearCallingIdentity();
8355
8356            // If this process is running instrumentation, finish it.
8357            if (r != null && r.instrumentationClass != null) {
8358                Slog.w(TAG, "Error in app " + r.processName
8359                      + " running instrumentation " + r.instrumentationClass + ":");
8360                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8361                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8362                Bundle info = new Bundle();
8363                info.putString("shortMsg", shortMsg);
8364                info.putString("longMsg", longMsg);
8365                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8366                Binder.restoreCallingIdentity(origId);
8367                return;
8368            }
8369
8370            // If we can't identify the process or it's already exceeded its crash quota,
8371            // quit right away without showing a crash dialog.
8372            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8373                Binder.restoreCallingIdentity(origId);
8374                return;
8375            }
8376
8377            Message msg = Message.obtain();
8378            msg.what = SHOW_ERROR_MSG;
8379            HashMap data = new HashMap();
8380            data.put("result", result);
8381            data.put("app", r);
8382            msg.obj = data;
8383            mHandler.sendMessage(msg);
8384
8385            Binder.restoreCallingIdentity(origId);
8386        }
8387
8388        int res = result.get();
8389
8390        Intent appErrorIntent = null;
8391        synchronized (this) {
8392            if (r != null && !r.isolated) {
8393                // XXX Can't keep track of crash time for isolated processes,
8394                // since they don't have a persistent identity.
8395                mProcessCrashTimes.put(r.info.processName, r.uid,
8396                        SystemClock.uptimeMillis());
8397            }
8398            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8399                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8400            }
8401        }
8402
8403        if (appErrorIntent != null) {
8404            try {
8405                mContext.startActivity(appErrorIntent);
8406            } catch (ActivityNotFoundException e) {
8407                Slog.w(TAG, "bug report receiver dissappeared", e);
8408            }
8409        }
8410    }
8411
8412    Intent createAppErrorIntentLocked(ProcessRecord r,
8413            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8414        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8415        if (report == null) {
8416            return null;
8417        }
8418        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8419        result.setComponent(r.errorReportReceiver);
8420        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8421        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8422        return result;
8423    }
8424
8425    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8426            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8427        if (r.errorReportReceiver == null) {
8428            return null;
8429        }
8430
8431        if (!r.crashing && !r.notResponding) {
8432            return null;
8433        }
8434
8435        ApplicationErrorReport report = new ApplicationErrorReport();
8436        report.packageName = r.info.packageName;
8437        report.installerPackageName = r.errorReportReceiver.getPackageName();
8438        report.processName = r.processName;
8439        report.time = timeMillis;
8440        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8441
8442        if (r.crashing) {
8443            report.type = ApplicationErrorReport.TYPE_CRASH;
8444            report.crashInfo = crashInfo;
8445        } else if (r.notResponding) {
8446            report.type = ApplicationErrorReport.TYPE_ANR;
8447            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8448
8449            report.anrInfo.activity = r.notRespondingReport.tag;
8450            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8451            report.anrInfo.info = r.notRespondingReport.longMsg;
8452        }
8453
8454        return report;
8455    }
8456
8457    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8458        enforceNotIsolatedCaller("getProcessesInErrorState");
8459        // assume our apps are happy - lazy create the list
8460        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8461
8462        final boolean allUsers = ActivityManager.checkUidPermission(
8463                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8464                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8465        int userId = UserHandle.getUserId(Binder.getCallingUid());
8466
8467        synchronized (this) {
8468
8469            // iterate across all processes
8470            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8471                ProcessRecord app = mLruProcesses.get(i);
8472                if (!allUsers && app.userId != userId) {
8473                    continue;
8474                }
8475                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8476                    // This one's in trouble, so we'll generate a report for it
8477                    // crashes are higher priority (in case there's a crash *and* an anr)
8478                    ActivityManager.ProcessErrorStateInfo report = null;
8479                    if (app.crashing) {
8480                        report = app.crashingReport;
8481                    } else if (app.notResponding) {
8482                        report = app.notRespondingReport;
8483                    }
8484
8485                    if (report != null) {
8486                        if (errList == null) {
8487                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8488                        }
8489                        errList.add(report);
8490                    } else {
8491                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8492                                " crashing = " + app.crashing +
8493                                " notResponding = " + app.notResponding);
8494                    }
8495                }
8496            }
8497        }
8498
8499        return errList;
8500    }
8501
8502    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8503        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8504            if (currApp != null) {
8505                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8506            }
8507            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8508        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8509            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8510        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8511            if (currApp != null) {
8512                currApp.lru = 0;
8513            }
8514            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8515        } else if (adj >= ProcessList.SERVICE_ADJ) {
8516            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8517        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8518            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8519        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8520            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8521        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8522            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8523        } else {
8524            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8525        }
8526    }
8527
8528    private void fillInProcMemInfo(ProcessRecord app,
8529            ActivityManager.RunningAppProcessInfo outInfo) {
8530        outInfo.pid = app.pid;
8531        outInfo.uid = app.info.uid;
8532        if (mHeavyWeightProcess == app) {
8533            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8534        }
8535        if (app.persistent) {
8536            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8537        }
8538        if (app.hasActivities) {
8539            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8540        }
8541        outInfo.lastTrimLevel = app.trimMemoryLevel;
8542        int adj = app.curAdj;
8543        outInfo.importance = oomAdjToImportance(adj, outInfo);
8544        outInfo.importanceReasonCode = app.adjTypeCode;
8545    }
8546
8547    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8548        enforceNotIsolatedCaller("getRunningAppProcesses");
8549        // Lazy instantiation of list
8550        List<ActivityManager.RunningAppProcessInfo> runList = null;
8551        final boolean allUsers = ActivityManager.checkUidPermission(
8552                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8553                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8554        int userId = UserHandle.getUserId(Binder.getCallingUid());
8555        synchronized (this) {
8556            // Iterate across all processes
8557            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8558                ProcessRecord app = mLruProcesses.get(i);
8559                if (!allUsers && app.userId != userId) {
8560                    continue;
8561                }
8562                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8563                    // Generate process state info for running application
8564                    ActivityManager.RunningAppProcessInfo currApp =
8565                        new ActivityManager.RunningAppProcessInfo(app.processName,
8566                                app.pid, app.getPackageList());
8567                    fillInProcMemInfo(app, currApp);
8568                    if (app.adjSource instanceof ProcessRecord) {
8569                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8570                        currApp.importanceReasonImportance = oomAdjToImportance(
8571                                app.adjSourceOom, null);
8572                    } else if (app.adjSource instanceof ActivityRecord) {
8573                        ActivityRecord r = (ActivityRecord)app.adjSource;
8574                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8575                    }
8576                    if (app.adjTarget instanceof ComponentName) {
8577                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8578                    }
8579                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8580                    //        + " lru=" + currApp.lru);
8581                    if (runList == null) {
8582                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8583                    }
8584                    runList.add(currApp);
8585                }
8586            }
8587        }
8588        return runList;
8589    }
8590
8591    public List<ApplicationInfo> getRunningExternalApplications() {
8592        enforceNotIsolatedCaller("getRunningExternalApplications");
8593        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8594        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8595        if (runningApps != null && runningApps.size() > 0) {
8596            Set<String> extList = new HashSet<String>();
8597            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8598                if (app.pkgList != null) {
8599                    for (String pkg : app.pkgList) {
8600                        extList.add(pkg);
8601                    }
8602                }
8603            }
8604            IPackageManager pm = AppGlobals.getPackageManager();
8605            for (String pkg : extList) {
8606                try {
8607                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8608                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8609                        retList.add(info);
8610                    }
8611                } catch (RemoteException e) {
8612                }
8613            }
8614        }
8615        return retList;
8616    }
8617
8618    @Override
8619    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8620        enforceNotIsolatedCaller("getMyMemoryState");
8621        synchronized (this) {
8622            ProcessRecord proc;
8623            synchronized (mPidsSelfLocked) {
8624                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8625            }
8626            fillInProcMemInfo(proc, outInfo);
8627        }
8628    }
8629
8630    @Override
8631    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8632        if (checkCallingPermission(android.Manifest.permission.DUMP)
8633                != PackageManager.PERMISSION_GRANTED) {
8634            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8635                    + Binder.getCallingPid()
8636                    + ", uid=" + Binder.getCallingUid()
8637                    + " without permission "
8638                    + android.Manifest.permission.DUMP);
8639            return;
8640        }
8641
8642        boolean dumpAll = false;
8643        boolean dumpClient = false;
8644        String dumpPackage = null;
8645
8646        int opti = 0;
8647        while (opti < args.length) {
8648            String opt = args[opti];
8649            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8650                break;
8651            }
8652            opti++;
8653            if ("-a".equals(opt)) {
8654                dumpAll = true;
8655            } else if ("-c".equals(opt)) {
8656                dumpClient = true;
8657            } else if ("-h".equals(opt)) {
8658                pw.println("Activity manager dump options:");
8659                pw.println("  [-a] [-c] [-h] [cmd] ...");
8660                pw.println("  cmd may be one of:");
8661                pw.println("    a[ctivities]: activity stack state");
8662                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8663                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8664                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8665                pw.println("    o[om]: out of memory management");
8666                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8667                pw.println("    provider [COMP_SPEC]: provider client-side state");
8668                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8669                pw.println("    service [COMP_SPEC]: service client-side state");
8670                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8671                pw.println("    all: dump all activities");
8672                pw.println("    top: dump the top activity");
8673                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8674                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8675                pw.println("    a partial substring in a component name, a");
8676                pw.println("    hex object identifier.");
8677                pw.println("  -a: include all available server state.");
8678                pw.println("  -c: include client state.");
8679                return;
8680            } else {
8681                pw.println("Unknown argument: " + opt + "; use -h for help");
8682            }
8683        }
8684
8685        long origId = Binder.clearCallingIdentity();
8686        boolean more = false;
8687        // Is the caller requesting to dump a particular piece of data?
8688        if (opti < args.length) {
8689            String cmd = args[opti];
8690            opti++;
8691            if ("activities".equals(cmd) || "a".equals(cmd)) {
8692                synchronized (this) {
8693                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8694                }
8695            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8696                String[] newArgs;
8697                String name;
8698                if (opti >= args.length) {
8699                    name = null;
8700                    newArgs = EMPTY_STRING_ARRAY;
8701                } else {
8702                    name = args[opti];
8703                    opti++;
8704                    newArgs = new String[args.length - opti];
8705                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8706                            args.length - opti);
8707                }
8708                synchronized (this) {
8709                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8710                }
8711            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8712                String[] newArgs;
8713                String name;
8714                if (opti >= args.length) {
8715                    name = null;
8716                    newArgs = EMPTY_STRING_ARRAY;
8717                } else {
8718                    name = args[opti];
8719                    opti++;
8720                    newArgs = new String[args.length - opti];
8721                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8722                            args.length - opti);
8723                }
8724                synchronized (this) {
8725                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8726                }
8727            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8728                String[] newArgs;
8729                String name;
8730                if (opti >= args.length) {
8731                    name = null;
8732                    newArgs = EMPTY_STRING_ARRAY;
8733                } else {
8734                    name = args[opti];
8735                    opti++;
8736                    newArgs = new String[args.length - opti];
8737                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8738                            args.length - opti);
8739                }
8740                synchronized (this) {
8741                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8742                }
8743            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8744                synchronized (this) {
8745                    dumpOomLocked(fd, pw, args, opti, true);
8746                }
8747            } else if ("provider".equals(cmd)) {
8748                String[] newArgs;
8749                String name;
8750                if (opti >= args.length) {
8751                    name = null;
8752                    newArgs = EMPTY_STRING_ARRAY;
8753                } else {
8754                    name = args[opti];
8755                    opti++;
8756                    newArgs = new String[args.length - opti];
8757                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8758                }
8759                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8760                    pw.println("No providers match: " + name);
8761                    pw.println("Use -h for help.");
8762                }
8763            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8764                synchronized (this) {
8765                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8766                }
8767            } else if ("service".equals(cmd)) {
8768                String[] newArgs;
8769                String name;
8770                if (opti >= args.length) {
8771                    name = null;
8772                    newArgs = EMPTY_STRING_ARRAY;
8773                } else {
8774                    name = args[opti];
8775                    opti++;
8776                    newArgs = new String[args.length - opti];
8777                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8778                            args.length - opti);
8779                }
8780                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8781                    pw.println("No services match: " + name);
8782                    pw.println("Use -h for help.");
8783                }
8784            } else if ("package".equals(cmd)) {
8785                String[] newArgs;
8786                if (opti >= args.length) {
8787                    pw.println("package: no package name specified");
8788                    pw.println("Use -h for help.");
8789                } else {
8790                    dumpPackage = args[opti];
8791                    opti++;
8792                    newArgs = new String[args.length - opti];
8793                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8794                            args.length - opti);
8795                    args = newArgs;
8796                    opti = 0;
8797                    more = true;
8798                }
8799            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8800                synchronized (this) {
8801                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8802                }
8803            } else {
8804                // Dumping a single activity?
8805                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8806                    pw.println("Bad activity command, or no activities match: " + cmd);
8807                    pw.println("Use -h for help.");
8808                }
8809            }
8810            if (!more) {
8811                Binder.restoreCallingIdentity(origId);
8812                return;
8813            }
8814        }
8815
8816        // No piece of data specified, dump everything.
8817        synchronized (this) {
8818            boolean needSep;
8819            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8820            if (needSep) {
8821                pw.println(" ");
8822            }
8823            if (dumpAll) {
8824                pw.println("-------------------------------------------------------------------------------");
8825            }
8826            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8827            if (needSep) {
8828                pw.println(" ");
8829            }
8830            if (dumpAll) {
8831                pw.println("-------------------------------------------------------------------------------");
8832            }
8833            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8834            if (needSep) {
8835                pw.println(" ");
8836            }
8837            if (dumpAll) {
8838                pw.println("-------------------------------------------------------------------------------");
8839            }
8840            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8841            if (needSep) {
8842                pw.println(" ");
8843            }
8844            if (dumpAll) {
8845                pw.println("-------------------------------------------------------------------------------");
8846            }
8847            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8848            if (needSep) {
8849                pw.println(" ");
8850            }
8851            if (dumpAll) {
8852                pw.println("-------------------------------------------------------------------------------");
8853            }
8854            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8855        }
8856        Binder.restoreCallingIdentity(origId);
8857    }
8858
8859    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8860            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8861        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8862        pw.println("  Main stack:");
8863        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8864                dumpPackage);
8865        pw.println(" ");
8866        pw.println("  Running activities (most recent first):");
8867        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8868                dumpPackage);
8869        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8870            pw.println(" ");
8871            pw.println("  Activities waiting for another to become visible:");
8872            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8873                    !dumpAll, false, dumpPackage);
8874        }
8875        if (mMainStack.mStoppingActivities.size() > 0) {
8876            pw.println(" ");
8877            pw.println("  Activities waiting to stop:");
8878            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8879                    !dumpAll, false, dumpPackage);
8880        }
8881        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8882            pw.println(" ");
8883            pw.println("  Activities waiting to sleep:");
8884            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8885                    !dumpAll, false, dumpPackage);
8886        }
8887        if (mMainStack.mFinishingActivities.size() > 0) {
8888            pw.println(" ");
8889            pw.println("  Activities waiting to finish:");
8890            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8891                    !dumpAll, false, dumpPackage);
8892        }
8893
8894        pw.println(" ");
8895        if (mMainStack.mPausingActivity != null) {
8896            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8897        }
8898        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8899        pw.println("  mFocusedActivity: " + mFocusedActivity);
8900        if (dumpAll) {
8901            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8902            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8903            pw.println("  mDismissKeyguardOnNextActivity: "
8904                    + mMainStack.mDismissKeyguardOnNextActivity);
8905        }
8906
8907        if (mRecentTasks.size() > 0) {
8908            pw.println();
8909            pw.println("  Recent tasks:");
8910
8911            final int N = mRecentTasks.size();
8912            for (int i=0; i<N; i++) {
8913                TaskRecord tr = mRecentTasks.get(i);
8914                if (dumpPackage != null) {
8915                    if (tr.realActivity == null ||
8916                            !dumpPackage.equals(tr.realActivity)) {
8917                        continue;
8918                    }
8919                }
8920                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8921                        pw.println(tr);
8922                if (dumpAll) {
8923                    mRecentTasks.get(i).dump(pw, "    ");
8924                }
8925            }
8926        }
8927
8928        if (dumpAll) {
8929            pw.println(" ");
8930            pw.println("  mCurTask: " + mCurTask);
8931        }
8932
8933        return true;
8934    }
8935
8936    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8937            int opti, boolean dumpAll, String dumpPackage) {
8938        boolean needSep = false;
8939        int numPers = 0;
8940
8941        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8942
8943        if (dumpAll) {
8944            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8945                final int NA = procs.size();
8946                for (int ia=0; ia<NA; ia++) {
8947                    ProcessRecord r = procs.valueAt(ia);
8948                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8949                        continue;
8950                    }
8951                    if (!needSep) {
8952                        pw.println("  All known processes:");
8953                        needSep = true;
8954                    }
8955                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8956                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8957                        pw.print(" "); pw.println(r);
8958                    r.dump(pw, "    ");
8959                    if (r.persistent) {
8960                        numPers++;
8961                    }
8962                }
8963            }
8964        }
8965
8966        if (mIsolatedProcesses.size() > 0) {
8967            if (needSep) pw.println(" ");
8968            needSep = true;
8969            pw.println("  Isolated process list (sorted by uid):");
8970            for (int i=0; i<mIsolatedProcesses.size(); i++) {
8971                ProcessRecord r = mIsolatedProcesses.valueAt(i);
8972                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8973                    continue;
8974                }
8975                pw.println(String.format("%sIsolated #%2d: %s",
8976                        "    ", i, r.toString()));
8977            }
8978        }
8979
8980        if (mLruProcesses.size() > 0) {
8981            if (needSep) pw.println(" ");
8982            needSep = true;
8983            pw.println("  Process LRU list (sorted by oom_adj):");
8984            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8985                    "Proc", "PERS", false, dumpPackage);
8986            needSep = true;
8987        }
8988
8989        if (dumpAll) {
8990            synchronized (mPidsSelfLocked) {
8991                boolean printed = false;
8992                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8993                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8994                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8995                        continue;
8996                    }
8997                    if (!printed) {
8998                        if (needSep) pw.println(" ");
8999                        needSep = true;
9000                        pw.println("  PID mappings:");
9001                        printed = true;
9002                    }
9003                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9004                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9005                }
9006            }
9007        }
9008
9009        if (mForegroundProcesses.size() > 0) {
9010            synchronized (mPidsSelfLocked) {
9011                boolean printed = false;
9012                for (int i=0; i<mForegroundProcesses.size(); i++) {
9013                    ProcessRecord r = mPidsSelfLocked.get(
9014                            mForegroundProcesses.valueAt(i).pid);
9015                    if (dumpPackage != null && (r == null
9016                            || !dumpPackage.equals(r.info.packageName))) {
9017                        continue;
9018                    }
9019                    if (!printed) {
9020                        if (needSep) pw.println(" ");
9021                        needSep = true;
9022                        pw.println("  Foreground Processes:");
9023                        printed = true;
9024                    }
9025                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9026                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9027                }
9028            }
9029        }
9030
9031        if (mPersistentStartingProcesses.size() > 0) {
9032            if (needSep) pw.println(" ");
9033            needSep = true;
9034            pw.println("  Persisent processes that are starting:");
9035            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9036                    "Starting Norm", "Restarting PERS", dumpPackage);
9037        }
9038
9039        if (mRemovedProcesses.size() > 0) {
9040            if (needSep) pw.println(" ");
9041            needSep = true;
9042            pw.println("  Processes that are being removed:");
9043            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9044                    "Removed Norm", "Removed PERS", dumpPackage);
9045        }
9046
9047        if (mProcessesOnHold.size() > 0) {
9048            if (needSep) pw.println(" ");
9049            needSep = true;
9050            pw.println("  Processes that are on old until the system is ready:");
9051            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9052                    "OnHold Norm", "OnHold PERS", dumpPackage);
9053        }
9054
9055        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9056
9057        if (mProcessCrashTimes.getMap().size() > 0) {
9058            boolean printed = false;
9059            long now = SystemClock.uptimeMillis();
9060            for (Map.Entry<String, SparseArray<Long>> procs
9061                    : mProcessCrashTimes.getMap().entrySet()) {
9062                String pname = procs.getKey();
9063                SparseArray<Long> uids = procs.getValue();
9064                final int N = uids.size();
9065                for (int i=0; i<N; i++) {
9066                    int puid = uids.keyAt(i);
9067                    ProcessRecord r = mProcessNames.get(pname, puid);
9068                    if (dumpPackage != null && (r == null
9069                            || !dumpPackage.equals(r.info.packageName))) {
9070                        continue;
9071                    }
9072                    if (!printed) {
9073                        if (needSep) pw.println(" ");
9074                        needSep = true;
9075                        pw.println("  Time since processes crashed:");
9076                        printed = true;
9077                    }
9078                    pw.print("    Process "); pw.print(pname);
9079                            pw.print(" uid "); pw.print(puid);
9080                            pw.print(": last crashed ");
9081                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9082                            pw.println(" ago");
9083                }
9084            }
9085        }
9086
9087        if (mBadProcesses.getMap().size() > 0) {
9088            boolean printed = false;
9089            for (Map.Entry<String, SparseArray<Long>> procs
9090                    : mBadProcesses.getMap().entrySet()) {
9091                String pname = procs.getKey();
9092                SparseArray<Long> uids = procs.getValue();
9093                final int N = uids.size();
9094                for (int i=0; i<N; i++) {
9095                    int puid = uids.keyAt(i);
9096                    ProcessRecord r = mProcessNames.get(pname, puid);
9097                    if (dumpPackage != null && (r == null
9098                            || !dumpPackage.equals(r.info.packageName))) {
9099                        continue;
9100                    }
9101                    if (!printed) {
9102                        if (needSep) pw.println(" ");
9103                        needSep = true;
9104                        pw.println("  Bad processes:");
9105                    }
9106                    pw.print("    Bad process "); pw.print(pname);
9107                            pw.print(" uid "); pw.print(puid);
9108                            pw.print(": crashed at time ");
9109                            pw.println(uids.valueAt(i));
9110                }
9111            }
9112        }
9113
9114        pw.println();
9115        pw.println("  mStartedUsers:");
9116        for (int i=0; i<mStartedUsers.size(); i++) {
9117            UserStartedState uss = mStartedUsers.valueAt(i);
9118            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9119                    pw.println(":");
9120            uss.dump("      ", pw);
9121        }
9122        pw.println("  mHomeProcess: " + mHomeProcess);
9123        pw.println("  mPreviousProcess: " + mPreviousProcess);
9124        if (dumpAll) {
9125            StringBuilder sb = new StringBuilder(128);
9126            sb.append("  mPreviousProcessVisibleTime: ");
9127            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9128            pw.println(sb);
9129        }
9130        if (mHeavyWeightProcess != null) {
9131            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9132        }
9133        pw.println("  mConfiguration: " + mConfiguration);
9134        if (dumpAll) {
9135            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9136            if (mCompatModePackages.getPackages().size() > 0) {
9137                boolean printed = false;
9138                for (Map.Entry<String, Integer> entry
9139                        : mCompatModePackages.getPackages().entrySet()) {
9140                    String pkg = entry.getKey();
9141                    int mode = entry.getValue();
9142                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9143                        continue;
9144                    }
9145                    if (!printed) {
9146                        pw.println("  mScreenCompatPackages:");
9147                        printed = true;
9148                    }
9149                    pw.print("    "); pw.print(pkg); pw.print(": ");
9150                            pw.print(mode); pw.println();
9151                }
9152            }
9153        }
9154        if (mSleeping || mWentToSleep || mLockScreenShown) {
9155            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9156                    + " mLockScreenShown " + mLockScreenShown);
9157        }
9158        if (mShuttingDown) {
9159            pw.println("  mShuttingDown=" + mShuttingDown);
9160        }
9161        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9162                || mOrigWaitForDebugger) {
9163            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9164                    + " mDebugTransient=" + mDebugTransient
9165                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9166        }
9167        if (mOpenGlTraceApp != null) {
9168            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9169        }
9170        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9171                || mProfileFd != null) {
9172            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9173            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9174            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9175                    + mAutoStopProfiler);
9176        }
9177        if (mAlwaysFinishActivities || mController != null) {
9178            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9179                    + " mController=" + mController);
9180        }
9181        if (dumpAll) {
9182            pw.println("  Total persistent processes: " + numPers);
9183            pw.println("  mStartRunning=" + mStartRunning
9184                    + " mProcessesReady=" + mProcessesReady
9185                    + " mSystemReady=" + mSystemReady);
9186            pw.println("  mBooting=" + mBooting
9187                    + " mBooted=" + mBooted
9188                    + " mFactoryTest=" + mFactoryTest);
9189            pw.print("  mLastPowerCheckRealtime=");
9190                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9191                    pw.println("");
9192            pw.print("  mLastPowerCheckUptime=");
9193                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9194                    pw.println("");
9195            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9196            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9197            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9198            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9199                    + " mNumHiddenProcs=" + mNumHiddenProcs
9200                    + " mNumServiceProcs=" + mNumServiceProcs
9201                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9202        }
9203
9204        return true;
9205    }
9206
9207    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9208            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9209        if (mProcessesToGc.size() > 0) {
9210            boolean printed = false;
9211            long now = SystemClock.uptimeMillis();
9212            for (int i=0; i<mProcessesToGc.size(); i++) {
9213                ProcessRecord proc = mProcessesToGc.get(i);
9214                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9215                    continue;
9216                }
9217                if (!printed) {
9218                    if (needSep) pw.println(" ");
9219                    needSep = true;
9220                    pw.println("  Processes that are waiting to GC:");
9221                    printed = true;
9222                }
9223                pw.print("    Process "); pw.println(proc);
9224                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9225                        pw.print(", last gced=");
9226                        pw.print(now-proc.lastRequestedGc);
9227                        pw.print(" ms ago, last lowMem=");
9228                        pw.print(now-proc.lastLowMemory);
9229                        pw.println(" ms ago");
9230
9231            }
9232        }
9233        return needSep;
9234    }
9235
9236    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9237            int opti, boolean dumpAll) {
9238        boolean needSep = false;
9239
9240        if (mLruProcesses.size() > 0) {
9241            if (needSep) pw.println(" ");
9242            needSep = true;
9243            pw.println("  OOM levels:");
9244            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9245            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9246            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9247            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9248            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9249            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9250            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9251            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9252            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9253            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9254            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9255            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9256            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9257
9258            if (needSep) pw.println(" ");
9259            needSep = true;
9260            pw.println("  Process OOM control:");
9261            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9262                    "Proc", "PERS", true, null);
9263            needSep = true;
9264        }
9265
9266        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9267
9268        pw.println();
9269        pw.println("  mHomeProcess: " + mHomeProcess);
9270        pw.println("  mPreviousProcess: " + mPreviousProcess);
9271        if (mHeavyWeightProcess != null) {
9272            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9273        }
9274
9275        return true;
9276    }
9277
9278    /**
9279     * There are three ways to call this:
9280     *  - no provider specified: dump all the providers
9281     *  - a flattened component name that matched an existing provider was specified as the
9282     *    first arg: dump that one provider
9283     *  - the first arg isn't the flattened component name of an existing provider:
9284     *    dump all providers whose component contains the first arg as a substring
9285     */
9286    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9287            int opti, boolean dumpAll) {
9288        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9289    }
9290
9291    static class ItemMatcher {
9292        ArrayList<ComponentName> components;
9293        ArrayList<String> strings;
9294        ArrayList<Integer> objects;
9295        boolean all;
9296
9297        ItemMatcher() {
9298            all = true;
9299        }
9300
9301        void build(String name) {
9302            ComponentName componentName = ComponentName.unflattenFromString(name);
9303            if (componentName != null) {
9304                if (components == null) {
9305                    components = new ArrayList<ComponentName>();
9306                }
9307                components.add(componentName);
9308                all = false;
9309            } else {
9310                int objectId = 0;
9311                // Not a '/' separated full component name; maybe an object ID?
9312                try {
9313                    objectId = Integer.parseInt(name, 16);
9314                    if (objects == null) {
9315                        objects = new ArrayList<Integer>();
9316                    }
9317                    objects.add(objectId);
9318                    all = false;
9319                } catch (RuntimeException e) {
9320                    // Not an integer; just do string match.
9321                    if (strings == null) {
9322                        strings = new ArrayList<String>();
9323                    }
9324                    strings.add(name);
9325                    all = false;
9326                }
9327            }
9328        }
9329
9330        int build(String[] args, int opti) {
9331            for (; opti<args.length; opti++) {
9332                String name = args[opti];
9333                if ("--".equals(name)) {
9334                    return opti+1;
9335                }
9336                build(name);
9337            }
9338            return opti;
9339        }
9340
9341        boolean match(Object object, ComponentName comp) {
9342            if (all) {
9343                return true;
9344            }
9345            if (components != null) {
9346                for (int i=0; i<components.size(); i++) {
9347                    if (components.get(i).equals(comp)) {
9348                        return true;
9349                    }
9350                }
9351            }
9352            if (objects != null) {
9353                for (int i=0; i<objects.size(); i++) {
9354                    if (System.identityHashCode(object) == objects.get(i)) {
9355                        return true;
9356                    }
9357                }
9358            }
9359            if (strings != null) {
9360                String flat = comp.flattenToString();
9361                for (int i=0; i<strings.size(); i++) {
9362                    if (flat.contains(strings.get(i))) {
9363                        return true;
9364                    }
9365                }
9366            }
9367            return false;
9368        }
9369    }
9370
9371    /**
9372     * There are three things that cmd can be:
9373     *  - a flattened component name that matches an existing activity
9374     *  - the cmd arg isn't the flattened component name of an existing activity:
9375     *    dump all activity whose component contains the cmd as a substring
9376     *  - A hex number of the ActivityRecord object instance.
9377     */
9378    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9379            int opti, boolean dumpAll) {
9380        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9381
9382        if ("all".equals(name)) {
9383            synchronized (this) {
9384                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9385                    activities.add(r1);
9386                }
9387            }
9388        } else if ("top".equals(name)) {
9389            synchronized (this) {
9390                final int N = mMainStack.mHistory.size();
9391                if (N > 0) {
9392                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9393                }
9394            }
9395        } else {
9396            ItemMatcher matcher = new ItemMatcher();
9397            matcher.build(name);
9398
9399            synchronized (this) {
9400                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9401                    if (matcher.match(r1, r1.intent.getComponent())) {
9402                        activities.add(r1);
9403                    }
9404                }
9405            }
9406        }
9407
9408        if (activities.size() <= 0) {
9409            return false;
9410        }
9411
9412        String[] newArgs = new String[args.length - opti];
9413        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9414
9415        TaskRecord lastTask = null;
9416        boolean needSep = false;
9417        for (int i=activities.size()-1; i>=0; i--) {
9418            ActivityRecord r = (ActivityRecord)activities.get(i);
9419            if (needSep) {
9420                pw.println();
9421            }
9422            needSep = true;
9423            synchronized (this) {
9424                if (lastTask != r.task) {
9425                    lastTask = r.task;
9426                    pw.print("TASK "); pw.print(lastTask.affinity);
9427                            pw.print(" id="); pw.println(lastTask.taskId);
9428                    if (dumpAll) {
9429                        lastTask.dump(pw, "  ");
9430                    }
9431                }
9432            }
9433            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9434        }
9435        return true;
9436    }
9437
9438    /**
9439     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9440     * there is a thread associated with the activity.
9441     */
9442    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9443            final ActivityRecord r, String[] args, boolean dumpAll) {
9444        String innerPrefix = prefix + "  ";
9445        synchronized (this) {
9446            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9447                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9448                    pw.print(" pid=");
9449                    if (r.app != null) pw.println(r.app.pid);
9450                    else pw.println("(not running)");
9451            if (dumpAll) {
9452                r.dump(pw, innerPrefix);
9453            }
9454        }
9455        if (r.app != null && r.app.thread != null) {
9456            // flush anything that is already in the PrintWriter since the thread is going
9457            // to write to the file descriptor directly
9458            pw.flush();
9459            try {
9460                TransferPipe tp = new TransferPipe();
9461                try {
9462                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9463                            r.appToken, innerPrefix, args);
9464                    tp.go(fd);
9465                } finally {
9466                    tp.kill();
9467                }
9468            } catch (IOException e) {
9469                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9470            } catch (RemoteException e) {
9471                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9472            }
9473        }
9474    }
9475
9476    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9477            int opti, boolean dumpAll, String dumpPackage) {
9478        boolean needSep = false;
9479        boolean onlyHistory = false;
9480
9481        if ("history".equals(dumpPackage)) {
9482            onlyHistory = true;
9483            dumpPackage = null;
9484        }
9485
9486        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9487        if (!onlyHistory && dumpAll) {
9488            if (mRegisteredReceivers.size() > 0) {
9489                boolean printed = false;
9490                Iterator it = mRegisteredReceivers.values().iterator();
9491                while (it.hasNext()) {
9492                    ReceiverList r = (ReceiverList)it.next();
9493                    if (dumpPackage != null && (r.app == null ||
9494                            !dumpPackage.equals(r.app.info.packageName))) {
9495                        continue;
9496                    }
9497                    if (!printed) {
9498                        pw.println("  Registered Receivers:");
9499                        needSep = true;
9500                        printed = true;
9501                    }
9502                    pw.print("  * "); pw.println(r);
9503                    r.dump(pw, "    ");
9504                }
9505            }
9506
9507            if (mReceiverResolver.dump(pw, needSep ?
9508                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9509                    "    ", dumpPackage, false)) {
9510                needSep = true;
9511            }
9512        }
9513
9514        for (BroadcastQueue q : mBroadcastQueues) {
9515            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9516        }
9517
9518        needSep = true;
9519
9520        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9521            for (int user=0; user<mStickyBroadcasts.size(); user++) {
9522                if (needSep) {
9523                    pw.println();
9524                }
9525                needSep = true;
9526                pw.print("  Sticky broadcasts for user ");
9527                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9528                StringBuilder sb = new StringBuilder(128);
9529                for (Map.Entry<String, ArrayList<Intent>> ent
9530                        : mStickyBroadcasts.valueAt(user).entrySet()) {
9531                    pw.print("  * Sticky action "); pw.print(ent.getKey());
9532                    if (dumpAll) {
9533                        pw.println(":");
9534                        ArrayList<Intent> intents = ent.getValue();
9535                        final int N = intents.size();
9536                        for (int i=0; i<N; i++) {
9537                            sb.setLength(0);
9538                            sb.append("    Intent: ");
9539                            intents.get(i).toShortString(sb, false, true, false, false);
9540                            pw.println(sb.toString());
9541                            Bundle bundle = intents.get(i).getExtras();
9542                            if (bundle != null) {
9543                                pw.print("      ");
9544                                pw.println(bundle.toString());
9545                            }
9546                        }
9547                    } else {
9548                        pw.println("");
9549                    }
9550                }
9551            }
9552        }
9553
9554        if (!onlyHistory && dumpAll) {
9555            pw.println();
9556            for (BroadcastQueue queue : mBroadcastQueues) {
9557                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9558                        + queue.mBroadcastsScheduled);
9559            }
9560            pw.println("  mHandler:");
9561            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9562            needSep = true;
9563        }
9564
9565        return needSep;
9566    }
9567
9568    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9569            int opti, boolean dumpAll, String dumpPackage) {
9570        boolean needSep = true;
9571
9572        ItemMatcher matcher = new ItemMatcher();
9573        matcher.build(args, opti);
9574
9575        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9576
9577        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9578
9579        if (mLaunchingProviders.size() > 0) {
9580            boolean printed = false;
9581            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9582                ContentProviderRecord r = mLaunchingProviders.get(i);
9583                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9584                    continue;
9585                }
9586                if (!printed) {
9587                    if (needSep) pw.println(" ");
9588                    needSep = true;
9589                    pw.println("  Launching content providers:");
9590                    printed = true;
9591                }
9592                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9593                        pw.println(r);
9594            }
9595        }
9596
9597        if (mGrantedUriPermissions.size() > 0) {
9598            if (needSep) pw.println();
9599            needSep = true;
9600            pw.println("Granted Uri Permissions:");
9601            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9602                int uid = mGrantedUriPermissions.keyAt(i);
9603                HashMap<Uri, UriPermission> perms
9604                        = mGrantedUriPermissions.valueAt(i);
9605                pw.print("  * UID "); pw.print(uid);
9606                        pw.println(" holds:");
9607                for (UriPermission perm : perms.values()) {
9608                    pw.print("    "); pw.println(perm);
9609                    if (dumpAll) {
9610                        perm.dump(pw, "      ");
9611                    }
9612                }
9613            }
9614            needSep = true;
9615        }
9616
9617        return needSep;
9618    }
9619
9620    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9621            int opti, boolean dumpAll, String dumpPackage) {
9622        boolean needSep = false;
9623
9624        if (mIntentSenderRecords.size() > 0) {
9625            boolean printed = false;
9626            Iterator<WeakReference<PendingIntentRecord>> it
9627                    = mIntentSenderRecords.values().iterator();
9628            while (it.hasNext()) {
9629                WeakReference<PendingIntentRecord> ref = it.next();
9630                PendingIntentRecord rec = ref != null ? ref.get(): null;
9631                if (dumpPackage != null && (rec == null
9632                        || !dumpPackage.equals(rec.key.packageName))) {
9633                    continue;
9634                }
9635                if (!printed) {
9636                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9637                    printed = true;
9638                }
9639                needSep = true;
9640                if (rec != null) {
9641                    pw.print("  * "); pw.println(rec);
9642                    if (dumpAll) {
9643                        rec.dump(pw, "    ");
9644                    }
9645                } else {
9646                    pw.print("  * "); pw.println(ref);
9647                }
9648            }
9649        }
9650
9651        return needSep;
9652    }
9653
9654    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9655            String prefix, String label, boolean complete, boolean brief, boolean client,
9656            String dumpPackage) {
9657        TaskRecord lastTask = null;
9658        boolean needNL = false;
9659        final String innerPrefix = prefix + "      ";
9660        final String[] args = new String[0];
9661        for (int i=list.size()-1; i>=0; i--) {
9662            final ActivityRecord r = (ActivityRecord)list.get(i);
9663            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9664                continue;
9665            }
9666            final boolean full = !brief && (complete || !r.isInHistory());
9667            if (needNL) {
9668                pw.println(" ");
9669                needNL = false;
9670            }
9671            if (lastTask != r.task) {
9672                lastTask = r.task;
9673                pw.print(prefix);
9674                pw.print(full ? "* " : "  ");
9675                pw.println(lastTask);
9676                if (full) {
9677                    lastTask.dump(pw, prefix + "  ");
9678                } else if (complete) {
9679                    // Complete + brief == give a summary.  Isn't that obvious?!?
9680                    if (lastTask.intent != null) {
9681                        pw.print(prefix); pw.print("  ");
9682                                pw.println(lastTask.intent.toInsecureStringWithClip());
9683                    }
9684                }
9685            }
9686            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9687            pw.print(" #"); pw.print(i); pw.print(": ");
9688            pw.println(r);
9689            if (full) {
9690                r.dump(pw, innerPrefix);
9691            } else if (complete) {
9692                // Complete + brief == give a summary.  Isn't that obvious?!?
9693                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9694                if (r.app != null) {
9695                    pw.print(innerPrefix); pw.println(r.app);
9696                }
9697            }
9698            if (client && r.app != null && r.app.thread != null) {
9699                // flush anything that is already in the PrintWriter since the thread is going
9700                // to write to the file descriptor directly
9701                pw.flush();
9702                try {
9703                    TransferPipe tp = new TransferPipe();
9704                    try {
9705                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9706                                r.appToken, innerPrefix, args);
9707                        // Short timeout, since blocking here can
9708                        // deadlock with the application.
9709                        tp.go(fd, 2000);
9710                    } finally {
9711                        tp.kill();
9712                    }
9713                } catch (IOException e) {
9714                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9715                } catch (RemoteException e) {
9716                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9717                }
9718                needNL = true;
9719            }
9720        }
9721    }
9722
9723    private static String buildOomTag(String prefix, String space, int val, int base) {
9724        if (val == base) {
9725            if (space == null) return prefix;
9726            return prefix + "  ";
9727        }
9728        return prefix + "+" + Integer.toString(val-base);
9729    }
9730
9731    private static final int dumpProcessList(PrintWriter pw,
9732            ActivityManagerService service, List list,
9733            String prefix, String normalLabel, String persistentLabel,
9734            String dumpPackage) {
9735        int numPers = 0;
9736        final int N = list.size()-1;
9737        for (int i=N; i>=0; i--) {
9738            ProcessRecord r = (ProcessRecord)list.get(i);
9739            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9740                continue;
9741            }
9742            pw.println(String.format("%s%s #%2d: %s",
9743                    prefix, (r.persistent ? persistentLabel : normalLabel),
9744                    i, r.toString()));
9745            if (r.persistent) {
9746                numPers++;
9747            }
9748        }
9749        return numPers;
9750    }
9751
9752    private static final boolean dumpProcessOomList(PrintWriter pw,
9753            ActivityManagerService service, List<ProcessRecord> origList,
9754            String prefix, String normalLabel, String persistentLabel,
9755            boolean inclDetails, String dumpPackage) {
9756
9757        ArrayList<Pair<ProcessRecord, Integer>> list
9758                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9759        for (int i=0; i<origList.size(); i++) {
9760            ProcessRecord r = origList.get(i);
9761            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9762                continue;
9763            }
9764            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9765        }
9766
9767        if (list.size() <= 0) {
9768            return false;
9769        }
9770
9771        Comparator<Pair<ProcessRecord, Integer>> comparator
9772                = new Comparator<Pair<ProcessRecord, Integer>>() {
9773            @Override
9774            public int compare(Pair<ProcessRecord, Integer> object1,
9775                    Pair<ProcessRecord, Integer> object2) {
9776                if (object1.first.setAdj != object2.first.setAdj) {
9777                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9778                }
9779                if (object1.second.intValue() != object2.second.intValue()) {
9780                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9781                }
9782                return 0;
9783            }
9784        };
9785
9786        Collections.sort(list, comparator);
9787
9788        final long curRealtime = SystemClock.elapsedRealtime();
9789        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9790        final long curUptime = SystemClock.uptimeMillis();
9791        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9792
9793        for (int i=list.size()-1; i>=0; i--) {
9794            ProcessRecord r = list.get(i).first;
9795            String oomAdj;
9796            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9797                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9798            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9799                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9800            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9801                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9802            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9803                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9804            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9805                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9806            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9807                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9808            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9809                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9810            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9811                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9812            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9813                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9814            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9815                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9816            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9817                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9818            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9819                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9820            } else {
9821                oomAdj = Integer.toString(r.setAdj);
9822            }
9823            String schedGroup;
9824            switch (r.setSchedGroup) {
9825                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9826                    schedGroup = "B";
9827                    break;
9828                case Process.THREAD_GROUP_DEFAULT:
9829                    schedGroup = "F";
9830                    break;
9831                default:
9832                    schedGroup = Integer.toString(r.setSchedGroup);
9833                    break;
9834            }
9835            String foreground;
9836            if (r.foregroundActivities) {
9837                foreground = "A";
9838            } else if (r.foregroundServices) {
9839                foreground = "S";
9840            } else {
9841                foreground = " ";
9842            }
9843            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9844                    prefix, (r.persistent ? persistentLabel : normalLabel),
9845                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9846                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9847            if (r.adjSource != null || r.adjTarget != null) {
9848                pw.print(prefix);
9849                pw.print("    ");
9850                if (r.adjTarget instanceof ComponentName) {
9851                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9852                } else if (r.adjTarget != null) {
9853                    pw.print(r.adjTarget.toString());
9854                } else {
9855                    pw.print("{null}");
9856                }
9857                pw.print("<=");
9858                if (r.adjSource instanceof ProcessRecord) {
9859                    pw.print("Proc{");
9860                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9861                    pw.println("}");
9862                } else if (r.adjSource != null) {
9863                    pw.println(r.adjSource.toString());
9864                } else {
9865                    pw.println("{null}");
9866                }
9867            }
9868            if (inclDetails) {
9869                pw.print(prefix);
9870                pw.print("    ");
9871                pw.print("oom: max="); pw.print(r.maxAdj);
9872                pw.print(" hidden="); pw.print(r.hiddenAdj);
9873                pw.print(" empty="); pw.print(r.emptyAdj);
9874                pw.print(" curRaw="); pw.print(r.curRawAdj);
9875                pw.print(" setRaw="); pw.print(r.setRawAdj);
9876                pw.print(" cur="); pw.print(r.curAdj);
9877                pw.print(" set="); pw.println(r.setAdj);
9878                pw.print(prefix);
9879                pw.print("    ");
9880                pw.print("keeping="); pw.print(r.keeping);
9881                pw.print(" hidden="); pw.print(r.hidden);
9882                pw.print(" empty="); pw.print(r.empty);
9883                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9884
9885                if (!r.keeping) {
9886                    if (r.lastWakeTime != 0) {
9887                        long wtime;
9888                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9889                        synchronized (stats) {
9890                            wtime = stats.getProcessWakeTime(r.info.uid,
9891                                    r.pid, curRealtime);
9892                        }
9893                        long timeUsed = wtime - r.lastWakeTime;
9894                        pw.print(prefix);
9895                        pw.print("    ");
9896                        pw.print("keep awake over ");
9897                        TimeUtils.formatDuration(realtimeSince, pw);
9898                        pw.print(" used ");
9899                        TimeUtils.formatDuration(timeUsed, pw);
9900                        pw.print(" (");
9901                        pw.print((timeUsed*100)/realtimeSince);
9902                        pw.println("%)");
9903                    }
9904                    if (r.lastCpuTime != 0) {
9905                        long timeUsed = r.curCpuTime - r.lastCpuTime;
9906                        pw.print(prefix);
9907                        pw.print("    ");
9908                        pw.print("run cpu over ");
9909                        TimeUtils.formatDuration(uptimeSince, pw);
9910                        pw.print(" used ");
9911                        TimeUtils.formatDuration(timeUsed, pw);
9912                        pw.print(" (");
9913                        pw.print((timeUsed*100)/uptimeSince);
9914                        pw.println("%)");
9915                    }
9916                }
9917            }
9918        }
9919        return true;
9920    }
9921
9922    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
9923        ArrayList<ProcessRecord> procs;
9924        synchronized (this) {
9925            if (args != null && args.length > start
9926                    && args[start].charAt(0) != '-') {
9927                procs = new ArrayList<ProcessRecord>();
9928                int pid = -1;
9929                try {
9930                    pid = Integer.parseInt(args[start]);
9931                } catch (NumberFormatException e) {
9932
9933                }
9934                for (int i=mLruProcesses.size()-1; i>=0; i--) {
9935                    ProcessRecord proc = mLruProcesses.get(i);
9936                    if (proc.pid == pid) {
9937                        procs.add(proc);
9938                    } else if (proc.processName.equals(args[start])) {
9939                        procs.add(proc);
9940                    }
9941                }
9942                if (procs.size() <= 0) {
9943                    pw.println("No process found for: " + args[start]);
9944                    return null;
9945                }
9946            } else {
9947                procs = new ArrayList<ProcessRecord>(mLruProcesses);
9948            }
9949        }
9950        return procs;
9951    }
9952
9953    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9954            PrintWriter pw, String[] args) {
9955        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9956        if (procs == null) {
9957            return;
9958        }
9959
9960        long uptime = SystemClock.uptimeMillis();
9961        long realtime = SystemClock.elapsedRealtime();
9962        pw.println("Applications Graphics Acceleration Info:");
9963        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9964
9965        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9966            ProcessRecord r = procs.get(i);
9967            if (r.thread != null) {
9968                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9969                pw.flush();
9970                try {
9971                    TransferPipe tp = new TransferPipe();
9972                    try {
9973                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9974                        tp.go(fd);
9975                    } finally {
9976                        tp.kill();
9977                    }
9978                } catch (IOException e) {
9979                    pw.println("Failure while dumping the app: " + r);
9980                    pw.flush();
9981                } catch (RemoteException e) {
9982                    pw.println("Got a RemoteException while dumping the app " + r);
9983                    pw.flush();
9984                }
9985            }
9986        }
9987    }
9988
9989    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
9990        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9991        if (procs == null) {
9992            return;
9993        }
9994
9995        pw.println("Applications Database Info:");
9996
9997        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9998            ProcessRecord r = procs.get(i);
9999            if (r.thread != null) {
10000                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10001                pw.flush();
10002                try {
10003                    TransferPipe tp = new TransferPipe();
10004                    try {
10005                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10006                        tp.go(fd);
10007                    } finally {
10008                        tp.kill();
10009                    }
10010                } catch (IOException e) {
10011                    pw.println("Failure while dumping the app: " + r);
10012                    pw.flush();
10013                } catch (RemoteException e) {
10014                    pw.println("Got a RemoteException while dumping the app " + r);
10015                    pw.flush();
10016                }
10017            }
10018        }
10019    }
10020
10021    final static class MemItem {
10022        final String label;
10023        final String shortLabel;
10024        final long pss;
10025        final int id;
10026        ArrayList<MemItem> subitems;
10027
10028        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10029            label = _label;
10030            shortLabel = _shortLabel;
10031            pss = _pss;
10032            id = _id;
10033        }
10034    }
10035
10036    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10037            boolean sort) {
10038        if (sort) {
10039            Collections.sort(items, new Comparator<MemItem>() {
10040                @Override
10041                public int compare(MemItem lhs, MemItem rhs) {
10042                    if (lhs.pss < rhs.pss) {
10043                        return 1;
10044                    } else if (lhs.pss > rhs.pss) {
10045                        return -1;
10046                    }
10047                    return 0;
10048                }
10049            });
10050        }
10051
10052        for (int i=0; i<items.size(); i++) {
10053            MemItem mi = items.get(i);
10054            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10055            if (mi.subitems != null) {
10056                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10057            }
10058        }
10059    }
10060
10061    // These are in KB.
10062    static final long[] DUMP_MEM_BUCKETS = new long[] {
10063        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10064        120*1024, 160*1024, 200*1024,
10065        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10066        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10067    };
10068
10069    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10070            boolean stackLike) {
10071        int start = label.lastIndexOf('.');
10072        if (start >= 0) start++;
10073        else start = 0;
10074        int end = label.length();
10075        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10076            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10077                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10078                out.append(bucket);
10079                out.append(stackLike ? "MB." : "MB ");
10080                out.append(label, start, end);
10081                return;
10082            }
10083        }
10084        out.append(memKB/1024);
10085        out.append(stackLike ? "MB." : "MB ");
10086        out.append(label, start, end);
10087    }
10088
10089    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10090            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10091            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10092            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10093            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10094    };
10095    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10096            "System", "Persistent", "Foreground",
10097            "Visible", "Perceptible", "Heavy Weight",
10098            "Backup", "A Services", "Home", "Previous",
10099            "B Services", "Background"
10100    };
10101
10102    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10103            PrintWriter pw, String prefix, String[] args, boolean brief,
10104            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10105        boolean dumpAll = false;
10106        boolean oomOnly = false;
10107
10108        int opti = 0;
10109        while (opti < args.length) {
10110            String opt = args[opti];
10111            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10112                break;
10113            }
10114            opti++;
10115            if ("-a".equals(opt)) {
10116                dumpAll = true;
10117            } else if ("--oom".equals(opt)) {
10118                oomOnly = true;
10119            } else if ("-h".equals(opt)) {
10120                pw.println("meminfo dump options: [-a] [--oom] [process]");
10121                pw.println("  -a: include all available information for each process.");
10122                pw.println("  --oom: only show processes organized by oom adj.");
10123                pw.println("If [process] is specified it can be the name or ");
10124                pw.println("pid of a specific process to dump.");
10125                return;
10126            } else {
10127                pw.println("Unknown argument: " + opt + "; use -h for help");
10128            }
10129        }
10130
10131        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10132        if (procs == null) {
10133            return;
10134        }
10135
10136        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10137        long uptime = SystemClock.uptimeMillis();
10138        long realtime = SystemClock.elapsedRealtime();
10139
10140        if (procs.size() == 1 || isCheckinRequest) {
10141            dumpAll = true;
10142        }
10143
10144        if (isCheckinRequest) {
10145            // short checkin version
10146            pw.println(uptime + "," + realtime);
10147            pw.flush();
10148        } else {
10149            pw.println("Applications Memory Usage (kB):");
10150            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10151        }
10152
10153        String[] innerArgs = new String[args.length-opti];
10154        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10155
10156        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10157        long nativePss=0, dalvikPss=0, otherPss=0;
10158        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10159
10160        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10161        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10162                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10163
10164        long totalPss = 0;
10165
10166        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10167            ProcessRecord r = procs.get(i);
10168            if (r.thread != null) {
10169                if (!isCheckinRequest && dumpAll) {
10170                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10171                    pw.flush();
10172                }
10173                Debug.MemoryInfo mi = null;
10174                if (dumpAll) {
10175                    try {
10176                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10177                    } catch (RemoteException e) {
10178                        if (!isCheckinRequest) {
10179                            pw.println("Got RemoteException!");
10180                            pw.flush();
10181                        }
10182                    }
10183                } else {
10184                    mi = new Debug.MemoryInfo();
10185                    Debug.getMemoryInfo(r.pid, mi);
10186                }
10187
10188                if (!isCheckinRequest && mi != null) {
10189                    long myTotalPss = mi.getTotalPss();
10190                    totalPss += myTotalPss;
10191                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10192                            r.processName, myTotalPss, 0);
10193                    procMems.add(pssItem);
10194
10195                    nativePss += mi.nativePss;
10196                    dalvikPss += mi.dalvikPss;
10197                    otherPss += mi.otherPss;
10198                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10199                        long mem = mi.getOtherPss(j);
10200                        miscPss[j] += mem;
10201                        otherPss -= mem;
10202                    }
10203
10204                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10205                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10206                                || oomIndex == (oomPss.length-1)) {
10207                            oomPss[oomIndex] += myTotalPss;
10208                            if (oomProcs[oomIndex] == null) {
10209                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10210                            }
10211                            oomProcs[oomIndex].add(pssItem);
10212                            break;
10213                        }
10214                    }
10215                }
10216            }
10217        }
10218
10219        if (!isCheckinRequest && procs.size() > 1) {
10220            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10221
10222            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10223            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10224            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10225            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10226                String label = Debug.MemoryInfo.getOtherLabel(j);
10227                catMems.add(new MemItem(label, label, miscPss[j], j));
10228            }
10229
10230            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10231            for (int j=0; j<oomPss.length; j++) {
10232                if (oomPss[j] != 0) {
10233                    String label = DUMP_MEM_OOM_LABEL[j];
10234                    MemItem item = new MemItem(label, label, oomPss[j],
10235                            DUMP_MEM_OOM_ADJ[j]);
10236                    item.subitems = oomProcs[j];
10237                    oomMems.add(item);
10238                }
10239            }
10240
10241            if (outTag != null || outStack != null) {
10242                if (outTag != null) {
10243                    appendMemBucket(outTag, totalPss, "total", false);
10244                }
10245                if (outStack != null) {
10246                    appendMemBucket(outStack, totalPss, "total", true);
10247                }
10248                boolean firstLine = true;
10249                for (int i=0; i<oomMems.size(); i++) {
10250                    MemItem miCat = oomMems.get(i);
10251                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10252                        continue;
10253                    }
10254                    if (miCat.id < ProcessList.SERVICE_ADJ
10255                            || miCat.id == ProcessList.HOME_APP_ADJ
10256                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10257                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10258                            outTag.append(" / ");
10259                        }
10260                        if (outStack != null) {
10261                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10262                                if (firstLine) {
10263                                    outStack.append(":");
10264                                    firstLine = false;
10265                                }
10266                                outStack.append("\n\t at ");
10267                            } else {
10268                                outStack.append("$");
10269                            }
10270                        }
10271                        for (int j=0; j<miCat.subitems.size(); j++) {
10272                            MemItem mi = miCat.subitems.get(j);
10273                            if (j > 0) {
10274                                if (outTag != null) {
10275                                    outTag.append(" ");
10276                                }
10277                                if (outStack != null) {
10278                                    outStack.append("$");
10279                                }
10280                            }
10281                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10282                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10283                            }
10284                            if (outStack != null) {
10285                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10286                            }
10287                        }
10288                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10289                            outStack.append("(");
10290                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10291                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10292                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10293                                    outStack.append(":");
10294                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10295                                }
10296                            }
10297                            outStack.append(")");
10298                        }
10299                    }
10300                }
10301            }
10302
10303            if (!brief && !oomOnly) {
10304                pw.println();
10305                pw.println("Total PSS by process:");
10306                dumpMemItems(pw, "  ", procMems, true);
10307                pw.println();
10308            }
10309            pw.println("Total PSS by OOM adjustment:");
10310            dumpMemItems(pw, "  ", oomMems, false);
10311            if (!oomOnly) {
10312                PrintWriter out = categoryPw != null ? categoryPw : pw;
10313                out.println();
10314                out.println("Total PSS by category:");
10315                dumpMemItems(out, "  ", catMems, true);
10316            }
10317            pw.println();
10318            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10319            final int[] SINGLE_LONG_FORMAT = new int[] {
10320                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10321            };
10322            long[] longOut = new long[1];
10323            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10324                    SINGLE_LONG_FORMAT, null, longOut, null);
10325            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10326            longOut[0] = 0;
10327            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10328                    SINGLE_LONG_FORMAT, null, longOut, null);
10329            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10330            longOut[0] = 0;
10331            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10332                    SINGLE_LONG_FORMAT, null, longOut, null);
10333            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10334            longOut[0] = 0;
10335            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10336                    SINGLE_LONG_FORMAT, null, longOut, null);
10337            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10338            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10339                    pw.print(shared); pw.println(" kB");
10340            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10341                    pw.print(voltile); pw.println(" kB volatile");
10342        }
10343    }
10344
10345    /**
10346     * Searches array of arguments for the specified string
10347     * @param args array of argument strings
10348     * @param value value to search for
10349     * @return true if the value is contained in the array
10350     */
10351    private static boolean scanArgs(String[] args, String value) {
10352        if (args != null) {
10353            for (String arg : args) {
10354                if (value.equals(arg)) {
10355                    return true;
10356                }
10357            }
10358        }
10359        return false;
10360    }
10361
10362    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10363            ContentProviderRecord cpr, boolean always) {
10364        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10365
10366        if (!inLaunching || always) {
10367            synchronized (cpr) {
10368                cpr.launchingApp = null;
10369                cpr.notifyAll();
10370            }
10371            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10372            String names[] = cpr.info.authority.split(";");
10373            for (int j = 0; j < names.length; j++) {
10374                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10375            }
10376        }
10377
10378        for (int i=0; i<cpr.connections.size(); i++) {
10379            ContentProviderConnection conn = cpr.connections.get(i);
10380            if (conn.waiting) {
10381                // If this connection is waiting for the provider, then we don't
10382                // need to mess with its process unless we are always removing
10383                // or for some reason the provider is not currently launching.
10384                if (inLaunching && !always) {
10385                    continue;
10386                }
10387            }
10388            ProcessRecord capp = conn.client;
10389            conn.dead = true;
10390            if (conn.stableCount > 0) {
10391                if (!capp.persistent && capp.thread != null
10392                        && capp.pid != 0
10393                        && capp.pid != MY_PID) {
10394                    Slog.i(TAG, "Kill " + capp.processName
10395                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10396                            + " in dying process " + (proc != null ? proc.processName : "??"));
10397                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10398                            capp.processName, capp.setAdj, "dying provider "
10399                                    + cpr.name.toShortString());
10400                    Process.killProcessQuiet(capp.pid);
10401                }
10402            } else if (capp.thread != null && conn.provider.provider != null) {
10403                try {
10404                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10405                } catch (RemoteException e) {
10406                }
10407                // In the protocol here, we don't expect the client to correctly
10408                // clean up this connection, we'll just remove it.
10409                cpr.connections.remove(i);
10410                conn.client.conProviders.remove(conn);
10411            }
10412        }
10413
10414        if (inLaunching && always) {
10415            mLaunchingProviders.remove(cpr);
10416        }
10417        return inLaunching;
10418    }
10419
10420    /**
10421     * Main code for cleaning up a process when it has gone away.  This is
10422     * called both as a result of the process dying, or directly when stopping
10423     * a process when running in single process mode.
10424     */
10425    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10426            boolean restarting, boolean allowRestart, int index) {
10427        if (index >= 0) {
10428            mLruProcesses.remove(index);
10429        }
10430
10431        mProcessesToGc.remove(app);
10432
10433        // Dismiss any open dialogs.
10434        if (app.crashDialog != null) {
10435            app.crashDialog.dismiss();
10436            app.crashDialog = null;
10437        }
10438        if (app.anrDialog != null) {
10439            app.anrDialog.dismiss();
10440            app.anrDialog = null;
10441        }
10442        if (app.waitDialog != null) {
10443            app.waitDialog.dismiss();
10444            app.waitDialog = null;
10445        }
10446
10447        app.crashing = false;
10448        app.notResponding = false;
10449
10450        app.resetPackageList();
10451        app.unlinkDeathRecipient();
10452        app.thread = null;
10453        app.forcingToForeground = null;
10454        app.foregroundServices = false;
10455        app.foregroundActivities = false;
10456        app.hasShownUi = false;
10457        app.hasAboveClient = false;
10458
10459        mServices.killServicesLocked(app, allowRestart);
10460
10461        boolean restart = false;
10462
10463        // Remove published content providers.
10464        if (!app.pubProviders.isEmpty()) {
10465            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10466            while (it.hasNext()) {
10467                ContentProviderRecord cpr = it.next();
10468
10469                final boolean always = app.bad || !allowRestart;
10470                if (removeDyingProviderLocked(app, cpr, always) || always) {
10471                    // We left the provider in the launching list, need to
10472                    // restart it.
10473                    restart = true;
10474                }
10475
10476                cpr.provider = null;
10477                cpr.proc = null;
10478            }
10479            app.pubProviders.clear();
10480        }
10481
10482        // Take care of any launching providers waiting for this process.
10483        if (checkAppInLaunchingProvidersLocked(app, false)) {
10484            restart = true;
10485        }
10486
10487        // Unregister from connected content providers.
10488        if (!app.conProviders.isEmpty()) {
10489            for (int i=0; i<app.conProviders.size(); i++) {
10490                ContentProviderConnection conn = app.conProviders.get(i);
10491                conn.provider.connections.remove(conn);
10492            }
10493            app.conProviders.clear();
10494        }
10495
10496        // At this point there may be remaining entries in mLaunchingProviders
10497        // where we were the only one waiting, so they are no longer of use.
10498        // Look for these and clean up if found.
10499        // XXX Commented out for now.  Trying to figure out a way to reproduce
10500        // the actual situation to identify what is actually going on.
10501        if (false) {
10502            for (int i=0; i<mLaunchingProviders.size(); i++) {
10503                ContentProviderRecord cpr = (ContentProviderRecord)
10504                        mLaunchingProviders.get(i);
10505                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10506                    synchronized (cpr) {
10507                        cpr.launchingApp = null;
10508                        cpr.notifyAll();
10509                    }
10510                }
10511            }
10512        }
10513
10514        skipCurrentReceiverLocked(app);
10515
10516        // Unregister any receivers.
10517        if (app.receivers.size() > 0) {
10518            Iterator<ReceiverList> it = app.receivers.iterator();
10519            while (it.hasNext()) {
10520                removeReceiverLocked(it.next());
10521            }
10522            app.receivers.clear();
10523        }
10524
10525        // If the app is undergoing backup, tell the backup manager about it
10526        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10527            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10528            try {
10529                IBackupManager bm = IBackupManager.Stub.asInterface(
10530                        ServiceManager.getService(Context.BACKUP_SERVICE));
10531                bm.agentDisconnected(app.info.packageName);
10532            } catch (RemoteException e) {
10533                // can't happen; backup manager is local
10534            }
10535        }
10536
10537        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10538            ProcessChangeItem item = mPendingProcessChanges.get(i);
10539            if (item.pid == app.pid) {
10540                mPendingProcessChanges.remove(i);
10541                mAvailProcessChanges.add(item);
10542            }
10543        }
10544        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10545
10546        // If the caller is restarting this app, then leave it in its
10547        // current lists and let the caller take care of it.
10548        if (restarting) {
10549            return;
10550        }
10551
10552        if (!app.persistent || app.isolated) {
10553            if (DEBUG_PROCESSES) Slog.v(TAG,
10554                    "Removing non-persistent process during cleanup: " + app);
10555            mProcessNames.remove(app.processName, app.uid);
10556            mIsolatedProcesses.remove(app.uid);
10557            if (mHeavyWeightProcess == app) {
10558                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10559                        mHeavyWeightProcess.userId, 0));
10560                mHeavyWeightProcess = null;
10561            }
10562        } else if (!app.removed) {
10563            // This app is persistent, so we need to keep its record around.
10564            // If it is not already on the pending app list, add it there
10565            // and start a new process for it.
10566            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10567                mPersistentStartingProcesses.add(app);
10568                restart = true;
10569            }
10570        }
10571        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10572                "Clean-up removing on hold: " + app);
10573        mProcessesOnHold.remove(app);
10574
10575        if (app == mHomeProcess) {
10576            mHomeProcess = null;
10577        }
10578        if (app == mPreviousProcess) {
10579            mPreviousProcess = null;
10580        }
10581
10582        if (restart && !app.isolated) {
10583            // We have components that still need to be running in the
10584            // process, so re-launch it.
10585            mProcessNames.put(app.processName, app.uid, app);
10586            startProcessLocked(app, "restart", app.processName);
10587        } else if (app.pid > 0 && app.pid != MY_PID) {
10588            // Goodbye!
10589            synchronized (mPidsSelfLocked) {
10590                mPidsSelfLocked.remove(app.pid);
10591                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10592            }
10593            app.setPid(0);
10594        }
10595    }
10596
10597    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10598        // Look through the content providers we are waiting to have launched,
10599        // and if any run in this process then either schedule a restart of
10600        // the process or kill the client waiting for it if this process has
10601        // gone bad.
10602        int NL = mLaunchingProviders.size();
10603        boolean restart = false;
10604        for (int i=0; i<NL; i++) {
10605            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10606            if (cpr.launchingApp == app) {
10607                if (!alwaysBad && !app.bad) {
10608                    restart = true;
10609                } else {
10610                    removeDyingProviderLocked(app, cpr, true);
10611                    NL = mLaunchingProviders.size();
10612                }
10613            }
10614        }
10615        return restart;
10616    }
10617
10618    // =========================================================
10619    // SERVICES
10620    // =========================================================
10621
10622    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10623            int flags) {
10624        enforceNotIsolatedCaller("getServices");
10625        synchronized (this) {
10626            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10627        }
10628    }
10629
10630    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10631        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10632        synchronized (this) {
10633            return mServices.getRunningServiceControlPanelLocked(name);
10634        }
10635    }
10636
10637    public ComponentName startService(IApplicationThread caller, Intent service,
10638            String resolvedType, int userId) {
10639        enforceNotIsolatedCaller("startService");
10640        // Refuse possible leaked file descriptors
10641        if (service != null && service.hasFileDescriptors() == true) {
10642            throw new IllegalArgumentException("File descriptors passed in Intent");
10643        }
10644
10645        if (DEBUG_SERVICE)
10646            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10647        synchronized(this) {
10648            final int callingPid = Binder.getCallingPid();
10649            final int callingUid = Binder.getCallingUid();
10650            checkValidCaller(callingUid, userId);
10651            final long origId = Binder.clearCallingIdentity();
10652            ComponentName res = mServices.startServiceLocked(caller, service,
10653                    resolvedType, callingPid, callingUid, userId);
10654            Binder.restoreCallingIdentity(origId);
10655            return res;
10656        }
10657    }
10658
10659    ComponentName startServiceInPackage(int uid,
10660            Intent service, String resolvedType, int userId) {
10661        synchronized(this) {
10662            if (DEBUG_SERVICE)
10663                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10664            final long origId = Binder.clearCallingIdentity();
10665            ComponentName res = mServices.startServiceLocked(null, service,
10666                    resolvedType, -1, uid, userId);
10667            Binder.restoreCallingIdentity(origId);
10668            return res;
10669        }
10670    }
10671
10672    public int stopService(IApplicationThread caller, Intent service,
10673            String resolvedType, int userId) {
10674        enforceNotIsolatedCaller("stopService");
10675        // Refuse possible leaked file descriptors
10676        if (service != null && service.hasFileDescriptors() == true) {
10677            throw new IllegalArgumentException("File descriptors passed in Intent");
10678        }
10679
10680        checkValidCaller(Binder.getCallingUid(), userId);
10681
10682        synchronized(this) {
10683            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10684        }
10685    }
10686
10687    public IBinder peekService(Intent service, String resolvedType) {
10688        enforceNotIsolatedCaller("peekService");
10689        // Refuse possible leaked file descriptors
10690        if (service != null && service.hasFileDescriptors() == true) {
10691            throw new IllegalArgumentException("File descriptors passed in Intent");
10692        }
10693        synchronized(this) {
10694            return mServices.peekServiceLocked(service, resolvedType);
10695        }
10696    }
10697
10698    public boolean stopServiceToken(ComponentName className, IBinder token,
10699            int startId) {
10700        synchronized(this) {
10701            return mServices.stopServiceTokenLocked(className, token, startId);
10702        }
10703    }
10704
10705    public void setServiceForeground(ComponentName className, IBinder token,
10706            int id, Notification notification, boolean removeNotification) {
10707        synchronized(this) {
10708            mServices.setServiceForegroundLocked(className, token, id, notification,
10709                    removeNotification);
10710        }
10711    }
10712
10713    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
10714            boolean requireFull, String name, String callerPackage) {
10715        synchronized(this) {
10716            return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll,
10717                    requireFull, name, callerPackage);
10718        }
10719    }
10720
10721    int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll,
10722            boolean requireFull, String name, String callerPackage) {
10723        final int callingUserId = UserHandle.getUserId(callingUid);
10724        if (callingUserId != userId) {
10725            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10726                if ((requireFull || checkComponentPermission(
10727                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10728                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
10729                        && checkComponentPermission(
10730                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10731                                callingPid, callingUid, -1, true)
10732                                != PackageManager.PERMISSION_GRANTED) {
10733                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
10734                        // In this case, they would like to just execute as their
10735                        // owner user instead of failing.
10736                        userId = callingUserId;
10737                    } else {
10738                        StringBuilder builder = new StringBuilder(128);
10739                        builder.append("Permission Denial: ");
10740                        builder.append(name);
10741                        if (callerPackage != null) {
10742                            builder.append(" from ");
10743                            builder.append(callerPackage);
10744                        }
10745                        builder.append(" asks to run as user ");
10746                        builder.append(userId);
10747                        builder.append(" but is calling from user ");
10748                        builder.append(UserHandle.getUserId(callingUid));
10749                        builder.append("; this requires ");
10750                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
10751                        if (!requireFull) {
10752                            builder.append("or");
10753                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
10754                        }
10755                        String msg = builder.toString();
10756                        Slog.w(TAG, msg);
10757                        throw new SecurityException(msg);
10758                    }
10759                }
10760            }
10761            if (userId == UserHandle.USER_CURRENT
10762                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
10763                userId = mCurrentUserId;
10764            }
10765            if (!allowAll && userId < 0) {
10766                throw new IllegalArgumentException(
10767                        "Call does not support special user #" + userId);
10768            }
10769        }
10770        return userId;
10771    }
10772
10773    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10774            String className, int flags) {
10775        boolean result = false;
10776        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10777            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10778                if (ActivityManager.checkUidPermission(
10779                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10780                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10781                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10782                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10783                            + " requests FLAG_SINGLE_USER, but app does not hold "
10784                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10785                    Slog.w(TAG, msg);
10786                    throw new SecurityException(msg);
10787                }
10788                result = true;
10789            }
10790        } else if (componentProcessName == aInfo.packageName) {
10791            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10792        } else if ("system".equals(componentProcessName)) {
10793            result = true;
10794        }
10795        if (DEBUG_MU) {
10796            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10797                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10798        }
10799        return result;
10800    }
10801
10802    public int bindService(IApplicationThread caller, IBinder token,
10803            Intent service, String resolvedType,
10804            IServiceConnection connection, int flags, int userId) {
10805        enforceNotIsolatedCaller("bindService");
10806        // Refuse possible leaked file descriptors
10807        if (service != null && service.hasFileDescriptors() == true) {
10808            throw new IllegalArgumentException("File descriptors passed in Intent");
10809        }
10810
10811        synchronized(this) {
10812            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10813                    connection, flags, userId);
10814        }
10815    }
10816
10817    public boolean unbindService(IServiceConnection connection) {
10818        synchronized (this) {
10819            return mServices.unbindServiceLocked(connection);
10820        }
10821    }
10822
10823    public void publishService(IBinder token, Intent intent, IBinder service) {
10824        // Refuse possible leaked file descriptors
10825        if (intent != null && intent.hasFileDescriptors() == true) {
10826            throw new IllegalArgumentException("File descriptors passed in Intent");
10827        }
10828
10829        synchronized(this) {
10830            if (!(token instanceof ServiceRecord)) {
10831                throw new IllegalArgumentException("Invalid service token");
10832            }
10833            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
10834        }
10835    }
10836
10837    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10838        // Refuse possible leaked file descriptors
10839        if (intent != null && intent.hasFileDescriptors() == true) {
10840            throw new IllegalArgumentException("File descriptors passed in Intent");
10841        }
10842
10843        synchronized(this) {
10844            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
10845        }
10846    }
10847
10848    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10849        synchronized(this) {
10850            if (!(token instanceof ServiceRecord)) {
10851                throw new IllegalArgumentException("Invalid service token");
10852            }
10853            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
10854        }
10855    }
10856
10857    // =========================================================
10858    // BACKUP AND RESTORE
10859    // =========================================================
10860
10861    // Cause the target app to be launched if necessary and its backup agent
10862    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10863    // activity manager to announce its creation.
10864    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10865        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10866        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10867
10868        synchronized(this) {
10869            // !!! TODO: currently no check here that we're already bound
10870            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10871            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10872            synchronized (stats) {
10873                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10874            }
10875
10876            // Backup agent is now in use, its package can't be stopped.
10877            try {
10878                AppGlobals.getPackageManager().setPackageStoppedState(
10879                        app.packageName, false, UserHandle.getUserId(app.uid));
10880            } catch (RemoteException e) {
10881            } catch (IllegalArgumentException e) {
10882                Slog.w(TAG, "Failed trying to unstop package "
10883                        + app.packageName + ": " + e);
10884            }
10885
10886            BackupRecord r = new BackupRecord(ss, app, backupMode);
10887            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10888                    ? new ComponentName(app.packageName, app.backupAgentName)
10889                    : new ComponentName("android", "FullBackupAgent");
10890            // startProcessLocked() returns existing proc's record if it's already running
10891            ProcessRecord proc = startProcessLocked(app.processName, app,
10892                    false, 0, "backup", hostingName, false, false);
10893            if (proc == null) {
10894                Slog.e(TAG, "Unable to start backup agent process " + r);
10895                return false;
10896            }
10897
10898            r.app = proc;
10899            mBackupTarget = r;
10900            mBackupAppName = app.packageName;
10901
10902            // Try not to kill the process during backup
10903            updateOomAdjLocked(proc);
10904
10905            // If the process is already attached, schedule the creation of the backup agent now.
10906            // If it is not yet live, this will be done when it attaches to the framework.
10907            if (proc.thread != null) {
10908                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
10909                try {
10910                    proc.thread.scheduleCreateBackupAgent(app,
10911                            compatibilityInfoForPackageLocked(app), backupMode);
10912                } catch (RemoteException e) {
10913                    // Will time out on the backup manager side
10914                }
10915            } else {
10916                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
10917            }
10918            // Invariants: at this point, the target app process exists and the application
10919            // is either already running or in the process of coming up.  mBackupTarget and
10920            // mBackupAppName describe the app, so that when it binds back to the AM we
10921            // know that it's scheduled for a backup-agent operation.
10922        }
10923
10924        return true;
10925    }
10926
10927    // A backup agent has just come up
10928    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10929        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
10930                + " = " + agent);
10931
10932        synchronized(this) {
10933            if (!agentPackageName.equals(mBackupAppName)) {
10934                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10935                return;
10936            }
10937        }
10938
10939        long oldIdent = Binder.clearCallingIdentity();
10940        try {
10941            IBackupManager bm = IBackupManager.Stub.asInterface(
10942                    ServiceManager.getService(Context.BACKUP_SERVICE));
10943            bm.agentConnected(agentPackageName, agent);
10944        } catch (RemoteException e) {
10945            // can't happen; the backup manager service is local
10946        } catch (Exception e) {
10947            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10948            e.printStackTrace();
10949        } finally {
10950            Binder.restoreCallingIdentity(oldIdent);
10951        }
10952    }
10953
10954    // done with this agent
10955    public void unbindBackupAgent(ApplicationInfo appInfo) {
10956        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
10957        if (appInfo == null) {
10958            Slog.w(TAG, "unbind backup agent for null app");
10959            return;
10960        }
10961
10962        synchronized(this) {
10963            if (mBackupAppName == null) {
10964                Slog.w(TAG, "Unbinding backup agent with no active backup");
10965                return;
10966            }
10967
10968            if (!mBackupAppName.equals(appInfo.packageName)) {
10969                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
10970                return;
10971            }
10972
10973            ProcessRecord proc = mBackupTarget.app;
10974            mBackupTarget = null;
10975            mBackupAppName = null;
10976
10977            // Not backing this app up any more; reset its OOM adjustment
10978            updateOomAdjLocked(proc);
10979
10980            // If the app crashed during backup, 'thread' will be null here
10981            if (proc.thread != null) {
10982                try {
10983                    proc.thread.scheduleDestroyBackupAgent(appInfo,
10984                            compatibilityInfoForPackageLocked(appInfo));
10985                } catch (Exception e) {
10986                    Slog.e(TAG, "Exception when unbinding backup agent:");
10987                    e.printStackTrace();
10988                }
10989            }
10990        }
10991    }
10992    // =========================================================
10993    // BROADCASTS
10994    // =========================================================
10995
10996    private final List getStickiesLocked(String action, IntentFilter filter,
10997            List cur, int userId) {
10998        final ContentResolver resolver = mContext.getContentResolver();
10999        HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11000        if (stickies == null) {
11001            return cur;
11002        }
11003        final ArrayList<Intent> list = stickies.get(action);
11004        if (list == null) {
11005            return cur;
11006        }
11007        int N = list.size();
11008        for (int i=0; i<N; i++) {
11009            Intent intent = list.get(i);
11010            if (filter.match(resolver, intent, true, TAG) >= 0) {
11011                if (cur == null) {
11012                    cur = new ArrayList<Intent>();
11013                }
11014                cur.add(intent);
11015            }
11016        }
11017        return cur;
11018    }
11019
11020    boolean isPendingBroadcastProcessLocked(int pid) {
11021        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11022                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11023    }
11024
11025    void skipPendingBroadcastLocked(int pid) {
11026            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11027            for (BroadcastQueue queue : mBroadcastQueues) {
11028                queue.skipPendingBroadcastLocked(pid);
11029            }
11030    }
11031
11032    // The app just attached; send any pending broadcasts that it should receive
11033    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11034        boolean didSomething = false;
11035        for (BroadcastQueue queue : mBroadcastQueues) {
11036            didSomething |= queue.sendPendingBroadcastsLocked(app);
11037        }
11038        return didSomething;
11039    }
11040
11041    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11042            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11043        enforceNotIsolatedCaller("registerReceiver");
11044        int callingUid;
11045        int callingPid;
11046        synchronized(this) {
11047            ProcessRecord callerApp = null;
11048            if (caller != null) {
11049                callerApp = getRecordForAppLocked(caller);
11050                if (callerApp == null) {
11051                    throw new SecurityException(
11052                            "Unable to find app for caller " + caller
11053                            + " (pid=" + Binder.getCallingPid()
11054                            + ") when registering receiver " + receiver);
11055                }
11056                if (callerApp.info.uid != Process.SYSTEM_UID &&
11057                        !callerApp.pkgList.contains(callerPackage)) {
11058                    throw new SecurityException("Given caller package " + callerPackage
11059                            + " is not running in process " + callerApp);
11060                }
11061                callingUid = callerApp.info.uid;
11062                callingPid = callerApp.pid;
11063            } else {
11064                callerPackage = null;
11065                callingUid = Binder.getCallingUid();
11066                callingPid = Binder.getCallingPid();
11067            }
11068
11069            userId = this.handleIncomingUserLocked(callingPid, callingUid, userId,
11070                    true, true, "registerReceiver", callerPackage);
11071
11072            List allSticky = null;
11073
11074            // Look for any matching sticky broadcasts...
11075            Iterator actions = filter.actionsIterator();
11076            if (actions != null) {
11077                while (actions.hasNext()) {
11078                    String action = (String)actions.next();
11079                    allSticky = getStickiesLocked(action, filter, allSticky,
11080                            UserHandle.USER_ALL);
11081                    allSticky = getStickiesLocked(action, filter, allSticky,
11082                            UserHandle.getUserId(callingUid));
11083                }
11084            } else {
11085                allSticky = getStickiesLocked(null, filter, allSticky,
11086                        UserHandle.USER_ALL);
11087                allSticky = getStickiesLocked(null, filter, allSticky,
11088                        UserHandle.getUserId(callingUid));
11089            }
11090
11091            // The first sticky in the list is returned directly back to
11092            // the client.
11093            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11094
11095            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11096                    + ": " + sticky);
11097
11098            if (receiver == null) {
11099                return sticky;
11100            }
11101
11102            ReceiverList rl
11103                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11104            if (rl == null) {
11105                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11106                        userId, receiver);
11107                if (rl.app != null) {
11108                    rl.app.receivers.add(rl);
11109                } else {
11110                    try {
11111                        receiver.asBinder().linkToDeath(rl, 0);
11112                    } catch (RemoteException e) {
11113                        return sticky;
11114                    }
11115                    rl.linkedToDeath = true;
11116                }
11117                mRegisteredReceivers.put(receiver.asBinder(), rl);
11118            } else if (rl.uid != callingUid) {
11119                throw new IllegalArgumentException(
11120                        "Receiver requested to register for uid " + callingUid
11121                        + " was previously registered for uid " + rl.uid);
11122            } else if (rl.pid != callingPid) {
11123                throw new IllegalArgumentException(
11124                        "Receiver requested to register for pid " + callingPid
11125                        + " was previously registered for pid " + rl.pid);
11126            } else if (rl.userId != userId) {
11127                throw new IllegalArgumentException(
11128                        "Receiver requested to register for user " + userId
11129                        + " was previously registered for user " + rl.userId);
11130            }
11131            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11132                    permission, callingUid, userId);
11133            rl.add(bf);
11134            if (!bf.debugCheck()) {
11135                Slog.w(TAG, "==> For Dynamic broadast");
11136            }
11137            mReceiverResolver.addFilter(bf);
11138
11139            // Enqueue broadcasts for all existing stickies that match
11140            // this filter.
11141            if (allSticky != null) {
11142                ArrayList receivers = new ArrayList();
11143                receivers.add(bf);
11144
11145                int N = allSticky.size();
11146                for (int i=0; i<N; i++) {
11147                    Intent intent = (Intent)allSticky.get(i);
11148                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11149                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11150                            null, -1, -1, null, receivers, null, 0, null, null,
11151                            false, true, true, -1);
11152                    queue.enqueueParallelBroadcastLocked(r);
11153                    queue.scheduleBroadcastsLocked();
11154                }
11155            }
11156
11157            return sticky;
11158        }
11159    }
11160
11161    public void unregisterReceiver(IIntentReceiver receiver) {
11162        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11163
11164        final long origId = Binder.clearCallingIdentity();
11165        try {
11166            boolean doTrim = false;
11167
11168            synchronized(this) {
11169                ReceiverList rl
11170                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11171                if (rl != null) {
11172                    if (rl.curBroadcast != null) {
11173                        BroadcastRecord r = rl.curBroadcast;
11174                        final boolean doNext = finishReceiverLocked(
11175                                receiver.asBinder(), r.resultCode, r.resultData,
11176                                r.resultExtras, r.resultAbort, true);
11177                        if (doNext) {
11178                            doTrim = true;
11179                            r.queue.processNextBroadcast(false);
11180                        }
11181                    }
11182
11183                    if (rl.app != null) {
11184                        rl.app.receivers.remove(rl);
11185                    }
11186                    removeReceiverLocked(rl);
11187                    if (rl.linkedToDeath) {
11188                        rl.linkedToDeath = false;
11189                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11190                    }
11191                }
11192            }
11193
11194            // If we actually concluded any broadcasts, we might now be able
11195            // to trim the recipients' apps from our working set
11196            if (doTrim) {
11197                trimApplications();
11198                return;
11199            }
11200
11201        } finally {
11202            Binder.restoreCallingIdentity(origId);
11203        }
11204    }
11205
11206    void removeReceiverLocked(ReceiverList rl) {
11207        mRegisteredReceivers.remove(rl.receiver.asBinder());
11208        int N = rl.size();
11209        for (int i=0; i<N; i++) {
11210            mReceiverResolver.removeFilter(rl.get(i));
11211        }
11212    }
11213
11214    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11215        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11216            ProcessRecord r = mLruProcesses.get(i);
11217            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11218                try {
11219                    r.thread.dispatchPackageBroadcast(cmd, packages);
11220                } catch (RemoteException ex) {
11221                }
11222            }
11223        }
11224    }
11225
11226    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11227            int[] users) {
11228        List<ResolveInfo> receivers = null;
11229        try {
11230            HashSet<ComponentName> singleUserReceivers = null;
11231            boolean scannedFirstReceivers = false;
11232            for (int user : users) {
11233                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11234                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11235                if (newReceivers != null && newReceivers.size() == 0) {
11236                    newReceivers = null;
11237                }
11238                if (receivers == null) {
11239                    receivers = newReceivers;
11240                } else if (newReceivers != null) {
11241                    // We need to concatenate the additional receivers
11242                    // found with what we have do far.  This would be easy,
11243                    // but we also need to de-dup any receivers that are
11244                    // singleUser.
11245                    if (!scannedFirstReceivers) {
11246                        // Collect any single user receivers we had already retrieved.
11247                        scannedFirstReceivers = true;
11248                        for (int i=0; i<receivers.size(); i++) {
11249                            ResolveInfo ri = receivers.get(i);
11250                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11251                                ComponentName cn = new ComponentName(
11252                                        ri.activityInfo.packageName, ri.activityInfo.name);
11253                                if (singleUserReceivers == null) {
11254                                    singleUserReceivers = new HashSet<ComponentName>();
11255                                }
11256                                singleUserReceivers.add(cn);
11257                            }
11258                        }
11259                    }
11260                    // Add the new results to the existing results, tracking
11261                    // and de-dupping single user receivers.
11262                    for (int i=0; i<newReceivers.size(); i++) {
11263                        ResolveInfo ri = receivers.get(i);
11264                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11265                            ComponentName cn = new ComponentName(
11266                                    ri.activityInfo.packageName, ri.activityInfo.name);
11267                            if (singleUserReceivers == null) {
11268                                singleUserReceivers = new HashSet<ComponentName>();
11269                            }
11270                            if (!singleUserReceivers.contains(cn)) {
11271                                singleUserReceivers.add(cn);
11272                                receivers.add(ri);
11273                            }
11274                        } else {
11275                            receivers.add(ri);
11276                        }
11277                    }
11278                }
11279            }
11280        } catch (RemoteException ex) {
11281            // pm is in same process, this will never happen.
11282        }
11283        return receivers;
11284    }
11285
11286    private final int broadcastIntentLocked(ProcessRecord callerApp,
11287            String callerPackage, Intent intent, String resolvedType,
11288            IIntentReceiver resultTo, int resultCode, String resultData,
11289            Bundle map, String requiredPermission,
11290            boolean ordered, boolean sticky, int callingPid, int callingUid,
11291            int userId) {
11292        intent = new Intent(intent);
11293
11294        // By default broadcasts do not go to stopped apps.
11295        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11296
11297        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11298            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11299            + " ordered=" + ordered + " userid=" + userId);
11300        if ((resultTo != null) && !ordered) {
11301            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11302        }
11303
11304        userId = handleIncomingUserLocked(callingPid, callingUid, userId,
11305                true, false, "broadcast", callerPackage);
11306
11307        // Make sure that the user who is receiving this broadcast is started
11308        // If not, we will just skip it.
11309        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11310            Slog.w(TAG, "Skipping broadcast of " + intent
11311                    + ": user " + userId + " is stopped");
11312            return ActivityManager.BROADCAST_SUCCESS;
11313        }
11314
11315        /*
11316         * Prevent non-system code (defined here to be non-persistent
11317         * processes) from sending protected broadcasts.
11318         */
11319        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11320            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11321            callingUid == 0) {
11322            // Always okay.
11323        } else if (callerApp == null || !callerApp.persistent) {
11324            try {
11325                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11326                        intent.getAction())) {
11327                    String msg = "Permission Denial: not allowed to send broadcast "
11328                            + intent.getAction() + " from pid="
11329                            + callingPid + ", uid=" + callingUid;
11330                    Slog.w(TAG, msg);
11331                    throw new SecurityException(msg);
11332                }
11333            } catch (RemoteException e) {
11334                Slog.w(TAG, "Remote exception", e);
11335                return ActivityManager.BROADCAST_SUCCESS;
11336            }
11337        }
11338
11339        // Handle special intents: if this broadcast is from the package
11340        // manager about a package being removed, we need to remove all of
11341        // its activities from the history stack.
11342        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11343                intent.getAction());
11344        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11345                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11346                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11347                || uidRemoved) {
11348            if (checkComponentPermission(
11349                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11350                    callingPid, callingUid, -1, true)
11351                    == PackageManager.PERMISSION_GRANTED) {
11352                if (uidRemoved) {
11353                    final Bundle intentExtras = intent.getExtras();
11354                    final int uid = intentExtras != null
11355                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11356                    if (uid >= 0) {
11357                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11358                        synchronized (bs) {
11359                            bs.removeUidStatsLocked(uid);
11360                        }
11361                    }
11362                } else {
11363                    // If resources are unavailable just force stop all
11364                    // those packages and flush the attribute cache as well.
11365                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11366                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11367                        if (list != null && (list.length > 0)) {
11368                            for (String pkg : list) {
11369                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11370                            }
11371                            sendPackageBroadcastLocked(
11372                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11373                        }
11374                    } else {
11375                        Uri data = intent.getData();
11376                        String ssp;
11377                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11378                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11379                                forceStopPackageLocked(ssp,
11380                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11381                                        false, userId);
11382                            }
11383                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11384                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11385                                        new String[] {ssp}, userId);
11386                            }
11387                        }
11388                    }
11389                }
11390            } else {
11391                String msg = "Permission Denial: " + intent.getAction()
11392                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11393                        + ", uid=" + callingUid + ")"
11394                        + " requires "
11395                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11396                Slog.w(TAG, msg);
11397                throw new SecurityException(msg);
11398            }
11399
11400        // Special case for adding a package: by default turn on compatibility
11401        // mode.
11402        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11403            Uri data = intent.getData();
11404            String ssp;
11405            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11406                mCompatModePackages.handlePackageAddedLocked(ssp,
11407                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11408            }
11409        }
11410
11411        /*
11412         * If this is the time zone changed action, queue up a message that will reset the timezone
11413         * of all currently running processes. This message will get queued up before the broadcast
11414         * happens.
11415         */
11416        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11417            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11418        }
11419
11420        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11421            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11422        }
11423
11424        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11425            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11426            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11427        }
11428
11429        // Add to the sticky list if requested.
11430        if (sticky) {
11431            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11432                    callingPid, callingUid)
11433                    != PackageManager.PERMISSION_GRANTED) {
11434                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11435                        + callingPid + ", uid=" + callingUid
11436                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11437                Slog.w(TAG, msg);
11438                throw new SecurityException(msg);
11439            }
11440            if (requiredPermission != null) {
11441                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11442                        + " and enforce permission " + requiredPermission);
11443                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11444            }
11445            if (intent.getComponent() != null) {
11446                throw new SecurityException(
11447                        "Sticky broadcasts can't target a specific component");
11448            }
11449            // We use userId directly here, since the "all" target is maintained
11450            // as a separate set of sticky broadcasts.
11451            if (userId != UserHandle.USER_ALL) {
11452                // But first, if this is not a broadcast to all users, then
11453                // make sure it doesn't conflict with an existing broadcast to
11454                // all users.
11455                HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11456                        UserHandle.USER_ALL);
11457                if (stickies != null) {
11458                    ArrayList<Intent> list = stickies.get(intent.getAction());
11459                    if (list != null) {
11460                        int N = list.size();
11461                        int i;
11462                        for (i=0; i<N; i++) {
11463                            if (intent.filterEquals(list.get(i))) {
11464                                throw new IllegalArgumentException(
11465                                        "Sticky broadcast " + intent + " for user "
11466                                        + userId + " conflicts with existing global broadcast");
11467                            }
11468                        }
11469                    }
11470                }
11471            }
11472            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11473            if (stickies == null) {
11474                stickies = new HashMap<String, ArrayList<Intent>>();
11475                mStickyBroadcasts.put(userId, stickies);
11476            }
11477            ArrayList<Intent> list = stickies.get(intent.getAction());
11478            if (list == null) {
11479                list = new ArrayList<Intent>();
11480                stickies.put(intent.getAction(), list);
11481            }
11482            int N = list.size();
11483            int i;
11484            for (i=0; i<N; i++) {
11485                if (intent.filterEquals(list.get(i))) {
11486                    // This sticky already exists, replace it.
11487                    list.set(i, new Intent(intent));
11488                    break;
11489                }
11490            }
11491            if (i >= N) {
11492                list.add(new Intent(intent));
11493            }
11494        }
11495
11496        int[] users;
11497        if (userId == UserHandle.USER_ALL) {
11498            // Caller wants broadcast to go to all started users.
11499            users = new int[mStartedUsers.size()];
11500            for (int i=0; i<mStartedUsers.size(); i++) {
11501                users[i] = mStartedUsers.keyAt(i);
11502            }
11503        } else {
11504            // Caller wants broadcast to go to one specific user.
11505            users = new int[] {userId};
11506        }
11507
11508        // Figure out who all will receive this broadcast.
11509        List receivers = null;
11510        List<BroadcastFilter> registeredReceivers = null;
11511        // Need to resolve the intent to interested receivers...
11512        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11513                 == 0) {
11514            receivers = collectReceiverComponents(intent, resolvedType, users);
11515        }
11516        if (intent.getComponent() == null) {
11517            registeredReceivers = mReceiverResolver.queryIntent(intent,
11518                    resolvedType, false, userId);
11519        }
11520
11521        final boolean replacePending =
11522                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11523
11524        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11525                + " replacePending=" + replacePending);
11526
11527        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11528        if (!ordered && NR > 0) {
11529            // If we are not serializing this broadcast, then send the
11530            // registered receivers separately so they don't wait for the
11531            // components to be launched.
11532            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11533            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11534                    callerPackage, callingPid, callingUid, requiredPermission,
11535                    registeredReceivers, resultTo, resultCode, resultData, map,
11536                    ordered, sticky, false, userId);
11537            if (DEBUG_BROADCAST) Slog.v(
11538                    TAG, "Enqueueing parallel broadcast " + r);
11539            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11540            if (!replaced) {
11541                queue.enqueueParallelBroadcastLocked(r);
11542                queue.scheduleBroadcastsLocked();
11543            }
11544            registeredReceivers = null;
11545            NR = 0;
11546        }
11547
11548        // Merge into one list.
11549        int ir = 0;
11550        if (receivers != null) {
11551            // A special case for PACKAGE_ADDED: do not allow the package
11552            // being added to see this broadcast.  This prevents them from
11553            // using this as a back door to get run as soon as they are
11554            // installed.  Maybe in the future we want to have a special install
11555            // broadcast or such for apps, but we'd like to deliberately make
11556            // this decision.
11557            String skipPackages[] = null;
11558            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11559                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11560                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11561                Uri data = intent.getData();
11562                if (data != null) {
11563                    String pkgName = data.getSchemeSpecificPart();
11564                    if (pkgName != null) {
11565                        skipPackages = new String[] { pkgName };
11566                    }
11567                }
11568            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11569                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11570            }
11571            if (skipPackages != null && (skipPackages.length > 0)) {
11572                for (String skipPackage : skipPackages) {
11573                    if (skipPackage != null) {
11574                        int NT = receivers.size();
11575                        for (int it=0; it<NT; it++) {
11576                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11577                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11578                                receivers.remove(it);
11579                                it--;
11580                                NT--;
11581                            }
11582                        }
11583                    }
11584                }
11585            }
11586
11587            int NT = receivers != null ? receivers.size() : 0;
11588            int it = 0;
11589            ResolveInfo curt = null;
11590            BroadcastFilter curr = null;
11591            while (it < NT && ir < NR) {
11592                if (curt == null) {
11593                    curt = (ResolveInfo)receivers.get(it);
11594                }
11595                if (curr == null) {
11596                    curr = registeredReceivers.get(ir);
11597                }
11598                if (curr.getPriority() >= curt.priority) {
11599                    // Insert this broadcast record into the final list.
11600                    receivers.add(it, curr);
11601                    ir++;
11602                    curr = null;
11603                    it++;
11604                    NT++;
11605                } else {
11606                    // Skip to the next ResolveInfo in the final list.
11607                    it++;
11608                    curt = null;
11609                }
11610            }
11611        }
11612        while (ir < NR) {
11613            if (receivers == null) {
11614                receivers = new ArrayList();
11615            }
11616            receivers.add(registeredReceivers.get(ir));
11617            ir++;
11618        }
11619
11620        if ((receivers != null && receivers.size() > 0)
11621                || resultTo != null) {
11622            BroadcastQueue queue = broadcastQueueForIntent(intent);
11623            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11624                    callerPackage, callingPid, callingUid, requiredPermission,
11625                    receivers, resultTo, resultCode, resultData, map, ordered,
11626                    sticky, false, userId);
11627            if (DEBUG_BROADCAST) Slog.v(
11628                    TAG, "Enqueueing ordered broadcast " + r
11629                    + ": prev had " + queue.mOrderedBroadcasts.size());
11630            if (DEBUG_BROADCAST) {
11631                int seq = r.intent.getIntExtra("seq", -1);
11632                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11633            }
11634            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11635            if (!replaced) {
11636                queue.enqueueOrderedBroadcastLocked(r);
11637                queue.scheduleBroadcastsLocked();
11638            }
11639        }
11640
11641        return ActivityManager.BROADCAST_SUCCESS;
11642    }
11643
11644    final Intent verifyBroadcastLocked(Intent intent) {
11645        // Refuse possible leaked file descriptors
11646        if (intent != null && intent.hasFileDescriptors() == true) {
11647            throw new IllegalArgumentException("File descriptors passed in Intent");
11648        }
11649
11650        int flags = intent.getFlags();
11651
11652        if (!mProcessesReady) {
11653            // if the caller really truly claims to know what they're doing, go
11654            // ahead and allow the broadcast without launching any receivers
11655            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11656                intent = new Intent(intent);
11657                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11658            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11659                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11660                        + " before boot completion");
11661                throw new IllegalStateException("Cannot broadcast before boot completed");
11662            }
11663        }
11664
11665        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11666            throw new IllegalArgumentException(
11667                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11668        }
11669
11670        return intent;
11671    }
11672
11673    public final int broadcastIntent(IApplicationThread caller,
11674            Intent intent, String resolvedType, IIntentReceiver resultTo,
11675            int resultCode, String resultData, Bundle map,
11676            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11677        enforceNotIsolatedCaller("broadcastIntent");
11678        synchronized(this) {
11679            intent = verifyBroadcastLocked(intent);
11680
11681            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11682            final int callingPid = Binder.getCallingPid();
11683            final int callingUid = Binder.getCallingUid();
11684            final long origId = Binder.clearCallingIdentity();
11685            int res = broadcastIntentLocked(callerApp,
11686                    callerApp != null ? callerApp.info.packageName : null,
11687                    intent, resolvedType, resultTo,
11688                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11689                    callingPid, callingUid, userId);
11690            Binder.restoreCallingIdentity(origId);
11691            return res;
11692        }
11693    }
11694
11695    int broadcastIntentInPackage(String packageName, int uid,
11696            Intent intent, String resolvedType, IIntentReceiver resultTo,
11697            int resultCode, String resultData, Bundle map,
11698            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11699        synchronized(this) {
11700            intent = verifyBroadcastLocked(intent);
11701
11702            final long origId = Binder.clearCallingIdentity();
11703            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11704                    resultTo, resultCode, resultData, map, requiredPermission,
11705                    serialized, sticky, -1, uid, userId);
11706            Binder.restoreCallingIdentity(origId);
11707            return res;
11708        }
11709    }
11710
11711    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11712        // Refuse possible leaked file descriptors
11713        if (intent != null && intent.hasFileDescriptors() == true) {
11714            throw new IllegalArgumentException("File descriptors passed in Intent");
11715        }
11716
11717        userId = handleIncomingUserLocked(Binder.getCallingPid(),
11718                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
11719
11720        synchronized(this) {
11721            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11722                    != PackageManager.PERMISSION_GRANTED) {
11723                String msg = "Permission Denial: unbroadcastIntent() from pid="
11724                        + Binder.getCallingPid()
11725                        + ", uid=" + Binder.getCallingUid()
11726                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11727                Slog.w(TAG, msg);
11728                throw new SecurityException(msg);
11729            }
11730            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11731            if (stickies != null) {
11732                ArrayList<Intent> list = stickies.get(intent.getAction());
11733                if (list != null) {
11734                    int N = list.size();
11735                    int i;
11736                    for (i=0; i<N; i++) {
11737                        if (intent.filterEquals(list.get(i))) {
11738                            list.remove(i);
11739                            break;
11740                        }
11741                    }
11742                    if (list.size() <= 0) {
11743                        stickies.remove(intent.getAction());
11744                    }
11745                }
11746                if (stickies.size() <= 0) {
11747                    mStickyBroadcasts.remove(userId);
11748                }
11749            }
11750        }
11751    }
11752
11753    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11754            String resultData, Bundle resultExtras, boolean resultAbort,
11755            boolean explicit) {
11756        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11757        if (r == null) {
11758            Slog.w(TAG, "finishReceiver called but not found on queue");
11759            return false;
11760        }
11761
11762        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11763                explicit);
11764    }
11765
11766    public void finishReceiver(IBinder who, int resultCode, String resultData,
11767            Bundle resultExtras, boolean resultAbort) {
11768        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11769
11770        // Refuse possible leaked file descriptors
11771        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11772            throw new IllegalArgumentException("File descriptors passed in Bundle");
11773        }
11774
11775        final long origId = Binder.clearCallingIdentity();
11776        try {
11777            boolean doNext = false;
11778            BroadcastRecord r = null;
11779
11780            synchronized(this) {
11781                r = broadcastRecordForReceiverLocked(who);
11782                if (r != null) {
11783                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11784                        resultData, resultExtras, resultAbort, true);
11785                }
11786            }
11787
11788            if (doNext) {
11789                r.queue.processNextBroadcast(false);
11790            }
11791            trimApplications();
11792        } finally {
11793            Binder.restoreCallingIdentity(origId);
11794        }
11795    }
11796
11797    // =========================================================
11798    // INSTRUMENTATION
11799    // =========================================================
11800
11801    public boolean startInstrumentation(ComponentName className,
11802            String profileFile, int flags, Bundle arguments,
11803            IInstrumentationWatcher watcher) {
11804        enforceNotIsolatedCaller("startInstrumentation");
11805        // Refuse possible leaked file descriptors
11806        if (arguments != null && arguments.hasFileDescriptors()) {
11807            throw new IllegalArgumentException("File descriptors passed in Bundle");
11808        }
11809
11810        synchronized(this) {
11811            InstrumentationInfo ii = null;
11812            ApplicationInfo ai = null;
11813            try {
11814                ii = mContext.getPackageManager().getInstrumentationInfo(
11815                    className, STOCK_PM_FLAGS);
11816                ai = mContext.getPackageManager().getApplicationInfo(
11817                        ii.targetPackage, STOCK_PM_FLAGS);
11818            } catch (PackageManager.NameNotFoundException e) {
11819            }
11820            if (ii == null) {
11821                reportStartInstrumentationFailure(watcher, className,
11822                        "Unable to find instrumentation info for: " + className);
11823                return false;
11824            }
11825            if (ai == null) {
11826                reportStartInstrumentationFailure(watcher, className,
11827                        "Unable to find instrumentation target package: " + ii.targetPackage);
11828                return false;
11829            }
11830
11831            int match = mContext.getPackageManager().checkSignatures(
11832                    ii.targetPackage, ii.packageName);
11833            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11834                String msg = "Permission Denial: starting instrumentation "
11835                        + className + " from pid="
11836                        + Binder.getCallingPid()
11837                        + ", uid=" + Binder.getCallingPid()
11838                        + " not allowed because package " + ii.packageName
11839                        + " does not have a signature matching the target "
11840                        + ii.targetPackage;
11841                reportStartInstrumentationFailure(watcher, className, msg);
11842                throw new SecurityException(msg);
11843            }
11844
11845            int userId = UserHandle.getCallingUserId();
11846            final long origId = Binder.clearCallingIdentity();
11847            // Instrumentation can kill and relaunch even persistent processes
11848            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
11849            ProcessRecord app = addAppLocked(ai, false);
11850            app.instrumentationClass = className;
11851            app.instrumentationInfo = ai;
11852            app.instrumentationProfileFile = profileFile;
11853            app.instrumentationArguments = arguments;
11854            app.instrumentationWatcher = watcher;
11855            app.instrumentationResultClass = className;
11856            Binder.restoreCallingIdentity(origId);
11857        }
11858
11859        return true;
11860    }
11861
11862    /**
11863     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11864     * error to the logs, but if somebody is watching, send the report there too.  This enables
11865     * the "am" command to report errors with more information.
11866     *
11867     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11868     * @param cn The component name of the instrumentation.
11869     * @param report The error report.
11870     */
11871    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11872            ComponentName cn, String report) {
11873        Slog.w(TAG, report);
11874        try {
11875            if (watcher != null) {
11876                Bundle results = new Bundle();
11877                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11878                results.putString("Error", report);
11879                watcher.instrumentationStatus(cn, -1, results);
11880            }
11881        } catch (RemoteException e) {
11882            Slog.w(TAG, e);
11883        }
11884    }
11885
11886    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11887        if (app.instrumentationWatcher != null) {
11888            try {
11889                // NOTE:  IInstrumentationWatcher *must* be oneway here
11890                app.instrumentationWatcher.instrumentationFinished(
11891                    app.instrumentationClass,
11892                    resultCode,
11893                    results);
11894            } catch (RemoteException e) {
11895            }
11896        }
11897        app.instrumentationWatcher = null;
11898        app.instrumentationClass = null;
11899        app.instrumentationInfo = null;
11900        app.instrumentationProfileFile = null;
11901        app.instrumentationArguments = null;
11902
11903        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
11904    }
11905
11906    public void finishInstrumentation(IApplicationThread target,
11907            int resultCode, Bundle results) {
11908        int userId = UserHandle.getCallingUserId();
11909        // Refuse possible leaked file descriptors
11910        if (results != null && results.hasFileDescriptors()) {
11911            throw new IllegalArgumentException("File descriptors passed in Intent");
11912        }
11913
11914        synchronized(this) {
11915            ProcessRecord app = getRecordForAppLocked(target);
11916            if (app == null) {
11917                Slog.w(TAG, "finishInstrumentation: no app for " + target);
11918                return;
11919            }
11920            final long origId = Binder.clearCallingIdentity();
11921            finishInstrumentationLocked(app, resultCode, results);
11922            Binder.restoreCallingIdentity(origId);
11923        }
11924    }
11925
11926    // =========================================================
11927    // CONFIGURATION
11928    // =========================================================
11929
11930    public ConfigurationInfo getDeviceConfigurationInfo() {
11931        ConfigurationInfo config = new ConfigurationInfo();
11932        synchronized (this) {
11933            config.reqTouchScreen = mConfiguration.touchscreen;
11934            config.reqKeyboardType = mConfiguration.keyboard;
11935            config.reqNavigation = mConfiguration.navigation;
11936            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11937                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
11938                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11939            }
11940            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11941                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
11942                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11943            }
11944            config.reqGlEsVersion = GL_ES_VERSION;
11945        }
11946        return config;
11947    }
11948
11949    public Configuration getConfiguration() {
11950        Configuration ci;
11951        synchronized(this) {
11952            ci = new Configuration(mConfiguration);
11953        }
11954        return ci;
11955    }
11956
11957    public void updatePersistentConfiguration(Configuration values) {
11958        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11959                "updateConfiguration()");
11960        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
11961                "updateConfiguration()");
11962        if (values == null) {
11963            throw new NullPointerException("Configuration must not be null");
11964        }
11965
11966        synchronized(this) {
11967            final long origId = Binder.clearCallingIdentity();
11968            updateConfigurationLocked(values, null, true, false);
11969            Binder.restoreCallingIdentity(origId);
11970        }
11971    }
11972
11973    public void updateConfiguration(Configuration values) {
11974        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11975                "updateConfiguration()");
11976
11977        synchronized(this) {
11978            if (values == null && mWindowManager != null) {
11979                // sentinel: fetch the current configuration from the window manager
11980                values = mWindowManager.computeNewConfiguration();
11981            }
11982
11983            if (mWindowManager != null) {
11984                mProcessList.applyDisplaySize(mWindowManager);
11985            }
11986
11987            final long origId = Binder.clearCallingIdentity();
11988            if (values != null) {
11989                Settings.System.clearConfiguration(values);
11990            }
11991            updateConfigurationLocked(values, null, false, false);
11992            Binder.restoreCallingIdentity(origId);
11993        }
11994    }
11995
11996    /**
11997     * Do either or both things: (1) change the current configuration, and (2)
11998     * make sure the given activity is running with the (now) current
11999     * configuration.  Returns true if the activity has been left running, or
12000     * false if <var>starting</var> is being destroyed to match the new
12001     * configuration.
12002     * @param persistent TODO
12003     */
12004    boolean updateConfigurationLocked(Configuration values,
12005            ActivityRecord starting, boolean persistent, boolean initLocale) {
12006        // do nothing if we are headless
12007        if (mHeadless) return true;
12008
12009        int changes = 0;
12010
12011        boolean kept = true;
12012
12013        if (values != null) {
12014            Configuration newConfig = new Configuration(mConfiguration);
12015            changes = newConfig.updateFrom(values);
12016            if (changes != 0) {
12017                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12018                    Slog.i(TAG, "Updating configuration to: " + values);
12019                }
12020
12021                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12022
12023                if (values.locale != null && !initLocale) {
12024                    saveLocaleLocked(values.locale,
12025                                     !values.locale.equals(mConfiguration.locale),
12026                                     values.userSetLocale);
12027                }
12028
12029                mConfigurationSeq++;
12030                if (mConfigurationSeq <= 0) {
12031                    mConfigurationSeq = 1;
12032                }
12033                newConfig.seq = mConfigurationSeq;
12034                mConfiguration = newConfig;
12035                Slog.i(TAG, "Config changed: " + newConfig);
12036
12037                final Configuration configCopy = new Configuration(mConfiguration);
12038
12039                // TODO: If our config changes, should we auto dismiss any currently
12040                // showing dialogs?
12041                mShowDialogs = shouldShowDialogs(newConfig);
12042
12043                AttributeCache ac = AttributeCache.instance();
12044                if (ac != null) {
12045                    ac.updateConfiguration(configCopy);
12046                }
12047
12048                // Make sure all resources in our process are updated
12049                // right now, so that anyone who is going to retrieve
12050                // resource values after we return will be sure to get
12051                // the new ones.  This is especially important during
12052                // boot, where the first config change needs to guarantee
12053                // all resources have that config before following boot
12054                // code is executed.
12055                mSystemThread.applyConfigurationToResources(configCopy);
12056
12057                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12058                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12059                    msg.obj = new Configuration(configCopy);
12060                    mHandler.sendMessage(msg);
12061                }
12062
12063                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12064                    ProcessRecord app = mLruProcesses.get(i);
12065                    try {
12066                        if (app.thread != null) {
12067                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12068                                    + app.processName + " new config " + mConfiguration);
12069                            app.thread.scheduleConfigurationChanged(configCopy);
12070                        }
12071                    } catch (Exception e) {
12072                    }
12073                }
12074                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12075                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12076                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
12077                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12078                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12079                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12080                    broadcastIntentLocked(null, null,
12081                            new Intent(Intent.ACTION_LOCALE_CHANGED),
12082                            null, null, 0, null, null,
12083                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12084                }
12085            }
12086        }
12087
12088        if (changes != 0 && starting == null) {
12089            // If the configuration changed, and the caller is not already
12090            // in the process of starting an activity, then find the top
12091            // activity to check if its configuration needs to change.
12092            starting = mMainStack.topRunningActivityLocked(null);
12093        }
12094
12095        if (starting != null) {
12096            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12097            // And we need to make sure at this point that all other activities
12098            // are made visible with the correct configuration.
12099            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12100        }
12101
12102        if (values != null && mWindowManager != null) {
12103            mWindowManager.setNewConfiguration(mConfiguration);
12104        }
12105
12106        return kept;
12107    }
12108
12109    /**
12110     * Decide based on the configuration whether we should shouw the ANR,
12111     * crash, etc dialogs.  The idea is that if there is no affordnace to
12112     * press the on-screen buttons, we shouldn't show the dialog.
12113     *
12114     * A thought: SystemUI might also want to get told about this, the Power
12115     * dialog / global actions also might want different behaviors.
12116     */
12117    private static final boolean shouldShowDialogs(Configuration config) {
12118        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12119                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12120    }
12121
12122    /**
12123     * Save the locale.  You must be inside a synchronized (this) block.
12124     */
12125    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12126        if(isDiff) {
12127            SystemProperties.set("user.language", l.getLanguage());
12128            SystemProperties.set("user.region", l.getCountry());
12129        }
12130
12131        if(isPersist) {
12132            SystemProperties.set("persist.sys.language", l.getLanguage());
12133            SystemProperties.set("persist.sys.country", l.getCountry());
12134            SystemProperties.set("persist.sys.localevar", l.getVariant());
12135        }
12136    }
12137
12138    @Override
12139    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12140        ActivityRecord srec = ActivityRecord.forToken(token);
12141        return srec != null && srec.task.affinity != null &&
12142                srec.task.affinity.equals(destAffinity);
12143    }
12144
12145    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12146            Intent resultData) {
12147        ComponentName dest = destIntent.getComponent();
12148
12149        synchronized (this) {
12150            ActivityRecord srec = ActivityRecord.forToken(token);
12151            if (srec == null) {
12152                return false;
12153            }
12154            ArrayList<ActivityRecord> history = srec.stack.mHistory;
12155            final int start = history.indexOf(srec);
12156            if (start < 0) {
12157                // Current activity is not in history stack; do nothing.
12158                return false;
12159            }
12160            int finishTo = start - 1;
12161            ActivityRecord parent = null;
12162            boolean foundParentInTask = false;
12163            if (dest != null) {
12164                TaskRecord tr = srec.task;
12165                for (int i = start - 1; i >= 0; i--) {
12166                    ActivityRecord r = history.get(i);
12167                    if (tr != r.task) {
12168                        // Couldn't find parent in the same task; stop at the one above this.
12169                        // (Root of current task; in-app "home" behavior)
12170                        // Always at least finish the current activity.
12171                        finishTo = Math.min(start - 1, i + 1);
12172                        parent = history.get(finishTo);
12173                        break;
12174                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
12175                            r.info.name.equals(dest.getClassName())) {
12176                        finishTo = i;
12177                        parent = r;
12178                        foundParentInTask = true;
12179                        break;
12180                    }
12181                }
12182            }
12183
12184            if (mController != null) {
12185                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12186                if (next != null) {
12187                    // ask watcher if this is allowed
12188                    boolean resumeOK = true;
12189                    try {
12190                        resumeOK = mController.activityResuming(next.packageName);
12191                    } catch (RemoteException e) {
12192                        mController = null;
12193                    }
12194
12195                    if (!resumeOK) {
12196                        return false;
12197                    }
12198                }
12199            }
12200            final long origId = Binder.clearCallingIdentity();
12201            for (int i = start; i > finishTo; i--) {
12202                ActivityRecord r = history.get(i);
12203                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12204                        "navigate-up");
12205                // Only return the supplied result for the first activity finished
12206                resultCode = Activity.RESULT_CANCELED;
12207                resultData = null;
12208            }
12209
12210            if (parent != null && foundParentInTask) {
12211                final int parentLaunchMode = parent.info.launchMode;
12212                final int destIntentFlags = destIntent.getFlags();
12213                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12214                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12215                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12216                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12217                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12218                } else {
12219                    try {
12220                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12221                                destIntent.getComponent(), 0, UserHandle.getCallingUserId());
12222                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12223                                null, aInfo, parent.appToken, null,
12224                                0, -1, parent.launchedFromUid, 0, null, true, null);
12225                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12226                    } catch (RemoteException e) {
12227                        foundParentInTask = false;
12228                    }
12229                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12230                            resultData, "navigate-up");
12231                }
12232            }
12233            Binder.restoreCallingIdentity(origId);
12234            return foundParentInTask;
12235        }
12236    }
12237
12238    public int getLaunchedFromUid(IBinder activityToken) {
12239        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12240        if (srec == null) {
12241            return -1;
12242        }
12243        return srec.launchedFromUid;
12244    }
12245
12246    // =========================================================
12247    // LIFETIME MANAGEMENT
12248    // =========================================================
12249
12250    // Returns which broadcast queue the app is the current [or imminent] receiver
12251    // on, or 'null' if the app is not an active broadcast recipient.
12252    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12253        BroadcastRecord r = app.curReceiver;
12254        if (r != null) {
12255            return r.queue;
12256        }
12257
12258        // It's not the current receiver, but it might be starting up to become one
12259        synchronized (this) {
12260            for (BroadcastQueue queue : mBroadcastQueues) {
12261                r = queue.mPendingBroadcast;
12262                if (r != null && r.curApp == app) {
12263                    // found it; report which queue it's in
12264                    return queue;
12265                }
12266            }
12267        }
12268
12269        return null;
12270    }
12271
12272    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12273            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12274        if (mAdjSeq == app.adjSeq) {
12275            // This adjustment has already been computed.  If we are calling
12276            // from the top, we may have already computed our adjustment with
12277            // an earlier hidden adjustment that isn't really for us... if
12278            // so, use the new hidden adjustment.
12279            if (!recursed && app.hidden) {
12280                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12281                        app.hasActivities ? hiddenAdj : emptyAdj;
12282            }
12283            return app.curRawAdj;
12284        }
12285
12286        if (app.thread == null) {
12287            app.adjSeq = mAdjSeq;
12288            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12289            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12290        }
12291
12292        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12293        app.adjSource = null;
12294        app.adjTarget = null;
12295        app.empty = false;
12296        app.hidden = false;
12297
12298        final int activitiesSize = app.activities.size();
12299
12300        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12301            // The max adjustment doesn't allow this app to be anything
12302            // below foreground, so it is not worth doing work for it.
12303            app.adjType = "fixed";
12304            app.adjSeq = mAdjSeq;
12305            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12306            app.hasActivities = false;
12307            app.foregroundActivities = false;
12308            app.keeping = true;
12309            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12310            // System process can do UI, and when they do we want to have
12311            // them trim their memory after the user leaves the UI.  To
12312            // facilitate this, here we need to determine whether or not it
12313            // is currently showing UI.
12314            app.systemNoUi = true;
12315            if (app == TOP_APP) {
12316                app.systemNoUi = false;
12317                app.hasActivities = true;
12318            } else if (activitiesSize > 0) {
12319                for (int j = 0; j < activitiesSize; j++) {
12320                    final ActivityRecord r = app.activities.get(j);
12321                    if (r.visible) {
12322                        app.systemNoUi = false;
12323                    }
12324                    if (r.app == app) {
12325                        app.hasActivities = true;
12326                    }
12327                }
12328            }
12329            return (app.curAdj=app.maxAdj);
12330        }
12331
12332        app.keeping = false;
12333        app.systemNoUi = false;
12334        app.hasActivities = false;
12335
12336        // Determine the importance of the process, starting with most
12337        // important to least, and assign an appropriate OOM adjustment.
12338        int adj;
12339        int schedGroup;
12340        boolean foregroundActivities = false;
12341        boolean interesting = false;
12342        BroadcastQueue queue;
12343        if (app == TOP_APP) {
12344            // The last app on the list is the foreground app.
12345            adj = ProcessList.FOREGROUND_APP_ADJ;
12346            schedGroup = Process.THREAD_GROUP_DEFAULT;
12347            app.adjType = "top-activity";
12348            foregroundActivities = true;
12349            interesting = true;
12350            app.hasActivities = true;
12351        } else if (app.instrumentationClass != null) {
12352            // Don't want to kill running instrumentation.
12353            adj = ProcessList.FOREGROUND_APP_ADJ;
12354            schedGroup = Process.THREAD_GROUP_DEFAULT;
12355            app.adjType = "instrumentation";
12356            interesting = true;
12357        } else if ((queue = isReceivingBroadcast(app)) != null) {
12358            // An app that is currently receiving a broadcast also
12359            // counts as being in the foreground for OOM killer purposes.
12360            // It's placed in a sched group based on the nature of the
12361            // broadcast as reflected by which queue it's active in.
12362            adj = ProcessList.FOREGROUND_APP_ADJ;
12363            schedGroup = (queue == mFgBroadcastQueue)
12364                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12365            app.adjType = "broadcast";
12366        } else if (app.executingServices.size() > 0) {
12367            // An app that is currently executing a service callback also
12368            // counts as being in the foreground.
12369            adj = ProcessList.FOREGROUND_APP_ADJ;
12370            schedGroup = Process.THREAD_GROUP_DEFAULT;
12371            app.adjType = "exec-service";
12372        } else {
12373            // Assume process is hidden (has activities); we will correct
12374            // later if this is not the case.
12375            adj = hiddenAdj;
12376            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12377            app.hidden = true;
12378            app.adjType = "bg-activities";
12379        }
12380
12381        boolean hasStoppingActivities = false;
12382
12383        // Examine all activities if not already foreground.
12384        if (!foregroundActivities && activitiesSize > 0) {
12385            for (int j = 0; j < activitiesSize; j++) {
12386                final ActivityRecord r = app.activities.get(j);
12387                if (r.visible) {
12388                    // App has a visible activity; only upgrade adjustment.
12389                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12390                        adj = ProcessList.VISIBLE_APP_ADJ;
12391                        app.adjType = "visible";
12392                    }
12393                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12394                    app.hidden = false;
12395                    app.hasActivities = true;
12396                    foregroundActivities = true;
12397                    break;
12398                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12399                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12400                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12401                        app.adjType = "pausing";
12402                    }
12403                    app.hidden = false;
12404                    foregroundActivities = true;
12405                } else if (r.state == ActivityState.STOPPING) {
12406                    // We will apply the actual adjustment later, because
12407                    // we want to allow this process to immediately go through
12408                    // any memory trimming that is in effect.
12409                    app.hidden = false;
12410                    foregroundActivities = true;
12411                    hasStoppingActivities = true;
12412                }
12413                if (r.app == app) {
12414                    app.hasActivities = true;
12415                }
12416            }
12417        }
12418
12419        if (adj == hiddenAdj && !app.hasActivities) {
12420            // Whoops, this process is completely empty as far as we know
12421            // at this point.
12422            adj = emptyAdj;
12423            app.empty = true;
12424            app.adjType = "bg-empty";
12425        }
12426
12427        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12428            if (app.foregroundServices) {
12429                // The user is aware of this app, so make it visible.
12430                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12431                app.hidden = false;
12432                app.adjType = "foreground-service";
12433                schedGroup = Process.THREAD_GROUP_DEFAULT;
12434            } else if (app.forcingToForeground != null) {
12435                // The user is aware of this app, so make it visible.
12436                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12437                app.hidden = false;
12438                app.adjType = "force-foreground";
12439                app.adjSource = app.forcingToForeground;
12440                schedGroup = Process.THREAD_GROUP_DEFAULT;
12441            }
12442        }
12443
12444        if (app.foregroundServices) {
12445            interesting = true;
12446        }
12447
12448        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12449            // We don't want to kill the current heavy-weight process.
12450            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12451            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12452            app.hidden = false;
12453            app.adjType = "heavy";
12454        }
12455
12456        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12457            // This process is hosting what we currently consider to be the
12458            // home app, so we don't want to let it go into the background.
12459            adj = ProcessList.HOME_APP_ADJ;
12460            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12461            app.hidden = false;
12462            app.adjType = "home";
12463        }
12464
12465        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12466                && app.activities.size() > 0) {
12467            // This was the previous process that showed UI to the user.
12468            // We want to try to keep it around more aggressively, to give
12469            // a good experience around switching between two apps.
12470            adj = ProcessList.PREVIOUS_APP_ADJ;
12471            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12472            app.hidden = false;
12473            app.adjType = "previous";
12474        }
12475
12476        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12477                + " reason=" + app.adjType);
12478
12479        // By default, we use the computed adjustment.  It may be changed if
12480        // there are applications dependent on our services or providers, but
12481        // this gives us a baseline and makes sure we don't get into an
12482        // infinite recursion.
12483        app.adjSeq = mAdjSeq;
12484        app.curRawAdj = app.nonStoppingAdj = adj;
12485
12486        if (mBackupTarget != null && app == mBackupTarget.app) {
12487            // If possible we want to avoid killing apps while they're being backed up
12488            if (adj > ProcessList.BACKUP_APP_ADJ) {
12489                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12490                adj = ProcessList.BACKUP_APP_ADJ;
12491                app.adjType = "backup";
12492                app.hidden = false;
12493            }
12494        }
12495
12496        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12497                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12498            final long now = SystemClock.uptimeMillis();
12499            // This process is more important if the top activity is
12500            // bound to the service.
12501            Iterator<ServiceRecord> jt = app.services.iterator();
12502            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12503                ServiceRecord s = jt.next();
12504                if (s.startRequested) {
12505                    if (app.hasShownUi && app != mHomeProcess) {
12506                        // If this process has shown some UI, let it immediately
12507                        // go to the LRU list because it may be pretty heavy with
12508                        // UI stuff.  We'll tag it with a label just to help
12509                        // debug and understand what is going on.
12510                        if (adj > ProcessList.SERVICE_ADJ) {
12511                            app.adjType = "started-bg-ui-services";
12512                        }
12513                    } else {
12514                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12515                            // This service has seen some activity within
12516                            // recent memory, so we will keep its process ahead
12517                            // of the background processes.
12518                            if (adj > ProcessList.SERVICE_ADJ) {
12519                                adj = ProcessList.SERVICE_ADJ;
12520                                app.adjType = "started-services";
12521                                app.hidden = false;
12522                            }
12523                        }
12524                        // If we have let the service slide into the background
12525                        // state, still have some text describing what it is doing
12526                        // even though the service no longer has an impact.
12527                        if (adj > ProcessList.SERVICE_ADJ) {
12528                            app.adjType = "started-bg-services";
12529                        }
12530                    }
12531                    // Don't kill this process because it is doing work; it
12532                    // has said it is doing work.
12533                    app.keeping = true;
12534                }
12535                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12536                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12537                    Iterator<ArrayList<ConnectionRecord>> kt
12538                            = s.connections.values().iterator();
12539                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12540                        ArrayList<ConnectionRecord> clist = kt.next();
12541                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12542                            // XXX should compute this based on the max of
12543                            // all connected clients.
12544                            ConnectionRecord cr = clist.get(i);
12545                            if (cr.binding.client == app) {
12546                                // Binding to ourself is not interesting.
12547                                continue;
12548                            }
12549                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12550                                ProcessRecord client = cr.binding.client;
12551                                int clientAdj = adj;
12552                                int myHiddenAdj = hiddenAdj;
12553                                if (myHiddenAdj > client.hiddenAdj) {
12554                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12555                                        myHiddenAdj = client.hiddenAdj;
12556                                    } else {
12557                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12558                                    }
12559                                }
12560                                int myEmptyAdj = emptyAdj;
12561                                if (myEmptyAdj > client.emptyAdj) {
12562                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12563                                        myEmptyAdj = client.emptyAdj;
12564                                    } else {
12565                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12566                                    }
12567                                }
12568                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12569                                        myEmptyAdj, TOP_APP, true, doingAll);
12570                                String adjType = null;
12571                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12572                                    // Not doing bind OOM management, so treat
12573                                    // this guy more like a started service.
12574                                    if (app.hasShownUi && app != mHomeProcess) {
12575                                        // If this process has shown some UI, let it immediately
12576                                        // go to the LRU list because it may be pretty heavy with
12577                                        // UI stuff.  We'll tag it with a label just to help
12578                                        // debug and understand what is going on.
12579                                        if (adj > clientAdj) {
12580                                            adjType = "bound-bg-ui-services";
12581                                        }
12582                                        app.hidden = false;
12583                                        clientAdj = adj;
12584                                    } else {
12585                                        if (now >= (s.lastActivity
12586                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12587                                            // This service has not seen activity within
12588                                            // recent memory, so allow it to drop to the
12589                                            // LRU list if there is no other reason to keep
12590                                            // it around.  We'll also tag it with a label just
12591                                            // to help debug and undertand what is going on.
12592                                            if (adj > clientAdj) {
12593                                                adjType = "bound-bg-services";
12594                                            }
12595                                            clientAdj = adj;
12596                                        }
12597                                    }
12598                                }
12599                                if (adj > clientAdj) {
12600                                    // If this process has recently shown UI, and
12601                                    // the process that is binding to it is less
12602                                    // important than being visible, then we don't
12603                                    // care about the binding as much as we care
12604                                    // about letting this process get into the LRU
12605                                    // list to be killed and restarted if needed for
12606                                    // memory.
12607                                    if (app.hasShownUi && app != mHomeProcess
12608                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12609                                        adjType = "bound-bg-ui-services";
12610                                    } else {
12611                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12612                                                |Context.BIND_IMPORTANT)) != 0) {
12613                                            adj = clientAdj;
12614                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12615                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12616                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12617                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12618                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12619                                            adj = clientAdj;
12620                                        } else {
12621                                            app.pendingUiClean = true;
12622                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12623                                                adj = ProcessList.VISIBLE_APP_ADJ;
12624                                            }
12625                                        }
12626                                        if (!client.hidden) {
12627                                            app.hidden = false;
12628                                        }
12629                                        if (client.keeping) {
12630                                            app.keeping = true;
12631                                        }
12632                                        adjType = "service";
12633                                    }
12634                                }
12635                                if (adjType != null) {
12636                                    app.adjType = adjType;
12637                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12638                                            .REASON_SERVICE_IN_USE;
12639                                    app.adjSource = cr.binding.client;
12640                                    app.adjSourceOom = clientAdj;
12641                                    app.adjTarget = s.name;
12642                                }
12643                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12644                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12645                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12646                                    }
12647                                }
12648                            }
12649                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12650                                ActivityRecord a = cr.activity;
12651                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12652                                        (a.visible || a.state == ActivityState.RESUMED
12653                                         || a.state == ActivityState.PAUSING)) {
12654                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12655                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12656                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12657                                    }
12658                                    app.hidden = false;
12659                                    app.adjType = "service";
12660                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12661                                            .REASON_SERVICE_IN_USE;
12662                                    app.adjSource = a;
12663                                    app.adjSourceOom = adj;
12664                                    app.adjTarget = s.name;
12665                                }
12666                            }
12667                        }
12668                    }
12669                }
12670            }
12671
12672            // Finally, if this process has active services running in it, we
12673            // would like to avoid killing it unless it would prevent the current
12674            // application from running.  By default we put the process in
12675            // with the rest of the background processes; as we scan through
12676            // its services we may bump it up from there.
12677            if (adj > hiddenAdj) {
12678                adj = hiddenAdj;
12679                app.hidden = false;
12680                app.adjType = "bg-services";
12681            }
12682        }
12683
12684        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12685                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12686            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12687            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12688                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12689                ContentProviderRecord cpr = jt.next();
12690                for (int i = cpr.connections.size()-1;
12691                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12692                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12693                        i--) {
12694                    ContentProviderConnection conn = cpr.connections.get(i);
12695                    ProcessRecord client = conn.client;
12696                    if (client == app) {
12697                        // Being our own client is not interesting.
12698                        continue;
12699                    }
12700                    int myHiddenAdj = hiddenAdj;
12701                    if (myHiddenAdj > client.hiddenAdj) {
12702                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12703                            myHiddenAdj = client.hiddenAdj;
12704                        } else {
12705                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12706                        }
12707                    }
12708                    int myEmptyAdj = emptyAdj;
12709                    if (myEmptyAdj > client.emptyAdj) {
12710                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12711                            myEmptyAdj = client.emptyAdj;
12712                        } else {
12713                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12714                        }
12715                    }
12716                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12717                            myEmptyAdj, TOP_APP, true, doingAll);
12718                    if (adj > clientAdj) {
12719                        if (app.hasShownUi && app != mHomeProcess
12720                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12721                            app.adjType = "bg-ui-provider";
12722                        } else {
12723                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12724                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12725                            app.adjType = "provider";
12726                        }
12727                        if (!client.hidden) {
12728                            app.hidden = false;
12729                        }
12730                        if (client.keeping) {
12731                            app.keeping = true;
12732                        }
12733                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12734                                .REASON_PROVIDER_IN_USE;
12735                        app.adjSource = client;
12736                        app.adjSourceOom = clientAdj;
12737                        app.adjTarget = cpr.name;
12738                    }
12739                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12740                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12741                    }
12742                }
12743                // If the provider has external (non-framework) process
12744                // dependencies, ensure that its adjustment is at least
12745                // FOREGROUND_APP_ADJ.
12746                if (cpr.hasExternalProcessHandles()) {
12747                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12748                        adj = ProcessList.FOREGROUND_APP_ADJ;
12749                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12750                        app.hidden = false;
12751                        app.keeping = true;
12752                        app.adjType = "provider";
12753                        app.adjTarget = cpr.name;
12754                    }
12755                }
12756            }
12757        }
12758
12759        if (adj == ProcessList.SERVICE_ADJ) {
12760            if (doingAll) {
12761                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12762                mNewNumServiceProcs++;
12763            }
12764            if (app.serviceb) {
12765                adj = ProcessList.SERVICE_B_ADJ;
12766            }
12767        } else {
12768            app.serviceb = false;
12769        }
12770
12771        app.nonStoppingAdj = adj;
12772
12773        if (hasStoppingActivities) {
12774            // Only upgrade adjustment.
12775            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12776                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12777                app.adjType = "stopping";
12778            }
12779        }
12780
12781        app.curRawAdj = adj;
12782
12783        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12784        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12785        if (adj > app.maxAdj) {
12786            adj = app.maxAdj;
12787            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12788                schedGroup = Process.THREAD_GROUP_DEFAULT;
12789            }
12790        }
12791        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12792            app.keeping = true;
12793        }
12794
12795        if (app.hasAboveClient) {
12796            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12797            // then we need to drop its adjustment to be lower than the service's
12798            // in order to honor the request.  We want to drop it by one adjustment
12799            // level...  but there is special meaning applied to various levels so
12800            // we will skip some of them.
12801            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12802                // System process will not get dropped, ever
12803            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12804                adj = ProcessList.VISIBLE_APP_ADJ;
12805            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12806                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12807            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12808                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12809            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12810                adj++;
12811            }
12812        }
12813
12814        int importance = app.memImportance;
12815        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12816            app.curAdj = adj;
12817            app.curSchedGroup = schedGroup;
12818            if (!interesting) {
12819                // For this reporting, if there is not something explicitly
12820                // interesting in this process then we will push it to the
12821                // background importance.
12822                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12823            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12824                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12825            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12826                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12827            } else if (adj >= ProcessList.HOME_APP_ADJ) {
12828                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12829            } else if (adj >= ProcessList.SERVICE_ADJ) {
12830                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12831            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12832                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12833            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12834                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12835            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12836                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12837            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12838                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12839            } else {
12840                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12841            }
12842        }
12843
12844        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12845        if (foregroundActivities != app.foregroundActivities) {
12846            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12847        }
12848        if (changes != 0) {
12849            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12850            app.memImportance = importance;
12851            app.foregroundActivities = foregroundActivities;
12852            int i = mPendingProcessChanges.size()-1;
12853            ProcessChangeItem item = null;
12854            while (i >= 0) {
12855                item = mPendingProcessChanges.get(i);
12856                if (item.pid == app.pid) {
12857                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12858                    break;
12859                }
12860                i--;
12861            }
12862            if (i < 0) {
12863                // No existing item in pending changes; need a new one.
12864                final int NA = mAvailProcessChanges.size();
12865                if (NA > 0) {
12866                    item = mAvailProcessChanges.remove(NA-1);
12867                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12868                } else {
12869                    item = new ProcessChangeItem();
12870                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
12871                }
12872                item.changes = 0;
12873                item.pid = app.pid;
12874                item.uid = app.info.uid;
12875                if (mPendingProcessChanges.size() == 0) {
12876                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
12877                            "*** Enqueueing dispatch processes changed!");
12878                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
12879                }
12880                mPendingProcessChanges.add(item);
12881            }
12882            item.changes |= changes;
12883            item.importance = importance;
12884            item.foregroundActivities = foregroundActivities;
12885            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
12886                    + Integer.toHexString(System.identityHashCode(item))
12887                    + " " + app.toShortString() + ": changes=" + item.changes
12888                    + " importance=" + item.importance
12889                    + " foreground=" + item.foregroundActivities
12890                    + " type=" + app.adjType + " source=" + app.adjSource
12891                    + " target=" + app.adjTarget);
12892        }
12893
12894        return app.curRawAdj;
12895    }
12896
12897    /**
12898     * Ask a given process to GC right now.
12899     */
12900    final void performAppGcLocked(ProcessRecord app) {
12901        try {
12902            app.lastRequestedGc = SystemClock.uptimeMillis();
12903            if (app.thread != null) {
12904                if (app.reportLowMemory) {
12905                    app.reportLowMemory = false;
12906                    app.thread.scheduleLowMemory();
12907                } else {
12908                    app.thread.processInBackground();
12909                }
12910            }
12911        } catch (Exception e) {
12912            // whatever.
12913        }
12914    }
12915
12916    /**
12917     * Returns true if things are idle enough to perform GCs.
12918     */
12919    private final boolean canGcNowLocked() {
12920        boolean processingBroadcasts = false;
12921        for (BroadcastQueue q : mBroadcastQueues) {
12922            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
12923                processingBroadcasts = true;
12924            }
12925        }
12926        return !processingBroadcasts
12927                && (mSleeping || (mMainStack.mResumedActivity != null &&
12928                        mMainStack.mResumedActivity.idle));
12929    }
12930
12931    /**
12932     * Perform GCs on all processes that are waiting for it, but only
12933     * if things are idle.
12934     */
12935    final void performAppGcsLocked() {
12936        final int N = mProcessesToGc.size();
12937        if (N <= 0) {
12938            return;
12939        }
12940        if (canGcNowLocked()) {
12941            while (mProcessesToGc.size() > 0) {
12942                ProcessRecord proc = mProcessesToGc.remove(0);
12943                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
12944                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12945                            <= SystemClock.uptimeMillis()) {
12946                        // To avoid spamming the system, we will GC processes one
12947                        // at a time, waiting a few seconds between each.
12948                        performAppGcLocked(proc);
12949                        scheduleAppGcsLocked();
12950                        return;
12951                    } else {
12952                        // It hasn't been long enough since we last GCed this
12953                        // process...  put it in the list to wait for its time.
12954                        addProcessToGcListLocked(proc);
12955                        break;
12956                    }
12957                }
12958            }
12959
12960            scheduleAppGcsLocked();
12961        }
12962    }
12963
12964    /**
12965     * If all looks good, perform GCs on all processes waiting for them.
12966     */
12967    final void performAppGcsIfAppropriateLocked() {
12968        if (canGcNowLocked()) {
12969            performAppGcsLocked();
12970            return;
12971        }
12972        // Still not idle, wait some more.
12973        scheduleAppGcsLocked();
12974    }
12975
12976    /**
12977     * Schedule the execution of all pending app GCs.
12978     */
12979    final void scheduleAppGcsLocked() {
12980        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
12981
12982        if (mProcessesToGc.size() > 0) {
12983            // Schedule a GC for the time to the next process.
12984            ProcessRecord proc = mProcessesToGc.get(0);
12985            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12986
12987            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
12988            long now = SystemClock.uptimeMillis();
12989            if (when < (now+GC_TIMEOUT)) {
12990                when = now + GC_TIMEOUT;
12991            }
12992            mHandler.sendMessageAtTime(msg, when);
12993        }
12994    }
12995
12996    /**
12997     * Add a process to the array of processes waiting to be GCed.  Keeps the
12998     * list in sorted order by the last GC time.  The process can't already be
12999     * on the list.
13000     */
13001    final void addProcessToGcListLocked(ProcessRecord proc) {
13002        boolean added = false;
13003        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13004            if (mProcessesToGc.get(i).lastRequestedGc <
13005                    proc.lastRequestedGc) {
13006                added = true;
13007                mProcessesToGc.add(i+1, proc);
13008                break;
13009            }
13010        }
13011        if (!added) {
13012            mProcessesToGc.add(0, proc);
13013        }
13014    }
13015
13016    /**
13017     * Set up to ask a process to GC itself.  This will either do it
13018     * immediately, or put it on the list of processes to gc the next
13019     * time things are idle.
13020     */
13021    final void scheduleAppGcLocked(ProcessRecord app) {
13022        long now = SystemClock.uptimeMillis();
13023        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13024            return;
13025        }
13026        if (!mProcessesToGc.contains(app)) {
13027            addProcessToGcListLocked(app);
13028            scheduleAppGcsLocked();
13029        }
13030    }
13031
13032    final void checkExcessivePowerUsageLocked(boolean doKills) {
13033        updateCpuStatsNow();
13034
13035        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13036        boolean doWakeKills = doKills;
13037        boolean doCpuKills = doKills;
13038        if (mLastPowerCheckRealtime == 0) {
13039            doWakeKills = false;
13040        }
13041        if (mLastPowerCheckUptime == 0) {
13042            doCpuKills = false;
13043        }
13044        if (stats.isScreenOn()) {
13045            doWakeKills = false;
13046        }
13047        final long curRealtime = SystemClock.elapsedRealtime();
13048        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13049        final long curUptime = SystemClock.uptimeMillis();
13050        final long uptimeSince = curUptime - mLastPowerCheckUptime;
13051        mLastPowerCheckRealtime = curRealtime;
13052        mLastPowerCheckUptime = curUptime;
13053        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13054            doWakeKills = false;
13055        }
13056        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13057            doCpuKills = false;
13058        }
13059        int i = mLruProcesses.size();
13060        while (i > 0) {
13061            i--;
13062            ProcessRecord app = mLruProcesses.get(i);
13063            if (!app.keeping) {
13064                long wtime;
13065                synchronized (stats) {
13066                    wtime = stats.getProcessWakeTime(app.info.uid,
13067                            app.pid, curRealtime);
13068                }
13069                long wtimeUsed = wtime - app.lastWakeTime;
13070                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13071                if (DEBUG_POWER) {
13072                    StringBuilder sb = new StringBuilder(128);
13073                    sb.append("Wake for ");
13074                    app.toShortString(sb);
13075                    sb.append(": over ");
13076                    TimeUtils.formatDuration(realtimeSince, sb);
13077                    sb.append(" used ");
13078                    TimeUtils.formatDuration(wtimeUsed, sb);
13079                    sb.append(" (");
13080                    sb.append((wtimeUsed*100)/realtimeSince);
13081                    sb.append("%)");
13082                    Slog.i(TAG, sb.toString());
13083                    sb.setLength(0);
13084                    sb.append("CPU for ");
13085                    app.toShortString(sb);
13086                    sb.append(": over ");
13087                    TimeUtils.formatDuration(uptimeSince, sb);
13088                    sb.append(" used ");
13089                    TimeUtils.formatDuration(cputimeUsed, sb);
13090                    sb.append(" (");
13091                    sb.append((cputimeUsed*100)/uptimeSince);
13092                    sb.append("%)");
13093                    Slog.i(TAG, sb.toString());
13094                }
13095                // If a process has held a wake lock for more
13096                // than 50% of the time during this period,
13097                // that sounds bad.  Kill!
13098                if (doWakeKills && realtimeSince > 0
13099                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13100                    synchronized (stats) {
13101                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13102                                realtimeSince, wtimeUsed);
13103                    }
13104                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13105                            + " (pid " + app.pid + "): held " + wtimeUsed
13106                            + " during " + realtimeSince);
13107                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13108                            app.processName, app.setAdj, "excessive wake lock");
13109                    Process.killProcessQuiet(app.pid);
13110                } else if (doCpuKills && uptimeSince > 0
13111                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13112                    synchronized (stats) {
13113                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13114                                uptimeSince, cputimeUsed);
13115                    }
13116                    Slog.w(TAG, "Excessive CPU in " + app.processName
13117                            + " (pid " + app.pid + "): used " + cputimeUsed
13118                            + " during " + uptimeSince);
13119                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13120                            app.processName, app.setAdj, "excessive cpu");
13121                    Process.killProcessQuiet(app.pid);
13122                } else {
13123                    app.lastWakeTime = wtime;
13124                    app.lastCpuTime = app.curCpuTime;
13125                }
13126            }
13127        }
13128    }
13129
13130    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13131            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13132        app.hiddenAdj = hiddenAdj;
13133        app.emptyAdj = emptyAdj;
13134
13135        if (app.thread == null) {
13136            return false;
13137        }
13138
13139        final boolean wasKeeping = app.keeping;
13140
13141        boolean success = true;
13142
13143        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13144
13145        if (app.curRawAdj != app.setRawAdj) {
13146            if (wasKeeping && !app.keeping) {
13147                // This app is no longer something we want to keep.  Note
13148                // its current wake lock time to later know to kill it if
13149                // it is not behaving well.
13150                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13151                synchronized (stats) {
13152                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13153                            app.pid, SystemClock.elapsedRealtime());
13154                }
13155                app.lastCpuTime = app.curCpuTime;
13156            }
13157
13158            app.setRawAdj = app.curRawAdj;
13159        }
13160
13161        if (app.curAdj != app.setAdj) {
13162            if (Process.setOomAdj(app.pid, app.curAdj)) {
13163                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13164                    TAG, "Set " + app.pid + " " + app.processName +
13165                    " adj " + app.curAdj + ": " + app.adjType);
13166                app.setAdj = app.curAdj;
13167            } else {
13168                success = false;
13169                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13170            }
13171        }
13172        if (app.setSchedGroup != app.curSchedGroup) {
13173            app.setSchedGroup = app.curSchedGroup;
13174            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13175                    "Setting process group of " + app.processName
13176                    + " to " + app.curSchedGroup);
13177            if (app.waitingToKill != null &&
13178                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13179                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13180                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13181                        app.processName, app.setAdj, app.waitingToKill);
13182                app.killedBackground = true;
13183                Process.killProcessQuiet(app.pid);
13184                success = false;
13185            } else {
13186                if (true) {
13187                    long oldId = Binder.clearCallingIdentity();
13188                    try {
13189                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13190                    } catch (Exception e) {
13191                        Slog.w(TAG, "Failed setting process group of " + app.pid
13192                                + " to " + app.curSchedGroup);
13193                        e.printStackTrace();
13194                    } finally {
13195                        Binder.restoreCallingIdentity(oldId);
13196                    }
13197                } else {
13198                    if (app.thread != null) {
13199                        try {
13200                            app.thread.setSchedulingGroup(app.curSchedGroup);
13201                        } catch (RemoteException e) {
13202                        }
13203                    }
13204                }
13205            }
13206        }
13207        return success;
13208    }
13209
13210    private final ActivityRecord resumedAppLocked() {
13211        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13212        if (resumedActivity == null || resumedActivity.app == null) {
13213            resumedActivity = mMainStack.mPausingActivity;
13214            if (resumedActivity == null || resumedActivity.app == null) {
13215                resumedActivity = mMainStack.topRunningActivityLocked(null);
13216            }
13217        }
13218        return resumedActivity;
13219    }
13220
13221    final boolean updateOomAdjLocked(ProcessRecord app) {
13222        final ActivityRecord TOP_ACT = resumedAppLocked();
13223        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13224        int curAdj = app.curAdj;
13225        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13226            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13227
13228        mAdjSeq++;
13229
13230        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
13231                TOP_APP, false);
13232        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13233            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13234        if (nowHidden != wasHidden) {
13235            // Changed to/from hidden state, so apps after it in the LRU
13236            // list may also be changed.
13237            updateOomAdjLocked();
13238        }
13239        return success;
13240    }
13241
13242    final void updateOomAdjLocked() {
13243        final ActivityRecord TOP_ACT = resumedAppLocked();
13244        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13245
13246        if (false) {
13247            RuntimeException e = new RuntimeException();
13248            e.fillInStackTrace();
13249            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13250        }
13251
13252        mAdjSeq++;
13253        mNewNumServiceProcs = 0;
13254
13255        // Let's determine how many processes we have running vs.
13256        // how many slots we have for background processes; we may want
13257        // to put multiple processes in a slot of there are enough of
13258        // them.
13259        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13260                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13261        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
13262        if (emptyFactor < 1) emptyFactor = 1;
13263        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13264        if (hiddenFactor < 1) hiddenFactor = 1;
13265        int stepHidden = 0;
13266        int stepEmpty = 0;
13267        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13268        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13269        int numHidden = 0;
13270        int numEmpty = 0;
13271        int numTrimming = 0;
13272
13273        mNumNonHiddenProcs = 0;
13274        mNumHiddenProcs = 0;
13275
13276        // First update the OOM adjustment for each of the
13277        // application processes based on their current state.
13278        int i = mLruProcesses.size();
13279        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13280        int nextHiddenAdj = curHiddenAdj+1;
13281        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13282        int nextEmptyAdj = curEmptyAdj+2;
13283        while (i > 0) {
13284            i--;
13285            ProcessRecord app = mLruProcesses.get(i);
13286            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13287            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
13288            if (!app.killedBackground) {
13289                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13290                    // This process was assigned as a hidden process...  step the
13291                    // hidden level.
13292                    mNumHiddenProcs++;
13293                    if (curHiddenAdj != nextHiddenAdj) {
13294                        stepHidden++;
13295                        if (stepHidden >= hiddenFactor) {
13296                            stepHidden = 0;
13297                            curHiddenAdj = nextHiddenAdj;
13298                            nextHiddenAdj += 2;
13299                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13300                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13301                            }
13302                        }
13303                    }
13304                    numHidden++;
13305                    if (numHidden > hiddenProcessLimit) {
13306                        Slog.i(TAG, "No longer want " + app.processName
13307                                + " (pid " + app.pid + "): hidden #" + numHidden);
13308                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13309                                app.processName, app.setAdj, "too many background");
13310                        app.killedBackground = true;
13311                        Process.killProcessQuiet(app.pid);
13312                    }
13313                } else {
13314                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13315                        // This process was assigned as an empty process...  step the
13316                        // empty level.
13317                        if (curEmptyAdj != nextEmptyAdj) {
13318                            stepEmpty++;
13319                            if (stepEmpty >= emptyFactor) {
13320                                stepEmpty = 0;
13321                                curEmptyAdj = nextEmptyAdj;
13322                                nextEmptyAdj += 2;
13323                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13324                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13325                                }
13326                            }
13327                        }
13328                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13329                        mNumNonHiddenProcs++;
13330                    }
13331                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13332                        numEmpty++;
13333                        if (numEmpty > emptyProcessLimit) {
13334                            Slog.i(TAG, "No longer want " + app.processName
13335                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13336                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13337                                    app.processName, app.setAdj, "too many background");
13338                            app.killedBackground = true;
13339                            Process.killProcessQuiet(app.pid);
13340                        }
13341                    }
13342                }
13343                if (app.isolated && app.services.size() <= 0) {
13344                    // If this is an isolated process, and there are no
13345                    // services running in it, then the process is no longer
13346                    // needed.  We agressively kill these because we can by
13347                    // definition not re-use the same process again, and it is
13348                    // good to avoid having whatever code was running in them
13349                    // left sitting around after no longer needed.
13350                    Slog.i(TAG, "Isolated process " + app.processName
13351                            + " (pid " + app.pid + ") no longer needed");
13352                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13353                            app.processName, app.setAdj, "isolated not needed");
13354                    app.killedBackground = true;
13355                    Process.killProcessQuiet(app.pid);
13356                }
13357                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13358                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13359                        && !app.killedBackground) {
13360                    numTrimming++;
13361                }
13362            }
13363        }
13364
13365        mNumServiceProcs = mNewNumServiceProcs;
13366
13367        // Now determine the memory trimming level of background processes.
13368        // Unfortunately we need to start at the back of the list to do this
13369        // properly.  We only do this if the number of background apps we
13370        // are managing to keep around is less than half the maximum we desire;
13371        // if we are keeping a good number around, we'll let them use whatever
13372        // memory they want.
13373        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13374                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13375            final int numHiddenAndEmpty = numHidden + numEmpty;
13376            final int N = mLruProcesses.size();
13377            int factor = numTrimming/3;
13378            int minFactor = 2;
13379            if (mHomeProcess != null) minFactor++;
13380            if (mPreviousProcess != null) minFactor++;
13381            if (factor < minFactor) factor = minFactor;
13382            int step = 0;
13383            int fgTrimLevel;
13384            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13385                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13386            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13387                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13388            } else {
13389                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13390            }
13391            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13392            for (i=0; i<N; i++) {
13393                ProcessRecord app = mLruProcesses.get(i);
13394                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13395                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13396                        && !app.killedBackground) {
13397                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13398                        try {
13399                            app.thread.scheduleTrimMemory(curLevel);
13400                        } catch (RemoteException e) {
13401                        }
13402                        if (false) {
13403                            // For now we won't do this; our memory trimming seems
13404                            // to be good enough at this point that destroying
13405                            // activities causes more harm than good.
13406                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13407                                    && app != mHomeProcess && app != mPreviousProcess) {
13408                                // Need to do this on its own message because the stack may not
13409                                // be in a consistent state at this point.
13410                                // For these apps we will also finish their activities
13411                                // to help them free memory.
13412                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13413                            }
13414                        }
13415                    }
13416                    app.trimMemoryLevel = curLevel;
13417                    step++;
13418                    if (step >= factor) {
13419                        step = 0;
13420                        switch (curLevel) {
13421                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13422                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13423                                break;
13424                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13425                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13426                                break;
13427                        }
13428                    }
13429                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13430                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13431                            && app.thread != null) {
13432                        try {
13433                            app.thread.scheduleTrimMemory(
13434                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13435                        } catch (RemoteException e) {
13436                        }
13437                    }
13438                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13439                } else {
13440                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13441                            && app.pendingUiClean) {
13442                        // If this application is now in the background and it
13443                        // had done UI, then give it the special trim level to
13444                        // have it free UI resources.
13445                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13446                        if (app.trimMemoryLevel < level && app.thread != null) {
13447                            try {
13448                                app.thread.scheduleTrimMemory(level);
13449                            } catch (RemoteException e) {
13450                            }
13451                        }
13452                        app.pendingUiClean = false;
13453                    }
13454                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13455                        try {
13456                            app.thread.scheduleTrimMemory(fgTrimLevel);
13457                        } catch (RemoteException e) {
13458                        }
13459                    }
13460                    app.trimMemoryLevel = fgTrimLevel;
13461                }
13462            }
13463        } else {
13464            final int N = mLruProcesses.size();
13465            for (i=0; i<N; i++) {
13466                ProcessRecord app = mLruProcesses.get(i);
13467                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13468                        && app.pendingUiClean) {
13469                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13470                            && app.thread != null) {
13471                        try {
13472                            app.thread.scheduleTrimMemory(
13473                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13474                        } catch (RemoteException e) {
13475                        }
13476                    }
13477                    app.pendingUiClean = false;
13478                }
13479                app.trimMemoryLevel = 0;
13480            }
13481        }
13482
13483        if (mAlwaysFinishActivities) {
13484            // Need to do this on its own message because the stack may not
13485            // be in a consistent state at this point.
13486            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13487        }
13488    }
13489
13490    final void trimApplications() {
13491        synchronized (this) {
13492            int i;
13493
13494            // First remove any unused application processes whose package
13495            // has been removed.
13496            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13497                final ProcessRecord app = mRemovedProcesses.get(i);
13498                if (app.activities.size() == 0
13499                        && app.curReceiver == null && app.services.size() == 0) {
13500                    Slog.i(
13501                        TAG, "Exiting empty application process "
13502                        + app.processName + " ("
13503                        + (app.thread != null ? app.thread.asBinder() : null)
13504                        + ")\n");
13505                    if (app.pid > 0 && app.pid != MY_PID) {
13506                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13507                                app.processName, app.setAdj, "empty");
13508                        Process.killProcessQuiet(app.pid);
13509                    } else {
13510                        try {
13511                            app.thread.scheduleExit();
13512                        } catch (Exception e) {
13513                            // Ignore exceptions.
13514                        }
13515                    }
13516                    cleanUpApplicationRecordLocked(app, false, true, -1);
13517                    mRemovedProcesses.remove(i);
13518
13519                    if (app.persistent) {
13520                        if (app.persistent) {
13521                            addAppLocked(app.info, false);
13522                        }
13523                    }
13524                }
13525            }
13526
13527            // Now update the oom adj for all processes.
13528            updateOomAdjLocked();
13529        }
13530    }
13531
13532    /** This method sends the specified signal to each of the persistent apps */
13533    public void signalPersistentProcesses(int sig) throws RemoteException {
13534        if (sig != Process.SIGNAL_USR1) {
13535            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13536        }
13537
13538        synchronized (this) {
13539            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13540                    != PackageManager.PERMISSION_GRANTED) {
13541                throw new SecurityException("Requires permission "
13542                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13543            }
13544
13545            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13546                ProcessRecord r = mLruProcesses.get(i);
13547                if (r.thread != null && r.persistent) {
13548                    Process.sendSignal(r.pid, sig);
13549                }
13550            }
13551        }
13552    }
13553
13554    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13555        if (proc == null || proc == mProfileProc) {
13556            proc = mProfileProc;
13557            path = mProfileFile;
13558            profileType = mProfileType;
13559            clearProfilerLocked();
13560        }
13561        if (proc == null) {
13562            return;
13563        }
13564        try {
13565            proc.thread.profilerControl(false, path, null, profileType);
13566        } catch (RemoteException e) {
13567            throw new IllegalStateException("Process disappeared");
13568        }
13569    }
13570
13571    private void clearProfilerLocked() {
13572        if (mProfileFd != null) {
13573            try {
13574                mProfileFd.close();
13575            } catch (IOException e) {
13576            }
13577        }
13578        mProfileApp = null;
13579        mProfileProc = null;
13580        mProfileFile = null;
13581        mProfileType = 0;
13582        mAutoStopProfiler = false;
13583    }
13584
13585    public boolean profileControl(String process, boolean start,
13586            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13587
13588        try {
13589            synchronized (this) {
13590                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13591                // its own permission.
13592                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13593                        != PackageManager.PERMISSION_GRANTED) {
13594                    throw new SecurityException("Requires permission "
13595                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13596                }
13597
13598                if (start && fd == null) {
13599                    throw new IllegalArgumentException("null fd");
13600                }
13601
13602                ProcessRecord proc = null;
13603                if (process != null) {
13604                    try {
13605                        int pid = Integer.parseInt(process);
13606                        synchronized (mPidsSelfLocked) {
13607                            proc = mPidsSelfLocked.get(pid);
13608                        }
13609                    } catch (NumberFormatException e) {
13610                    }
13611
13612                    if (proc == null) {
13613                        HashMap<String, SparseArray<ProcessRecord>> all
13614                                = mProcessNames.getMap();
13615                        SparseArray<ProcessRecord> procs = all.get(process);
13616                        if (procs != null && procs.size() > 0) {
13617                            proc = procs.valueAt(0);
13618                        }
13619                    }
13620                }
13621
13622                if (start && (proc == null || proc.thread == null)) {
13623                    throw new IllegalArgumentException("Unknown process: " + process);
13624                }
13625
13626                if (start) {
13627                    stopProfilerLocked(null, null, 0);
13628                    setProfileApp(proc.info, proc.processName, path, fd, false);
13629                    mProfileProc = proc;
13630                    mProfileType = profileType;
13631                    try {
13632                        fd = fd.dup();
13633                    } catch (IOException e) {
13634                        fd = null;
13635                    }
13636                    proc.thread.profilerControl(start, path, fd, profileType);
13637                    fd = null;
13638                    mProfileFd = null;
13639                } else {
13640                    stopProfilerLocked(proc, path, profileType);
13641                    if (fd != null) {
13642                        try {
13643                            fd.close();
13644                        } catch (IOException e) {
13645                        }
13646                    }
13647                }
13648
13649                return true;
13650            }
13651        } catch (RemoteException e) {
13652            throw new IllegalStateException("Process disappeared");
13653        } finally {
13654            if (fd != null) {
13655                try {
13656                    fd.close();
13657                } catch (IOException e) {
13658                }
13659            }
13660        }
13661    }
13662
13663    public boolean dumpHeap(String process, boolean managed,
13664            String path, ParcelFileDescriptor fd) throws RemoteException {
13665
13666        try {
13667            synchronized (this) {
13668                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13669                // its own permission (same as profileControl).
13670                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13671                        != PackageManager.PERMISSION_GRANTED) {
13672                    throw new SecurityException("Requires permission "
13673                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13674                }
13675
13676                if (fd == null) {
13677                    throw new IllegalArgumentException("null fd");
13678                }
13679
13680                ProcessRecord proc = null;
13681                try {
13682                    int pid = Integer.parseInt(process);
13683                    synchronized (mPidsSelfLocked) {
13684                        proc = mPidsSelfLocked.get(pid);
13685                    }
13686                } catch (NumberFormatException e) {
13687                }
13688
13689                if (proc == null) {
13690                    HashMap<String, SparseArray<ProcessRecord>> all
13691                            = mProcessNames.getMap();
13692                    SparseArray<ProcessRecord> procs = all.get(process);
13693                    if (procs != null && procs.size() > 0) {
13694                        proc = procs.valueAt(0);
13695                    }
13696                }
13697
13698                if (proc == null || proc.thread == null) {
13699                    throw new IllegalArgumentException("Unknown process: " + process);
13700                }
13701
13702                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13703                if (!isDebuggable) {
13704                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13705                        throw new SecurityException("Process not debuggable: " + proc);
13706                    }
13707                }
13708
13709                proc.thread.dumpHeap(managed, path, fd);
13710                fd = null;
13711                return true;
13712            }
13713        } catch (RemoteException e) {
13714            throw new IllegalStateException("Process disappeared");
13715        } finally {
13716            if (fd != null) {
13717                try {
13718                    fd.close();
13719                } catch (IOException e) {
13720                }
13721            }
13722        }
13723    }
13724
13725    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13726    public void monitor() {
13727        synchronized (this) { }
13728    }
13729
13730    void onCoreSettingsChange(Bundle settings) {
13731        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13732            ProcessRecord processRecord = mLruProcesses.get(i);
13733            try {
13734                if (processRecord.thread != null) {
13735                    processRecord.thread.setCoreSettings(settings);
13736                }
13737            } catch (RemoteException re) {
13738                /* ignore */
13739            }
13740        }
13741    }
13742
13743    // Multi-user methods
13744
13745    @Override
13746    public boolean switchUser(int userId) {
13747        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13748                != PackageManager.PERMISSION_GRANTED) {
13749            String msg = "Permission Denial: switchUser() from pid="
13750                    + Binder.getCallingPid()
13751                    + ", uid=" + Binder.getCallingUid()
13752                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13753            Slog.w(TAG, msg);
13754            throw new SecurityException(msg);
13755        }
13756        synchronized (this) {
13757            if (mCurrentUserId == userId) {
13758                return true;
13759            }
13760
13761            // If the user we are switching to is not currently started, then
13762            // we need to start it now.
13763            if (mStartedUsers.get(userId) == null) {
13764                mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
13765            }
13766
13767            mCurrentUserId = userId;
13768            boolean haveActivities = mMainStack.switchUser(userId);
13769            if (!haveActivities) {
13770                startHomeActivityLocked(userId, mStartedUsers.get(userId));
13771            }
13772        }
13773
13774        long ident = Binder.clearCallingIdentity();
13775        try {
13776            // Inform of user switch
13777            Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13778            addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13779            mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,
13780                    android.Manifest.permission.MANAGE_USERS);
13781        } finally {
13782            Binder.restoreCallingIdentity(ident);
13783        }
13784
13785        return true;
13786    }
13787
13788    void finishUserSwitch(UserStartedState uss) {
13789        synchronized (this) {
13790            if (uss.mState == UserStartedState.STATE_BOOTING
13791                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
13792                uss.mState = UserStartedState.STATE_RUNNING;
13793                final int userId = uss.mHandle.getIdentifier();
13794                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
13795                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13796                broadcastIntentLocked(null, null, intent,
13797                        null, null, 0, null, null,
13798                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
13799                        false, false, MY_PID, Process.SYSTEM_UID, userId);
13800            }
13801        }
13802    }
13803
13804    @Override
13805    public int stopUser(final int userId, final IStopUserCallback callback) {
13806        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13807                != PackageManager.PERMISSION_GRANTED) {
13808            String msg = "Permission Denial: switchUser() from pid="
13809                    + Binder.getCallingPid()
13810                    + ", uid=" + Binder.getCallingUid()
13811                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13812            Slog.w(TAG, msg);
13813            throw new SecurityException(msg);
13814        }
13815        if (userId <= 0) {
13816            throw new IllegalArgumentException("Can't stop primary user " + userId);
13817        }
13818        synchronized (this) {
13819            if (mCurrentUserId == userId) {
13820                return ActivityManager.USER_OP_IS_CURRENT;
13821            }
13822
13823            final UserStartedState uss = mStartedUsers.get(userId);
13824            if (uss == null) {
13825                // User is not started, nothing to do...  but we do need to
13826                // callback if requested.
13827                if (callback != null) {
13828                    mHandler.post(new Runnable() {
13829                        @Override
13830                        public void run() {
13831                            try {
13832                                callback.userStopped(userId);
13833                            } catch (RemoteException e) {
13834                            }
13835                        }
13836                    });
13837                }
13838                return ActivityManager.USER_OP_SUCCESS;
13839            }
13840
13841            if (callback != null) {
13842                uss.mStopCallbacks.add(callback);
13843            }
13844
13845            if (uss.mState != UserStartedState.STATE_STOPPING) {
13846                uss.mState = UserStartedState.STATE_STOPPING;
13847
13848                long ident = Binder.clearCallingIdentity();
13849                try {
13850                    // Inform of user switch
13851                    Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13852                    final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() {
13853                        @Override
13854                        public void performReceive(Intent intent, int resultCode, String data,
13855                                Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
13856                            finishUserStop(uss);
13857                        }
13858                    };
13859                    broadcastIntentLocked(null, null, intent,
13860                            null, resultReceiver, 0, null, null, null,
13861                            true, false, MY_PID, Process.SYSTEM_UID, userId);
13862                } finally {
13863                    Binder.restoreCallingIdentity(ident);
13864                }
13865            }
13866        }
13867
13868        return ActivityManager.USER_OP_SUCCESS;
13869    }
13870
13871    void finishUserStop(UserStartedState uss) {
13872        final int userId = uss.mHandle.getIdentifier();
13873        boolean stopped;
13874        ArrayList<IStopUserCallback> callbacks;
13875        synchronized (this) {
13876            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
13877            if (uss.mState != UserStartedState.STATE_STOPPING
13878                    || mStartedUsers.get(userId) != uss) {
13879                stopped = false;
13880            } else {
13881                stopped = true;
13882                // User can no longer run.
13883                mStartedUsers.remove(userId);
13884
13885                // Clean up all state and processes associated with the user.
13886                // Kill all the processes for the user.
13887                forceStopUserLocked(userId);
13888            }
13889        }
13890
13891        for (int i=0; i<callbacks.size(); i++) {
13892            try {
13893                if (stopped) callbacks.get(i).userStopped(userId);
13894                else callbacks.get(i).userStopAborted(userId);
13895            } catch (RemoteException e) {
13896            }
13897        }
13898    }
13899
13900    @Override
13901    public UserInfo getCurrentUser() {
13902        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13903                != PackageManager.PERMISSION_GRANTED) {
13904            String msg = "Permission Denial: getCurrentUser() from pid="
13905                    + Binder.getCallingPid()
13906                    + ", uid=" + Binder.getCallingUid()
13907                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13908            Slog.w(TAG, msg);
13909            throw new SecurityException(msg);
13910        }
13911        synchronized (this) {
13912            return getUserManager().getUserInfo(mCurrentUserId);
13913        }
13914    }
13915
13916    private boolean userExists(int userId) {
13917        UserInfo user = getUserManager().getUserInfo(userId);
13918        return user != null;
13919    }
13920
13921    UserManager getUserManager() {
13922        if (mUserManager == null) {
13923            mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
13924        }
13925        return mUserManager;
13926    }
13927
13928    private void checkValidCaller(int uid, int userId) {
13929        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
13930
13931        throw new SecurityException("Caller uid=" + uid
13932                + " is not privileged to communicate with user=" + userId);
13933    }
13934
13935    private int applyUserId(int uid, int userId) {
13936        return UserHandle.getUid(userId, uid);
13937    }
13938
13939    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
13940        if (info == null) return null;
13941        ApplicationInfo newInfo = new ApplicationInfo(info);
13942        newInfo.uid = applyUserId(info.uid, userId);
13943        newInfo.dataDir = USER_DATA_DIR + userId + "/"
13944                + info.packageName;
13945        return newInfo;
13946    }
13947
13948    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
13949        if (aInfo == null
13950                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
13951            return aInfo;
13952        }
13953
13954        ActivityInfo info = new ActivityInfo(aInfo);
13955        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
13956        return info;
13957    }
13958}
13959