ActivityManagerService.java revision 8264408f5995534f8e3147b001664ea0df52aaa5
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.IThumbnailReceiver;
50import android.app.Instrumentation;
51import android.app.Notification;
52import android.app.NotificationManager;
53import android.app.PendingIntent;
54import android.app.Service;
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.PackageManager.NameNotFoundException;
80import android.content.pm.PathPermission;
81import android.content.pm.ProviderInfo;
82import android.content.pm.ResolveInfo;
83import android.content.pm.ServiceInfo;
84import android.content.pm.UserInfo;
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.ServiceManager;
110import android.os.StrictMode;
111import android.os.SystemClock;
112import android.os.SystemProperties;
113import android.os.UserId;
114import android.provider.Settings;
115import android.text.format.Time;
116import android.util.EventLog;
117import android.util.Log;
118import android.util.Pair;
119import android.util.PrintWriterPrinter;
120import android.util.Slog;
121import android.util.SparseArray;
122import android.util.SparseIntArray;
123import android.util.TimeUtils;
124import android.view.Gravity;
125import android.view.LayoutInflater;
126import android.view.View;
127import android.view.WindowManager;
128import android.view.WindowManagerPolicy;
129
130import java.io.BufferedInputStream;
131import java.io.BufferedOutputStream;
132import java.io.BufferedReader;
133import java.io.DataInputStream;
134import java.io.DataOutputStream;
135import java.io.File;
136import java.io.FileDescriptor;
137import java.io.FileInputStream;
138import java.io.FileNotFoundException;
139import java.io.FileOutputStream;
140import java.io.IOException;
141import java.io.InputStreamReader;
142import java.io.PrintWriter;
143import java.io.StringWriter;
144import java.lang.ref.WeakReference;
145import java.util.ArrayList;
146import java.util.Collection;
147import java.util.Collections;
148import java.util.Comparator;
149import java.util.HashMap;
150import java.util.HashSet;
151import java.util.Iterator;
152import java.util.List;
153import java.util.Locale;
154import java.util.Map;
155import java.util.Map.Entry;
156import java.util.Set;
157import java.util.concurrent.atomic.AtomicBoolean;
158import java.util.concurrent.atomic.AtomicLong;
159
160public final class ActivityManagerService extends ActivityManagerNative
161        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
162    private static final String USER_DATA_DIR = "/data/user/";
163    static final String TAG = "ActivityManager";
164    static final String TAG_MU = "ActivityManagerServiceMU";
165    static final boolean DEBUG = false;
166    static final boolean localLOGV = DEBUG;
167    static final boolean DEBUG_SWITCH = localLOGV || false;
168    static final boolean DEBUG_TASKS = localLOGV || false;
169    static final boolean DEBUG_PAUSE = localLOGV || false;
170    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
171    static final boolean DEBUG_TRANSITION = localLOGV || false;
172    static final boolean DEBUG_BROADCAST = localLOGV || false;
173    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
174    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
175    static final boolean DEBUG_SERVICE = localLOGV || false;
176    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
177    static final boolean DEBUG_VISBILITY = localLOGV || false;
178    static final boolean DEBUG_PROCESSES = localLOGV || false;
179    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
180    static final boolean DEBUG_PROVIDER = localLOGV || false;
181    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
182    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
183    static final boolean DEBUG_RESULTS = localLOGV || false;
184    static final boolean DEBUG_BACKUP = localLOGV || false;
185    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
186    static final boolean DEBUG_POWER = localLOGV || false;
187    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
188    static final boolean DEBUG_MU = localLOGV || false;
189    static final boolean VALIDATE_TOKENS = false;
190    static final boolean SHOW_ACTIVITY_START_TIME = true;
191
192    // Control over CPU and battery monitoring.
193    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
194    static final boolean MONITOR_CPU_USAGE = true;
195    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
196    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
197    static final boolean MONITOR_THREAD_CPU_USAGE = false;
198
199    // The flags that are set for all calls we make to the package manager.
200    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
201
202    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
203
204    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
205
206    // Maximum number of recent tasks that we can remember.
207    static final int MAX_RECENT_TASKS = 20;
208
209    // Amount of time after a call to stopAppSwitches() during which we will
210    // prevent further untrusted switches from happening.
211    static final long APP_SWITCH_DELAY_TIME = 5*1000;
212
213    // How long we wait for a launched process to attach to the activity manager
214    // before we decide it's never going to come up for real.
215    static final int PROC_START_TIMEOUT = 10*1000;
216
217    // How long we wait for a launched process to attach to the activity manager
218    // before we decide it's never going to come up for real, when the process was
219    // started with a wrapper for instrumentation (such as Valgrind) because it
220    // could take much longer than usual.
221    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
222
223    // How long to wait after going idle before forcing apps to GC.
224    static final int GC_TIMEOUT = 5*1000;
225
226    // The minimum amount of time between successive GC requests for a process.
227    static final int GC_MIN_INTERVAL = 60*1000;
228
229    // The rate at which we check for apps using excessive power -- 15 mins.
230    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
231
232    // The minimum sample duration we will allow before deciding we have
233    // enough data on wake locks to start killing things.
234    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
235
236    // The minimum sample duration we will allow before deciding we have
237    // enough data on CPU usage to start killing things.
238    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
239
240    // How long we allow a receiver to run before giving up on it.
241    static final int BROADCAST_FG_TIMEOUT = 10*1000;
242    static final int BROADCAST_BG_TIMEOUT = 60*1000;
243
244    // How long we wait until we timeout on key dispatching.
245    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
246
247    // How long we wait until we timeout on key dispatching during instrumentation.
248    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
249
250    static final int MY_PID = Process.myPid();
251
252    static final String[] EMPTY_STRING_ARRAY = new String[0];
253
254    public ActivityStack mMainStack;
255
256    private final boolean mHeadless;
257
258    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
259    // default actuion automatically.  Important for devices without direct input
260    // devices.
261    private boolean mShowDialogs = true;
262
263    /**
264     * Description of a request to start a new activity, which has been held
265     * due to app switches being disabled.
266     */
267    static class PendingActivityLaunch {
268        ActivityRecord r;
269        ActivityRecord sourceRecord;
270        int startFlags;
271    }
272
273    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
274            = new ArrayList<PendingActivityLaunch>();
275
276
277    BroadcastQueue mFgBroadcastQueue;
278    BroadcastQueue mBgBroadcastQueue;
279    // Convenient for easy iteration over the queues. Foreground is first
280    // so that dispatch of foreground broadcasts gets precedence.
281    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
282
283    BroadcastQueue broadcastQueueForIntent(Intent intent) {
284        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
285        if (DEBUG_BACKGROUND_BROADCAST) {
286            Slog.i(TAG, "Broadcast intent " + intent + " on "
287                    + (isFg ? "foreground" : "background")
288                    + " queue");
289        }
290        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
291    }
292
293    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
294        for (BroadcastQueue queue : mBroadcastQueues) {
295            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
296            if (r != null) {
297                return r;
298            }
299        }
300        return null;
301    }
302
303    /**
304     * Activity we have told the window manager to have key focus.
305     */
306    ActivityRecord mFocusedActivity = null;
307    /**
308     * List of intents that were used to start the most recent tasks.
309     */
310    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
311
312    /**
313     * Process management.
314     */
315    final ProcessList mProcessList = new ProcessList();
316
317    /**
318     * All of the applications we currently have running organized by name.
319     * The keys are strings of the application package name (as
320     * returned by the package manager), and the keys are ApplicationRecord
321     * objects.
322     */
323    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
324
325    /**
326     * The currently running isolated processes.
327     */
328    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
329
330    /**
331     * Counter for assigning isolated process uids, to avoid frequently reusing the
332     * same ones.
333     */
334    int mNextIsolatedProcessUid = 0;
335
336    /**
337     * The currently running heavy-weight process, if any.
338     */
339    ProcessRecord mHeavyWeightProcess = null;
340
341    /**
342     * The last time that various processes have crashed.
343     */
344    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
345
346    /**
347     * Set of applications that we consider to be bad, and will reject
348     * incoming broadcasts from (which the user has no control over).
349     * Processes are added to this set when they have crashed twice within
350     * a minimum amount of time; they are removed from it when they are
351     * later restarted (hopefully due to some user action).  The value is the
352     * time it was added to the list.
353     */
354    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
355
356    /**
357     * All of the processes we currently have running organized by pid.
358     * The keys are the pid running the application.
359     *
360     * <p>NOTE: This object is protected by its own lock, NOT the global
361     * activity manager lock!
362     */
363    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
364
365    /**
366     * All of the processes that have been forced to be foreground.  The key
367     * is the pid of the caller who requested it (we hold a death
368     * link on it).
369     */
370    abstract class ForegroundToken implements IBinder.DeathRecipient {
371        int pid;
372        IBinder token;
373    }
374    final SparseArray<ForegroundToken> mForegroundProcesses
375            = new SparseArray<ForegroundToken>();
376
377    /**
378     * List of records for processes that someone had tried to start before the
379     * system was ready.  We don't start them at that point, but ensure they
380     * are started by the time booting is complete.
381     */
382    final ArrayList<ProcessRecord> mProcessesOnHold
383            = new ArrayList<ProcessRecord>();
384
385    /**
386     * List of persistent applications that are in the process
387     * of being started.
388     */
389    final ArrayList<ProcessRecord> mPersistentStartingProcesses
390            = new ArrayList<ProcessRecord>();
391
392    /**
393     * Processes that are being forcibly torn down.
394     */
395    final ArrayList<ProcessRecord> mRemovedProcesses
396            = new ArrayList<ProcessRecord>();
397
398    /**
399     * List of running applications, sorted by recent usage.
400     * The first entry in the list is the least recently used.
401     * It contains ApplicationRecord objects.  This list does NOT include
402     * any persistent application records (since we never want to exit them).
403     */
404    final ArrayList<ProcessRecord> mLruProcesses
405            = new ArrayList<ProcessRecord>();
406
407    /**
408     * List of processes that should gc as soon as things are idle.
409     */
410    final ArrayList<ProcessRecord> mProcessesToGc
411            = new ArrayList<ProcessRecord>();
412
413    /**
414     * This is the process holding what we currently consider to be
415     * the "home" activity.
416     */
417    ProcessRecord mHomeProcess;
418
419    /**
420     * This is the process holding the activity the user last visited that
421     * is in a different process from the one they are currently in.
422     */
423    ProcessRecord mPreviousProcess;
424
425    /**
426     * The time at which the previous process was last visible.
427     */
428    long mPreviousProcessVisibleTime;
429
430    /**
431     * Packages that the user has asked to have run in screen size
432     * compatibility mode instead of filling the screen.
433     */
434    final CompatModePackages mCompatModePackages;
435
436    /**
437     * Set of PendingResultRecord objects that are currently active.
438     */
439    final HashSet mPendingResultRecords = new HashSet();
440
441    /**
442     * Set of IntentSenderRecord objects that are currently active.
443     */
444    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
445            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
446
447    /**
448     * Fingerprints (hashCode()) of stack traces that we've
449     * already logged DropBox entries for.  Guarded by itself.  If
450     * something (rogue user app) forces this over
451     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
452     */
453    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
454    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
455
456    /**
457     * Strict Mode background batched logging state.
458     *
459     * The string buffer is guarded by itself, and its lock is also
460     * used to determine if another batched write is already
461     * in-flight.
462     */
463    private final StringBuilder mStrictModeBuffer = new StringBuilder();
464
465    /**
466     * Keeps track of all IIntentReceivers that have been registered for
467     * broadcasts.  Hash keys are the receiver IBinder, hash value is
468     * a ReceiverList.
469     */
470    final HashMap mRegisteredReceivers = new HashMap();
471
472    /**
473     * Resolver for broadcast intents to registered receivers.
474     * Holds BroadcastFilter (subclass of IntentFilter).
475     */
476    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
477            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
478        @Override
479        protected boolean allowFilterResult(
480                BroadcastFilter filter, List<BroadcastFilter> dest) {
481            IBinder target = filter.receiverList.receiver.asBinder();
482            for (int i=dest.size()-1; i>=0; i--) {
483                if (dest.get(i).receiverList.receiver.asBinder() == target) {
484                    return false;
485                }
486            }
487            return true;
488        }
489
490        @Override
491        protected BroadcastFilter[] newArray(int size) {
492            return new BroadcastFilter[size];
493        }
494
495        @Override
496        protected String packageForFilter(BroadcastFilter filter) {
497            return filter.packageName;
498        }
499    };
500
501    /**
502     * State of all active sticky broadcasts.  Keys are the action of the
503     * sticky Intent, values are an ArrayList of all broadcasted intents with
504     * that action (which should usually be one).
505     */
506    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
507            new HashMap<String, ArrayList<Intent>>();
508
509    final ActiveServices mServices;
510
511    /**
512     * Backup/restore process management
513     */
514    String mBackupAppName = null;
515    BackupRecord mBackupTarget = null;
516
517    /**
518     * List of PendingThumbnailsRecord objects of clients who are still
519     * waiting to receive all of the thumbnails for a task.
520     */
521    final ArrayList mPendingThumbnails = new ArrayList();
522
523    /**
524     * List of HistoryRecord objects that have been finished and must
525     * still report back to a pending thumbnail receiver.
526     */
527    final ArrayList mCancelledThumbnails = new ArrayList();
528
529    final ProviderMap mProviderMap = new ProviderMap();
530
531    /**
532     * List of content providers who have clients waiting for them.  The
533     * application is currently being launched and the provider will be
534     * removed from this list once it is published.
535     */
536    final ArrayList<ContentProviderRecord> mLaunchingProviders
537            = new ArrayList<ContentProviderRecord>();
538
539    /**
540     * Global set of specific Uri permissions that have been granted.
541     */
542    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
543            = new SparseArray<HashMap<Uri, UriPermission>>();
544
545    CoreSettingsObserver mCoreSettingsObserver;
546
547    /**
548     * Thread-local storage used to carry caller permissions over through
549     * indirect content-provider access.
550     * @see #ActivityManagerService.openContentUri()
551     */
552    private class Identity {
553        public int pid;
554        public int uid;
555
556        Identity(int _pid, int _uid) {
557            pid = _pid;
558            uid = _uid;
559        }
560    }
561
562    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
563
564    /**
565     * All information we have collected about the runtime performance of
566     * any user id that can impact battery performance.
567     */
568    final BatteryStatsService mBatteryStatsService;
569
570    /**
571     * information about component usage
572     */
573    final UsageStatsService mUsageStatsService;
574
575    /**
576     * Current configuration information.  HistoryRecord objects are given
577     * a reference to this object to indicate which configuration they are
578     * currently running in, so this object must be kept immutable.
579     */
580    Configuration mConfiguration = new Configuration();
581
582    /**
583     * Current sequencing integer of the configuration, for skipping old
584     * configurations.
585     */
586    int mConfigurationSeq = 0;
587
588    /**
589     * Hardware-reported OpenGLES version.
590     */
591    final int GL_ES_VERSION;
592
593    /**
594     * List of initialization arguments to pass to all processes when binding applications to them.
595     * For example, references to the commonly used services.
596     */
597    HashMap<String, IBinder> mAppBindArgs;
598
599    /**
600     * Temporary to avoid allocations.  Protected by main lock.
601     */
602    final StringBuilder mStringBuilder = new StringBuilder(256);
603
604    /**
605     * Used to control how we initialize the service.
606     */
607    boolean mStartRunning = false;
608    ComponentName mTopComponent;
609    String mTopAction;
610    String mTopData;
611    boolean mProcessesReady = false;
612    boolean mSystemReady = false;
613    boolean mBooting = false;
614    boolean mWaitingUpdate = false;
615    boolean mDidUpdate = false;
616    boolean mOnBattery = false;
617    boolean mLaunchWarningShown = false;
618
619    Context mContext;
620
621    int mFactoryTest;
622
623    boolean mCheckedForSetup;
624
625    /**
626     * The time at which we will allow normal application switches again,
627     * after a call to {@link #stopAppSwitches()}.
628     */
629    long mAppSwitchesAllowedTime;
630
631    /**
632     * This is set to true after the first switch after mAppSwitchesAllowedTime
633     * is set; any switches after that will clear the time.
634     */
635    boolean mDidAppSwitch;
636
637    /**
638     * Last time (in realtime) at which we checked for power usage.
639     */
640    long mLastPowerCheckRealtime;
641
642    /**
643     * Last time (in uptime) at which we checked for power usage.
644     */
645    long mLastPowerCheckUptime;
646
647    /**
648     * Set while we are wanting to sleep, to prevent any
649     * activities from being started/resumed.
650     */
651    boolean mSleeping = false;
652
653    /**
654     * State of external calls telling us if the device is asleep.
655     */
656    boolean mWentToSleep = false;
657
658    /**
659     * State of external call telling us if the lock screen is shown.
660     */
661    boolean mLockScreenShown = false;
662
663    /**
664     * Set if we are shutting down the system, similar to sleeping.
665     */
666    boolean mShuttingDown = false;
667
668    /**
669     * Task identifier that activities are currently being started
670     * in.  Incremented each time a new task is created.
671     * todo: Replace this with a TokenSpace class that generates non-repeating
672     * integers that won't wrap.
673     */
674    int mCurTask = 1;
675
676    /**
677     * Current sequence id for oom_adj computation traversal.
678     */
679    int mAdjSeq = 0;
680
681    /**
682     * Current sequence id for process LRU updating.
683     */
684    int mLruSeq = 0;
685
686    /**
687     * Keep track of the number of service processes we last found, to
688     * determine on the next iteration which should be B services.
689     */
690    int mNumServiceProcs = 0;
691    int mNewNumServiceProcs = 0;
692
693    /**
694     * System monitoring: number of processes that died since the last
695     * N procs were started.
696     */
697    int[] mProcDeaths = new int[20];
698
699    /**
700     * This is set if we had to do a delayed dexopt of an app before launching
701     * it, to increasing the ANR timeouts in that case.
702     */
703    boolean mDidDexOpt;
704
705    String mDebugApp = null;
706    boolean mWaitForDebugger = false;
707    boolean mDebugTransient = false;
708    String mOrigDebugApp = null;
709    boolean mOrigWaitForDebugger = false;
710    boolean mAlwaysFinishActivities = false;
711    IActivityController mController = null;
712    String mProfileApp = null;
713    ProcessRecord mProfileProc = null;
714    String mProfileFile;
715    ParcelFileDescriptor mProfileFd;
716    int mProfileType = 0;
717    boolean mAutoStopProfiler = false;
718    String mOpenGlTraceApp = null;
719
720    static class ProcessChangeItem {
721        static final int CHANGE_ACTIVITIES = 1<<0;
722        static final int CHANGE_IMPORTANCE= 1<<1;
723        int changes;
724        int uid;
725        int pid;
726        int importance;
727        boolean foregroundActivities;
728    }
729
730    final RemoteCallbackList<IProcessObserver> mProcessObservers
731            = new RemoteCallbackList<IProcessObserver>();
732    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
733
734    final ArrayList<ProcessChangeItem> mPendingProcessChanges
735            = new ArrayList<ProcessChangeItem>();
736    final ArrayList<ProcessChangeItem> mAvailProcessChanges
737            = new ArrayList<ProcessChangeItem>();
738
739    /**
740     * Callback of last caller to {@link #requestPss}.
741     */
742    Runnable mRequestPssCallback;
743
744    /**
745     * Remaining processes for which we are waiting results from the last
746     * call to {@link #requestPss}.
747     */
748    final ArrayList<ProcessRecord> mRequestPssList
749            = new ArrayList<ProcessRecord>();
750
751    /**
752     * Runtime statistics collection thread.  This object's lock is used to
753     * protect all related state.
754     */
755    final Thread mProcessStatsThread;
756
757    /**
758     * Used to collect process stats when showing not responding dialog.
759     * Protected by mProcessStatsThread.
760     */
761    final ProcessStats mProcessStats = new ProcessStats(
762            MONITOR_THREAD_CPU_USAGE);
763    final AtomicLong mLastCpuTime = new AtomicLong(0);
764    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
765
766    long mLastWriteTime = 0;
767
768    /**
769     * Set to true after the system has finished booting.
770     */
771    boolean mBooted = false;
772
773    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
774    int mProcessLimitOverride = -1;
775
776    WindowManagerService mWindowManager;
777
778    static ActivityManagerService mSelf;
779    static ActivityThread mSystemThread;
780
781    private final class AppDeathRecipient implements IBinder.DeathRecipient {
782        final ProcessRecord mApp;
783        final int mPid;
784        final IApplicationThread mAppThread;
785
786        AppDeathRecipient(ProcessRecord app, int pid,
787                IApplicationThread thread) {
788            if (localLOGV) Slog.v(
789                TAG, "New death recipient " + this
790                + " for thread " + thread.asBinder());
791            mApp = app;
792            mPid = pid;
793            mAppThread = thread;
794        }
795
796        public void binderDied() {
797            if (localLOGV) Slog.v(
798                TAG, "Death received in " + this
799                + " for thread " + mAppThread.asBinder());
800            synchronized(ActivityManagerService.this) {
801                appDiedLocked(mApp, mPid, mAppThread);
802            }
803        }
804    }
805
806    static final int SHOW_ERROR_MSG = 1;
807    static final int SHOW_NOT_RESPONDING_MSG = 2;
808    static final int SHOW_FACTORY_ERROR_MSG = 3;
809    static final int UPDATE_CONFIGURATION_MSG = 4;
810    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
811    static final int WAIT_FOR_DEBUGGER_MSG = 6;
812    static final int SERVICE_TIMEOUT_MSG = 12;
813    static final int UPDATE_TIME_ZONE = 13;
814    static final int SHOW_UID_ERROR_MSG = 14;
815    static final int IM_FEELING_LUCKY_MSG = 15;
816    static final int PROC_START_TIMEOUT_MSG = 20;
817    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
818    static final int KILL_APPLICATION_MSG = 22;
819    static final int FINALIZE_PENDING_INTENT_MSG = 23;
820    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
821    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
822    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
823    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
824    static final int CLEAR_DNS_CACHE = 28;
825    static final int UPDATE_HTTP_PROXY = 29;
826    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
827    static final int DISPATCH_PROCESSES_CHANGED = 31;
828    static final int DISPATCH_PROCESS_DIED = 32;
829    static final int REPORT_MEM_USAGE = 33;
830
831    static final int FIRST_ACTIVITY_STACK_MSG = 100;
832    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
833    static final int FIRST_COMPAT_MODE_MSG = 300;
834
835    AlertDialog mUidAlert;
836    CompatModeDialog mCompatModeDialog;
837    long mLastMemUsageReportTime = 0;
838
839    final Handler mHandler = new Handler() {
840        //public Handler() {
841        //    if (localLOGV) Slog.v(TAG, "Handler started!");
842        //}
843
844        public void handleMessage(Message msg) {
845            switch (msg.what) {
846            case SHOW_ERROR_MSG: {
847                HashMap data = (HashMap) msg.obj;
848                synchronized (ActivityManagerService.this) {
849                    ProcessRecord proc = (ProcessRecord)data.get("app");
850                    if (proc != null && proc.crashDialog != null) {
851                        Slog.e(TAG, "App already has crash dialog: " + proc);
852                        return;
853                    }
854                    AppErrorResult res = (AppErrorResult) data.get("result");
855                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
856                        Dialog d = new AppErrorDialog(mContext, res, proc);
857                        d.show();
858                        proc.crashDialog = d;
859                    } else {
860                        // The device is asleep, so just pretend that the user
861                        // saw a crash dialog and hit "force quit".
862                        res.set(0);
863                    }
864                }
865
866                ensureBootCompleted();
867            } break;
868            case SHOW_NOT_RESPONDING_MSG: {
869                synchronized (ActivityManagerService.this) {
870                    HashMap data = (HashMap) msg.obj;
871                    ProcessRecord proc = (ProcessRecord)data.get("app");
872                    if (proc != null && proc.anrDialog != null) {
873                        Slog.e(TAG, "App already has anr dialog: " + proc);
874                        return;
875                    }
876
877                    Intent intent = new Intent("android.intent.action.ANR");
878                    if (!mProcessesReady) {
879                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
880                                | Intent.FLAG_RECEIVER_FOREGROUND);
881                    }
882                    broadcastIntentLocked(null, null, intent,
883                            null, null, 0, null, null, null,
884                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
885
886                    if (mShowDialogs) {
887                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
888                                mContext, proc, (ActivityRecord)data.get("activity"));
889                        d.show();
890                        proc.anrDialog = d;
891                    } else {
892                        // Just kill the app if there is no dialog to be shown.
893                        killAppAtUsersRequest(proc, null);
894                    }
895                }
896
897                ensureBootCompleted();
898            } break;
899            case SHOW_STRICT_MODE_VIOLATION_MSG: {
900                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
901                synchronized (ActivityManagerService.this) {
902                    ProcessRecord proc = (ProcessRecord) data.get("app");
903                    if (proc == null) {
904                        Slog.e(TAG, "App not found when showing strict mode dialog.");
905                        break;
906                    }
907                    if (proc.crashDialog != null) {
908                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
909                        return;
910                    }
911                    AppErrorResult res = (AppErrorResult) data.get("result");
912                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
913                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
914                        d.show();
915                        proc.crashDialog = d;
916                    } else {
917                        // The device is asleep, so just pretend that the user
918                        // saw a crash dialog and hit "force quit".
919                        res.set(0);
920                    }
921                }
922                ensureBootCompleted();
923            } break;
924            case SHOW_FACTORY_ERROR_MSG: {
925                Dialog d = new FactoryErrorDialog(
926                    mContext, msg.getData().getCharSequence("msg"));
927                d.show();
928                ensureBootCompleted();
929            } break;
930            case UPDATE_CONFIGURATION_MSG: {
931                final ContentResolver resolver = mContext.getContentResolver();
932                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
933            } break;
934            case GC_BACKGROUND_PROCESSES_MSG: {
935                synchronized (ActivityManagerService.this) {
936                    performAppGcsIfAppropriateLocked();
937                }
938            } break;
939            case WAIT_FOR_DEBUGGER_MSG: {
940                synchronized (ActivityManagerService.this) {
941                    ProcessRecord app = (ProcessRecord)msg.obj;
942                    if (msg.arg1 != 0) {
943                        if (!app.waitedForDebugger) {
944                            Dialog d = new AppWaitingForDebuggerDialog(
945                                    ActivityManagerService.this,
946                                    mContext, app);
947                            app.waitDialog = d;
948                            app.waitedForDebugger = true;
949                            d.show();
950                        }
951                    } else {
952                        if (app.waitDialog != null) {
953                            app.waitDialog.dismiss();
954                            app.waitDialog = null;
955                        }
956                    }
957                }
958            } break;
959            case SERVICE_TIMEOUT_MSG: {
960                if (mDidDexOpt) {
961                    mDidDexOpt = false;
962                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
963                    nmsg.obj = msg.obj;
964                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
965                    return;
966                }
967                mServices.serviceTimeout((ProcessRecord)msg.obj);
968            } break;
969            case UPDATE_TIME_ZONE: {
970                synchronized (ActivityManagerService.this) {
971                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
972                        ProcessRecord r = mLruProcesses.get(i);
973                        if (r.thread != null) {
974                            try {
975                                r.thread.updateTimeZone();
976                            } catch (RemoteException ex) {
977                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
978                            }
979                        }
980                    }
981                }
982            } break;
983            case CLEAR_DNS_CACHE: {
984                synchronized (ActivityManagerService.this) {
985                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
986                        ProcessRecord r = mLruProcesses.get(i);
987                        if (r.thread != null) {
988                            try {
989                                r.thread.clearDnsCache();
990                            } catch (RemoteException ex) {
991                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
992                            }
993                        }
994                    }
995                }
996            } break;
997            case UPDATE_HTTP_PROXY: {
998                ProxyProperties proxy = (ProxyProperties)msg.obj;
999                String host = "";
1000                String port = "";
1001                String exclList = "";
1002                if (proxy != null) {
1003                    host = proxy.getHost();
1004                    port = Integer.toString(proxy.getPort());
1005                    exclList = proxy.getExclusionList();
1006                }
1007                synchronized (ActivityManagerService.this) {
1008                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1009                        ProcessRecord r = mLruProcesses.get(i);
1010                        if (r.thread != null) {
1011                            try {
1012                                r.thread.setHttpProxy(host, port, exclList);
1013                            } catch (RemoteException ex) {
1014                                Slog.w(TAG, "Failed to update http proxy for: " +
1015                                        r.info.processName);
1016                            }
1017                        }
1018                    }
1019                }
1020            } break;
1021            case SHOW_UID_ERROR_MSG: {
1022                String title = "System UIDs Inconsistent";
1023                String text = "UIDs on the system are inconsistent, you need to wipe your"
1024                        + " data partition or your device will be unstable.";
1025                Log.e(TAG, title + ": " + text);
1026                if (mShowDialogs) {
1027                    // XXX This is a temporary dialog, no need to localize.
1028                    AlertDialog d = new BaseErrorDialog(mContext);
1029                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1030                    d.setCancelable(false);
1031                    d.setTitle(title);
1032                    d.setMessage(text);
1033                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1034                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1035                    mUidAlert = d;
1036                    d.show();
1037                }
1038            } break;
1039            case IM_FEELING_LUCKY_MSG: {
1040                if (mUidAlert != null) {
1041                    mUidAlert.dismiss();
1042                    mUidAlert = null;
1043                }
1044            } break;
1045            case PROC_START_TIMEOUT_MSG: {
1046                if (mDidDexOpt) {
1047                    mDidDexOpt = false;
1048                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1049                    nmsg.obj = msg.obj;
1050                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1051                    return;
1052                }
1053                ProcessRecord app = (ProcessRecord)msg.obj;
1054                synchronized (ActivityManagerService.this) {
1055                    processStartTimedOutLocked(app);
1056                }
1057            } break;
1058            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1059                synchronized (ActivityManagerService.this) {
1060                    doPendingActivityLaunchesLocked(true);
1061                }
1062            } break;
1063            case KILL_APPLICATION_MSG: {
1064                synchronized (ActivityManagerService.this) {
1065                    int uid = msg.arg1;
1066                    boolean restart = (msg.arg2 == 1);
1067                    String pkg = (String) msg.obj;
1068                    forceStopPackageLocked(pkg, uid, restart, false, true, false,
1069                            UserId.getUserId(uid));
1070                }
1071            } break;
1072            case FINALIZE_PENDING_INTENT_MSG: {
1073                ((PendingIntentRecord)msg.obj).completeFinalize();
1074            } break;
1075            case POST_HEAVY_NOTIFICATION_MSG: {
1076                INotificationManager inm = NotificationManager.getService();
1077                if (inm == null) {
1078                    return;
1079                }
1080
1081                ActivityRecord root = (ActivityRecord)msg.obj;
1082                ProcessRecord process = root.app;
1083                if (process == null) {
1084                    return;
1085                }
1086
1087                try {
1088                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1089                    String text = mContext.getString(R.string.heavy_weight_notification,
1090                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1091                    Notification notification = new Notification();
1092                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1093                    notification.when = 0;
1094                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1095                    notification.tickerText = text;
1096                    notification.defaults = 0; // please be quiet
1097                    notification.sound = null;
1098                    notification.vibrate = null;
1099                    notification.setLatestEventInfo(context, text,
1100                            mContext.getText(R.string.heavy_weight_notification_detail),
1101                            PendingIntent.getActivity(mContext, 0, root.intent,
1102                                    PendingIntent.FLAG_CANCEL_CURRENT));
1103
1104                    try {
1105                        int[] outId = new int[1];
1106                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
1107                                notification, outId);
1108                    } catch (RuntimeException e) {
1109                        Slog.w(ActivityManagerService.TAG,
1110                                "Error showing notification for heavy-weight app", e);
1111                    } catch (RemoteException e) {
1112                    }
1113                } catch (NameNotFoundException e) {
1114                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1115                }
1116            } break;
1117            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1118                INotificationManager inm = NotificationManager.getService();
1119                if (inm == null) {
1120                    return;
1121                }
1122                try {
1123                    inm.cancelNotification("android",
1124                            R.string.heavy_weight_notification);
1125                } catch (RuntimeException e) {
1126                    Slog.w(ActivityManagerService.TAG,
1127                            "Error canceling notification for service", e);
1128                } catch (RemoteException e) {
1129                }
1130            } break;
1131            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1132                synchronized (ActivityManagerService.this) {
1133                    checkExcessivePowerUsageLocked(true);
1134                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1135                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1136                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1137                }
1138            } break;
1139            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1140                synchronized (ActivityManagerService.this) {
1141                    ActivityRecord ar = (ActivityRecord)msg.obj;
1142                    if (mCompatModeDialog != null) {
1143                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1144                                ar.info.applicationInfo.packageName)) {
1145                            return;
1146                        }
1147                        mCompatModeDialog.dismiss();
1148                        mCompatModeDialog = null;
1149                    }
1150                    if (ar != null && false) {
1151                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1152                                ar.packageName)) {
1153                            int mode = mCompatModePackages.computeCompatModeLocked(
1154                                    ar.info.applicationInfo);
1155                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1156                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1157                                mCompatModeDialog = new CompatModeDialog(
1158                                        ActivityManagerService.this, mContext,
1159                                        ar.info.applicationInfo);
1160                                mCompatModeDialog.show();
1161                            }
1162                        }
1163                    }
1164                }
1165                break;
1166            }
1167            case DISPATCH_PROCESSES_CHANGED: {
1168                dispatchProcessesChanged();
1169                break;
1170            }
1171            case DISPATCH_PROCESS_DIED: {
1172                final int pid = msg.arg1;
1173                final int uid = msg.arg2;
1174                dispatchProcessDied(pid, uid);
1175                break;
1176            }
1177            case REPORT_MEM_USAGE: {
1178                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1179                if (!isDebuggable) {
1180                    return;
1181                }
1182                synchronized (ActivityManagerService.this) {
1183                    long now = SystemClock.uptimeMillis();
1184                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1185                        // Don't report more than every 5 minutes to somewhat
1186                        // avoid spamming.
1187                        return;
1188                    }
1189                    mLastMemUsageReportTime = now;
1190                }
1191                Thread thread = new Thread() {
1192                    @Override public void run() {
1193                        StringBuilder dropBuilder = new StringBuilder(1024);
1194                        StringBuilder logBuilder = new StringBuilder(1024);
1195                        StringWriter oomSw = new StringWriter();
1196                        PrintWriter oomPw = new PrintWriter(oomSw);
1197                        StringWriter catSw = new StringWriter();
1198                        PrintWriter catPw = new PrintWriter(catSw);
1199                        String[] emptyArgs = new String[] { };
1200                        StringBuilder tag = new StringBuilder(128);
1201                        StringBuilder stack = new StringBuilder(128);
1202                        tag.append("Low on memory -- ");
1203                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1204                                tag, stack);
1205                        dropBuilder.append(stack);
1206                        dropBuilder.append('\n');
1207                        dropBuilder.append('\n');
1208                        String oomString = oomSw.toString();
1209                        dropBuilder.append(oomString);
1210                        dropBuilder.append('\n');
1211                        logBuilder.append(oomString);
1212                        try {
1213                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1214                                    "procrank", });
1215                            final InputStreamReader converter = new InputStreamReader(
1216                                    proc.getInputStream());
1217                            BufferedReader in = new BufferedReader(converter);
1218                            String line;
1219                            while (true) {
1220                                line = in.readLine();
1221                                if (line == null) {
1222                                    break;
1223                                }
1224                                if (line.length() > 0) {
1225                                    logBuilder.append(line);
1226                                    logBuilder.append('\n');
1227                                }
1228                                dropBuilder.append(line);
1229                                dropBuilder.append('\n');
1230                            }
1231                            converter.close();
1232                        } catch (IOException e) {
1233                        }
1234                        synchronized (ActivityManagerService.this) {
1235                            catPw.println();
1236                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1237                            catPw.println();
1238                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1239                                    false, false, null);
1240                            catPw.println();
1241                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1242                        }
1243                        dropBuilder.append(catSw.toString());
1244                        addErrorToDropBox("lowmem", null, "system_server", null,
1245                                null, tag.toString(), dropBuilder.toString(), null, null);
1246                        Slog.i(TAG, logBuilder.toString());
1247                        synchronized (ActivityManagerService.this) {
1248                            long now = SystemClock.uptimeMillis();
1249                            if (mLastMemUsageReportTime < now) {
1250                                mLastMemUsageReportTime = now;
1251                            }
1252                        }
1253                    }
1254                };
1255                thread.start();
1256                break;
1257            }
1258            }
1259        }
1260    };
1261
1262    public static void setSystemProcess() {
1263        try {
1264            ActivityManagerService m = mSelf;
1265
1266            ServiceManager.addService("activity", m, true);
1267            ServiceManager.addService("meminfo", new MemBinder(m));
1268            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1269            ServiceManager.addService("dbinfo", new DbBinder(m));
1270            if (MONITOR_CPU_USAGE) {
1271                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1272            }
1273            ServiceManager.addService("permission", new PermissionController(m));
1274
1275            ApplicationInfo info =
1276                mSelf.mContext.getPackageManager().getApplicationInfo(
1277                            "android", STOCK_PM_FLAGS);
1278            mSystemThread.installSystemApplicationInfo(info);
1279
1280            synchronized (mSelf) {
1281                ProcessRecord app = mSelf.newProcessRecordLocked(
1282                        mSystemThread.getApplicationThread(), info,
1283                        info.processName, false);
1284                app.persistent = true;
1285                app.pid = MY_PID;
1286                app.maxAdj = ProcessList.SYSTEM_ADJ;
1287                mSelf.mProcessNames.put(app.processName, app.uid, app);
1288                synchronized (mSelf.mPidsSelfLocked) {
1289                    mSelf.mPidsSelfLocked.put(app.pid, app);
1290                }
1291                mSelf.updateLruProcessLocked(app, true, true);
1292            }
1293        } catch (PackageManager.NameNotFoundException e) {
1294            throw new RuntimeException(
1295                    "Unable to find android system package", e);
1296        }
1297    }
1298
1299    public void setWindowManager(WindowManagerService wm) {
1300        mWindowManager = wm;
1301    }
1302
1303    public static final Context main(int factoryTest) {
1304        AThread thr = new AThread();
1305        thr.start();
1306
1307        synchronized (thr) {
1308            while (thr.mService == null) {
1309                try {
1310                    thr.wait();
1311                } catch (InterruptedException e) {
1312                }
1313            }
1314        }
1315
1316        ActivityManagerService m = thr.mService;
1317        mSelf = m;
1318        ActivityThread at = ActivityThread.systemMain();
1319        mSystemThread = at;
1320        Context context = at.getSystemContext();
1321        context.setTheme(android.R.style.Theme_Holo);
1322        m.mContext = context;
1323        m.mFactoryTest = factoryTest;
1324        m.mMainStack = new ActivityStack(m, context, true);
1325
1326        m.mBatteryStatsService.publish(context);
1327        m.mUsageStatsService.publish(context);
1328
1329        synchronized (thr) {
1330            thr.mReady = true;
1331            thr.notifyAll();
1332        }
1333
1334        m.startRunning(null, null, null, null);
1335
1336        return context;
1337    }
1338
1339    public static ActivityManagerService self() {
1340        return mSelf;
1341    }
1342
1343    static class AThread extends Thread {
1344        ActivityManagerService mService;
1345        boolean mReady = false;
1346
1347        public AThread() {
1348            super("ActivityManager");
1349        }
1350
1351        public void run() {
1352            Looper.prepare();
1353
1354            android.os.Process.setThreadPriority(
1355                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1356            android.os.Process.setCanSelfBackground(false);
1357
1358            ActivityManagerService m = new ActivityManagerService();
1359
1360            synchronized (this) {
1361                mService = m;
1362                notifyAll();
1363            }
1364
1365            synchronized (this) {
1366                while (!mReady) {
1367                    try {
1368                        wait();
1369                    } catch (InterruptedException e) {
1370                    }
1371                }
1372            }
1373
1374            // For debug builds, log event loop stalls to dropbox for analysis.
1375            if (StrictMode.conditionallyEnableDebugLogging()) {
1376                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1377            }
1378
1379            Looper.loop();
1380        }
1381    }
1382
1383    static class MemBinder extends Binder {
1384        ActivityManagerService mActivityManagerService;
1385        MemBinder(ActivityManagerService activityManagerService) {
1386            mActivityManagerService = activityManagerService;
1387        }
1388
1389        @Override
1390        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1391            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1392                    != PackageManager.PERMISSION_GRANTED) {
1393                pw.println("Permission Denial: can't dump meminfo from from pid="
1394                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1395                        + " without permission " + android.Manifest.permission.DUMP);
1396                return;
1397            }
1398
1399            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1400                    false, null, null, null);
1401        }
1402    }
1403
1404    static class GraphicsBinder extends Binder {
1405        ActivityManagerService mActivityManagerService;
1406        GraphicsBinder(ActivityManagerService activityManagerService) {
1407            mActivityManagerService = activityManagerService;
1408        }
1409
1410        @Override
1411        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1412            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1413                    != PackageManager.PERMISSION_GRANTED) {
1414                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1415                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1416                        + " without permission " + android.Manifest.permission.DUMP);
1417                return;
1418            }
1419
1420            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1421        }
1422    }
1423
1424    static class DbBinder extends Binder {
1425        ActivityManagerService mActivityManagerService;
1426        DbBinder(ActivityManagerService activityManagerService) {
1427            mActivityManagerService = activityManagerService;
1428        }
1429
1430        @Override
1431        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1432            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1433                    != PackageManager.PERMISSION_GRANTED) {
1434                pw.println("Permission Denial: can't dump dbinfo from from pid="
1435                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1436                        + " without permission " + android.Manifest.permission.DUMP);
1437                return;
1438            }
1439
1440            mActivityManagerService.dumpDbInfo(fd, pw, args);
1441        }
1442    }
1443
1444    static class CpuBinder extends Binder {
1445        ActivityManagerService mActivityManagerService;
1446        CpuBinder(ActivityManagerService activityManagerService) {
1447            mActivityManagerService = activityManagerService;
1448        }
1449
1450        @Override
1451        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1452            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1453                    != PackageManager.PERMISSION_GRANTED) {
1454                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1455                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1456                        + " without permission " + android.Manifest.permission.DUMP);
1457                return;
1458            }
1459
1460            synchronized (mActivityManagerService.mProcessStatsThread) {
1461                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1462                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1463                        SystemClock.uptimeMillis()));
1464            }
1465        }
1466    }
1467
1468    private ActivityManagerService() {
1469        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1470
1471        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1472        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1473        mBroadcastQueues[0] = mFgBroadcastQueue;
1474        mBroadcastQueues[1] = mBgBroadcastQueue;
1475
1476        mServices = new ActiveServices(this);
1477
1478        File dataDir = Environment.getDataDirectory();
1479        File systemDir = new File(dataDir, "system");
1480        systemDir.mkdirs();
1481        mBatteryStatsService = new BatteryStatsService(new File(
1482                systemDir, "batterystats.bin").toString());
1483        mBatteryStatsService.getActiveStatistics().readLocked();
1484        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1485        mOnBattery = DEBUG_POWER ? true
1486                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1487        mBatteryStatsService.getActiveStatistics().setCallback(this);
1488
1489        mUsageStatsService = new UsageStatsService(new File(
1490                systemDir, "usagestats").toString());
1491        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1492
1493        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1494            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1495
1496        mConfiguration.setToDefaults();
1497        mConfiguration.locale = Locale.getDefault();
1498        mConfigurationSeq = mConfiguration.seq = 1;
1499        mProcessStats.init();
1500
1501        mCompatModePackages = new CompatModePackages(this, systemDir);
1502
1503        // Add ourself to the Watchdog monitors.
1504        Watchdog.getInstance().addMonitor(this);
1505
1506        mProcessStatsThread = new Thread("ProcessStats") {
1507            public void run() {
1508                while (true) {
1509                    try {
1510                        try {
1511                            synchronized(this) {
1512                                final long now = SystemClock.uptimeMillis();
1513                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1514                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1515                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1516                                //        + ", write delay=" + nextWriteDelay);
1517                                if (nextWriteDelay < nextCpuDelay) {
1518                                    nextCpuDelay = nextWriteDelay;
1519                                }
1520                                if (nextCpuDelay > 0) {
1521                                    mProcessStatsMutexFree.set(true);
1522                                    this.wait(nextCpuDelay);
1523                                }
1524                            }
1525                        } catch (InterruptedException e) {
1526                        }
1527                        updateCpuStatsNow();
1528                    } catch (Exception e) {
1529                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1530                    }
1531                }
1532            }
1533        };
1534        mProcessStatsThread.start();
1535    }
1536
1537    @Override
1538    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1539            throws RemoteException {
1540        if (code == SYSPROPS_TRANSACTION) {
1541            // We need to tell all apps about the system property change.
1542            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1543            synchronized(this) {
1544                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1545                    final int NA = apps.size();
1546                    for (int ia=0; ia<NA; ia++) {
1547                        ProcessRecord app = apps.valueAt(ia);
1548                        if (app.thread != null) {
1549                            procs.add(app.thread.asBinder());
1550                        }
1551                    }
1552                }
1553            }
1554
1555            int N = procs.size();
1556            for (int i=0; i<N; i++) {
1557                Parcel data2 = Parcel.obtain();
1558                try {
1559                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1560                } catch (RemoteException e) {
1561                }
1562                data2.recycle();
1563            }
1564        }
1565        try {
1566            return super.onTransact(code, data, reply, flags);
1567        } catch (RuntimeException e) {
1568            // The activity manager only throws security exceptions, so let's
1569            // log all others.
1570            if (!(e instanceof SecurityException)) {
1571                Slog.e(TAG, "Activity Manager Crash", e);
1572            }
1573            throw e;
1574        }
1575    }
1576
1577    void updateCpuStats() {
1578        final long now = SystemClock.uptimeMillis();
1579        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1580            return;
1581        }
1582        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1583            synchronized (mProcessStatsThread) {
1584                mProcessStatsThread.notify();
1585            }
1586        }
1587    }
1588
1589    void updateCpuStatsNow() {
1590        synchronized (mProcessStatsThread) {
1591            mProcessStatsMutexFree.set(false);
1592            final long now = SystemClock.uptimeMillis();
1593            boolean haveNewCpuStats = false;
1594
1595            if (MONITOR_CPU_USAGE &&
1596                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1597                mLastCpuTime.set(now);
1598                haveNewCpuStats = true;
1599                mProcessStats.update();
1600                //Slog.i(TAG, mProcessStats.printCurrentState());
1601                //Slog.i(TAG, "Total CPU usage: "
1602                //        + mProcessStats.getTotalCpuPercent() + "%");
1603
1604                // Slog the cpu usage if the property is set.
1605                if ("true".equals(SystemProperties.get("events.cpu"))) {
1606                    int user = mProcessStats.getLastUserTime();
1607                    int system = mProcessStats.getLastSystemTime();
1608                    int iowait = mProcessStats.getLastIoWaitTime();
1609                    int irq = mProcessStats.getLastIrqTime();
1610                    int softIrq = mProcessStats.getLastSoftIrqTime();
1611                    int idle = mProcessStats.getLastIdleTime();
1612
1613                    int total = user + system + iowait + irq + softIrq + idle;
1614                    if (total == 0) total = 1;
1615
1616                    EventLog.writeEvent(EventLogTags.CPU,
1617                            ((user+system+iowait+irq+softIrq) * 100) / total,
1618                            (user * 100) / total,
1619                            (system * 100) / total,
1620                            (iowait * 100) / total,
1621                            (irq * 100) / total,
1622                            (softIrq * 100) / total);
1623                }
1624            }
1625
1626            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1627            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1628            synchronized(bstats) {
1629                synchronized(mPidsSelfLocked) {
1630                    if (haveNewCpuStats) {
1631                        if (mOnBattery) {
1632                            int perc = bstats.startAddingCpuLocked();
1633                            int totalUTime = 0;
1634                            int totalSTime = 0;
1635                            final int N = mProcessStats.countStats();
1636                            for (int i=0; i<N; i++) {
1637                                ProcessStats.Stats st = mProcessStats.getStats(i);
1638                                if (!st.working) {
1639                                    continue;
1640                                }
1641                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1642                                int otherUTime = (st.rel_utime*perc)/100;
1643                                int otherSTime = (st.rel_stime*perc)/100;
1644                                totalUTime += otherUTime;
1645                                totalSTime += otherSTime;
1646                                if (pr != null) {
1647                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1648                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1649                                            st.rel_stime-otherSTime);
1650                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1651                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1652                                } else {
1653                                    BatteryStatsImpl.Uid.Proc ps =
1654                                            bstats.getProcessStatsLocked(st.name, st.pid);
1655                                    if (ps != null) {
1656                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1657                                                st.rel_stime-otherSTime);
1658                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1659                                    }
1660                                }
1661                            }
1662                            bstats.finishAddingCpuLocked(perc, totalUTime,
1663                                    totalSTime, cpuSpeedTimes);
1664                        }
1665                    }
1666                }
1667
1668                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1669                    mLastWriteTime = now;
1670                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1671                }
1672            }
1673        }
1674    }
1675
1676    @Override
1677    public void batteryNeedsCpuUpdate() {
1678        updateCpuStatsNow();
1679    }
1680
1681    @Override
1682    public void batteryPowerChanged(boolean onBattery) {
1683        // When plugging in, update the CPU stats first before changing
1684        // the plug state.
1685        updateCpuStatsNow();
1686        synchronized (this) {
1687            synchronized(mPidsSelfLocked) {
1688                mOnBattery = DEBUG_POWER ? true : onBattery;
1689            }
1690        }
1691    }
1692
1693    /**
1694     * Initialize the application bind args. These are passed to each
1695     * process when the bindApplication() IPC is sent to the process. They're
1696     * lazily setup to make sure the services are running when they're asked for.
1697     */
1698    private HashMap<String, IBinder> getCommonServicesLocked() {
1699        if (mAppBindArgs == null) {
1700            mAppBindArgs = new HashMap<String, IBinder>();
1701
1702            // Setup the application init args
1703            mAppBindArgs.put("package", ServiceManager.getService("package"));
1704            mAppBindArgs.put("window", ServiceManager.getService("window"));
1705            mAppBindArgs.put(Context.ALARM_SERVICE,
1706                    ServiceManager.getService(Context.ALARM_SERVICE));
1707        }
1708        return mAppBindArgs;
1709    }
1710
1711    final void setFocusedActivityLocked(ActivityRecord r) {
1712        if (mFocusedActivity != r) {
1713            mFocusedActivity = r;
1714            if (r != null) {
1715                mWindowManager.setFocusedApp(r.appToken, true);
1716            }
1717        }
1718    }
1719
1720    private final void updateLruProcessInternalLocked(ProcessRecord app,
1721            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1722        // put it on the LRU to keep track of when it should be exited.
1723        int lrui = mLruProcesses.indexOf(app);
1724        if (lrui >= 0) mLruProcesses.remove(lrui);
1725
1726        int i = mLruProcesses.size()-1;
1727        int skipTop = 0;
1728
1729        app.lruSeq = mLruSeq;
1730
1731        // compute the new weight for this process.
1732        if (updateActivityTime) {
1733            app.lastActivityTime = SystemClock.uptimeMillis();
1734        }
1735        if (app.activities.size() > 0) {
1736            // If this process has activities, we more strongly want to keep
1737            // it around.
1738            app.lruWeight = app.lastActivityTime;
1739        } else if (app.pubProviders.size() > 0) {
1740            // If this process contains content providers, we want to keep
1741            // it a little more strongly.
1742            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1743            // Also don't let it kick out the first few "real" hidden processes.
1744            skipTop = ProcessList.MIN_HIDDEN_APPS;
1745        } else {
1746            // If this process doesn't have activities, we less strongly
1747            // want to keep it around, and generally want to avoid getting
1748            // in front of any very recently used activities.
1749            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1750            // Also don't let it kick out the first few "real" hidden processes.
1751            skipTop = ProcessList.MIN_HIDDEN_APPS;
1752        }
1753
1754        while (i >= 0) {
1755            ProcessRecord p = mLruProcesses.get(i);
1756            // If this app shouldn't be in front of the first N background
1757            // apps, then skip over that many that are currently hidden.
1758            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1759                skipTop--;
1760            }
1761            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1762                mLruProcesses.add(i+1, app);
1763                break;
1764            }
1765            i--;
1766        }
1767        if (i < 0) {
1768            mLruProcesses.add(0, app);
1769        }
1770
1771        // If the app is currently using a content provider or service,
1772        // bump those processes as well.
1773        if (app.connections.size() > 0) {
1774            for (ConnectionRecord cr : app.connections) {
1775                if (cr.binding != null && cr.binding.service != null
1776                        && cr.binding.service.app != null
1777                        && cr.binding.service.app.lruSeq != mLruSeq) {
1778                    updateLruProcessInternalLocked(cr.binding.service.app, false,
1779                            updateActivityTime, i+1);
1780                }
1781            }
1782        }
1783        for (int j=app.conProviders.size()-1; j>=0; j--) {
1784            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1785            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1786                updateLruProcessInternalLocked(cpr.proc, false,
1787                        updateActivityTime, i+1);
1788            }
1789        }
1790
1791        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1792        if (oomAdj) {
1793            updateOomAdjLocked();
1794        }
1795    }
1796
1797    final void updateLruProcessLocked(ProcessRecord app,
1798            boolean oomAdj, boolean updateActivityTime) {
1799        mLruSeq++;
1800        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1801    }
1802
1803    final ProcessRecord getProcessRecordLocked(
1804            String processName, int uid) {
1805        if (uid == Process.SYSTEM_UID) {
1806            // The system gets to run in any process.  If there are multiple
1807            // processes with the same uid, just pick the first (this
1808            // should never happen).
1809            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1810                    processName);
1811            if (procs == null) return null;
1812            final int N = procs.size();
1813            for (int i = 0; i < N; i++) {
1814                if (UserId.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1815            }
1816        }
1817        ProcessRecord proc = mProcessNames.get(processName, uid);
1818        return proc;
1819    }
1820
1821    void ensurePackageDexOpt(String packageName) {
1822        IPackageManager pm = AppGlobals.getPackageManager();
1823        try {
1824            if (pm.performDexOpt(packageName)) {
1825                mDidDexOpt = true;
1826            }
1827        } catch (RemoteException e) {
1828        }
1829    }
1830
1831    boolean isNextTransitionForward() {
1832        int transit = mWindowManager.getPendingAppTransition();
1833        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1834                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1835                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1836    }
1837
1838    final ProcessRecord startProcessLocked(String processName,
1839            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1840            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1841            boolean isolated) {
1842        ProcessRecord app;
1843        if (!isolated) {
1844            app = getProcessRecordLocked(processName, info.uid);
1845        } else {
1846            // If this is an isolated process, it can't re-use an existing process.
1847            app = null;
1848        }
1849        // We don't have to do anything more if:
1850        // (1) There is an existing application record; and
1851        // (2) The caller doesn't think it is dead, OR there is no thread
1852        //     object attached to it so we know it couldn't have crashed; and
1853        // (3) There is a pid assigned to it, so it is either starting or
1854        //     already running.
1855        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1856                + " app=" + app + " knownToBeDead=" + knownToBeDead
1857                + " thread=" + (app != null ? app.thread : null)
1858                + " pid=" + (app != null ? app.pid : -1));
1859        if (app != null && app.pid > 0) {
1860            if (!knownToBeDead || app.thread == null) {
1861                // We already have the app running, or are waiting for it to
1862                // come up (we have a pid but not yet its thread), so keep it.
1863                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1864                // If this is a new package in the process, add the package to the list
1865                app.addPackage(info.packageName);
1866                return app;
1867            } else {
1868                // An application record is attached to a previous process,
1869                // clean it up now.
1870                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1871                handleAppDiedLocked(app, true, true);
1872            }
1873        }
1874
1875        String hostingNameStr = hostingName != null
1876                ? hostingName.flattenToShortString() : null;
1877
1878        if (!isolated) {
1879            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1880                // If we are in the background, then check to see if this process
1881                // is bad.  If so, we will just silently fail.
1882                if (mBadProcesses.get(info.processName, info.uid) != null) {
1883                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1884                            + "/" + info.processName);
1885                    return null;
1886                }
1887            } else {
1888                // When the user is explicitly starting a process, then clear its
1889                // crash count so that we won't make it bad until they see at
1890                // least one crash dialog again, and make the process good again
1891                // if it had been bad.
1892                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1893                        + "/" + info.processName);
1894                mProcessCrashTimes.remove(info.processName, info.uid);
1895                if (mBadProcesses.get(info.processName, info.uid) != null) {
1896                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1897                            info.processName);
1898                    mBadProcesses.remove(info.processName, info.uid);
1899                    if (app != null) {
1900                        app.bad = false;
1901                    }
1902                }
1903            }
1904        }
1905
1906        if (app == null) {
1907            app = newProcessRecordLocked(null, info, processName, isolated);
1908            if (app == null) {
1909                Slog.w(TAG, "Failed making new process record for "
1910                        + processName + "/" + info.uid + " isolated=" + isolated);
1911                return null;
1912            }
1913            mProcessNames.put(processName, app.uid, app);
1914            if (isolated) {
1915                mIsolatedProcesses.put(app.uid, app);
1916            }
1917        } else {
1918            // If this is a new package in the process, add the package to the list
1919            app.addPackage(info.packageName);
1920        }
1921
1922        // If the system is not ready yet, then hold off on starting this
1923        // process until it is.
1924        if (!mProcessesReady
1925                && !isAllowedWhileBooting(info)
1926                && !allowWhileBooting) {
1927            if (!mProcessesOnHold.contains(app)) {
1928                mProcessesOnHold.add(app);
1929            }
1930            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1931            return app;
1932        }
1933
1934        startProcessLocked(app, hostingType, hostingNameStr);
1935        return (app.pid != 0) ? app : null;
1936    }
1937
1938    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1939        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1940    }
1941
1942    private final void startProcessLocked(ProcessRecord app,
1943            String hostingType, String hostingNameStr) {
1944        if (app.pid > 0 && app.pid != MY_PID) {
1945            synchronized (mPidsSelfLocked) {
1946                mPidsSelfLocked.remove(app.pid);
1947                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1948            }
1949            app.pid = 0;
1950        }
1951
1952        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1953                "startProcessLocked removing on hold: " + app);
1954        mProcessesOnHold.remove(app);
1955
1956        updateCpuStats();
1957
1958        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1959        mProcDeaths[0] = 0;
1960
1961        try {
1962            int uid = app.uid;
1963
1964            int[] gids = null;
1965            if (!app.isolated) {
1966                try {
1967                    gids = mContext.getPackageManager().getPackageGids(
1968                            app.info.packageName);
1969                } catch (PackageManager.NameNotFoundException e) {
1970                    Slog.w(TAG, "Unable to retrieve gids", e);
1971                }
1972            }
1973            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1974                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1975                        && mTopComponent != null
1976                        && app.processName.equals(mTopComponent.getPackageName())) {
1977                    uid = 0;
1978                }
1979                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1980                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1981                    uid = 0;
1982                }
1983            }
1984            int debugFlags = 0;
1985            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1986                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1987                // Also turn on CheckJNI for debuggable apps. It's quite
1988                // awkward to turn on otherwise.
1989                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1990            }
1991            // Run the app in safe mode if its manifest requests so or the
1992            // system is booted in safe mode.
1993            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1994                Zygote.systemInSafeMode == true) {
1995                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1996            }
1997            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1998                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1999            }
2000            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2001                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2002            }
2003            if ("1".equals(SystemProperties.get("debug.assert"))) {
2004                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2005            }
2006
2007            // Start the process.  It will either succeed and return a result containing
2008            // the PID of the new process, or else throw a RuntimeException.
2009            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2010                    app.processName, uid, uid, gids, debugFlags,
2011                    app.info.targetSdkVersion, null, null);
2012
2013            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2014            synchronized (bs) {
2015                if (bs.isOnBattery()) {
2016                    app.batteryStats.incStartsLocked();
2017                }
2018            }
2019
2020            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2021                    app.processName, hostingType,
2022                    hostingNameStr != null ? hostingNameStr : "");
2023
2024            if (app.persistent) {
2025                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2026            }
2027
2028            StringBuilder buf = mStringBuilder;
2029            buf.setLength(0);
2030            buf.append("Start proc ");
2031            buf.append(app.processName);
2032            buf.append(" for ");
2033            buf.append(hostingType);
2034            if (hostingNameStr != null) {
2035                buf.append(" ");
2036                buf.append(hostingNameStr);
2037            }
2038            buf.append(": pid=");
2039            buf.append(startResult.pid);
2040            buf.append(" uid=");
2041            buf.append(uid);
2042            buf.append(" gids={");
2043            if (gids != null) {
2044                for (int gi=0; gi<gids.length; gi++) {
2045                    if (gi != 0) buf.append(", ");
2046                    buf.append(gids[gi]);
2047
2048                }
2049            }
2050            buf.append("}");
2051            Slog.i(TAG, buf.toString());
2052            app.pid = startResult.pid;
2053            app.usingWrapper = startResult.usingWrapper;
2054            app.removed = false;
2055            synchronized (mPidsSelfLocked) {
2056                this.mPidsSelfLocked.put(startResult.pid, app);
2057                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2058                msg.obj = app;
2059                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2060                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2061            }
2062        } catch (RuntimeException e) {
2063            // XXX do better error recovery.
2064            app.pid = 0;
2065            Slog.e(TAG, "Failure starting process " + app.processName, e);
2066        }
2067    }
2068
2069    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2070        if (resumed) {
2071            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2072        } else {
2073            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2074        }
2075    }
2076
2077    boolean startHomeActivityLocked(int userId) {
2078        if (mHeadless) {
2079            // Added because none of the other calls to ensureBootCompleted seem to fire
2080            // when running headless.
2081            ensureBootCompleted();
2082            return false;
2083        }
2084
2085        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2086                && mTopAction == null) {
2087            // We are running in factory test mode, but unable to find
2088            // the factory test app, so just sit around displaying the
2089            // error message and don't try to start anything.
2090            return false;
2091        }
2092        Intent intent = new Intent(
2093            mTopAction,
2094            mTopData != null ? Uri.parse(mTopData) : null);
2095        intent.setComponent(mTopComponent);
2096        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2097            intent.addCategory(Intent.CATEGORY_HOME);
2098        }
2099        ActivityInfo aInfo =
2100            intent.resolveActivityInfo(mContext.getPackageManager(),
2101                    STOCK_PM_FLAGS);
2102        if (aInfo != null) {
2103            intent.setComponent(new ComponentName(
2104                    aInfo.applicationInfo.packageName, aInfo.name));
2105            // Don't do this if the home app is currently being
2106            // instrumented.
2107            aInfo = new ActivityInfo(aInfo);
2108            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2109            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2110                    aInfo.applicationInfo.uid);
2111            if (app == null || app.instrumentationClass == null) {
2112                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2113                mMainStack.startActivityLocked(null, intent, null, aInfo,
2114                        null, null, 0, 0, 0, 0, null, false, null);
2115            }
2116        }
2117
2118        return true;
2119    }
2120
2121    /**
2122     * Starts the "new version setup screen" if appropriate.
2123     */
2124    void startSetupActivityLocked() {
2125        // Only do this once per boot.
2126        if (mCheckedForSetup) {
2127            return;
2128        }
2129
2130        // We will show this screen if the current one is a different
2131        // version than the last one shown, and we are not running in
2132        // low-level factory test mode.
2133        final ContentResolver resolver = mContext.getContentResolver();
2134        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2135                Settings.Secure.getInt(resolver,
2136                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2137            mCheckedForSetup = true;
2138
2139            // See if we should be showing the platform update setup UI.
2140            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2141            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2142                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2143
2144            // We don't allow third party apps to replace this.
2145            ResolveInfo ri = null;
2146            for (int i=0; ris != null && i<ris.size(); i++) {
2147                if ((ris.get(i).activityInfo.applicationInfo.flags
2148                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2149                    ri = ris.get(i);
2150                    break;
2151                }
2152            }
2153
2154            if (ri != null) {
2155                String vers = ri.activityInfo.metaData != null
2156                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2157                        : null;
2158                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2159                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2160                            Intent.METADATA_SETUP_VERSION);
2161                }
2162                String lastVers = Settings.Secure.getString(
2163                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2164                if (vers != null && !vers.equals(lastVers)) {
2165                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2166                    intent.setComponent(new ComponentName(
2167                            ri.activityInfo.packageName, ri.activityInfo.name));
2168                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2169                            null, null, 0, 0, 0, 0, null, false, null);
2170                }
2171            }
2172        }
2173    }
2174
2175    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2176        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2177    }
2178
2179    void enforceNotIsolatedCaller(String caller) {
2180        if (UserId.isIsolated(Binder.getCallingUid())) {
2181            throw new SecurityException("Isolated process not allowed to call " + caller);
2182        }
2183    }
2184
2185    public int getFrontActivityScreenCompatMode() {
2186        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2187        synchronized (this) {
2188            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2189        }
2190    }
2191
2192    public void setFrontActivityScreenCompatMode(int mode) {
2193        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2194                "setFrontActivityScreenCompatMode");
2195        synchronized (this) {
2196            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2197        }
2198    }
2199
2200    public int getPackageScreenCompatMode(String packageName) {
2201        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2202        synchronized (this) {
2203            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2204        }
2205    }
2206
2207    public void setPackageScreenCompatMode(String packageName, int mode) {
2208        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2209                "setPackageScreenCompatMode");
2210        synchronized (this) {
2211            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2212        }
2213    }
2214
2215    public boolean getPackageAskScreenCompat(String packageName) {
2216        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2217        synchronized (this) {
2218            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2219        }
2220    }
2221
2222    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2223        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2224                "setPackageAskScreenCompat");
2225        synchronized (this) {
2226            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2227        }
2228    }
2229
2230    void reportResumedActivityLocked(ActivityRecord r) {
2231        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2232        updateUsageStats(r, true);
2233    }
2234
2235    private void dispatchProcessesChanged() {
2236        int N;
2237        synchronized (this) {
2238            N = mPendingProcessChanges.size();
2239            if (mActiveProcessChanges.length < N) {
2240                mActiveProcessChanges = new ProcessChangeItem[N];
2241            }
2242            mPendingProcessChanges.toArray(mActiveProcessChanges);
2243            mAvailProcessChanges.addAll(mPendingProcessChanges);
2244            mPendingProcessChanges.clear();
2245            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2246        }
2247        int i = mProcessObservers.beginBroadcast();
2248        while (i > 0) {
2249            i--;
2250            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2251            if (observer != null) {
2252                try {
2253                    for (int j=0; j<N; j++) {
2254                        ProcessChangeItem item = mActiveProcessChanges[j];
2255                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2256                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2257                                    + item.pid + " uid=" + item.uid + ": "
2258                                    + item.foregroundActivities);
2259                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2260                                    item.foregroundActivities);
2261                        }
2262                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2263                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2264                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2265                            observer.onImportanceChanged(item.pid, item.uid,
2266                                    item.importance);
2267                        }
2268                    }
2269                } catch (RemoteException e) {
2270                }
2271            }
2272        }
2273        mProcessObservers.finishBroadcast();
2274    }
2275
2276    private void dispatchProcessDied(int pid, int uid) {
2277        int i = mProcessObservers.beginBroadcast();
2278        while (i > 0) {
2279            i--;
2280            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2281            if (observer != null) {
2282                try {
2283                    observer.onProcessDied(pid, uid);
2284                } catch (RemoteException e) {
2285                }
2286            }
2287        }
2288        mProcessObservers.finishBroadcast();
2289    }
2290
2291    final void doPendingActivityLaunchesLocked(boolean doResume) {
2292        final int N = mPendingActivityLaunches.size();
2293        if (N <= 0) {
2294            return;
2295        }
2296        for (int i=0; i<N; i++) {
2297            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2298            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2299                    pal.startFlags, doResume && i == (N-1), null);
2300        }
2301        mPendingActivityLaunches.clear();
2302    }
2303
2304    public final int startActivity(IApplicationThread caller,
2305            Intent intent, String resolvedType, IBinder resultTo,
2306            String resultWho, int requestCode, int startFlags,
2307            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2308        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2309                startFlags, profileFile, profileFd, options, UserId.getCallingUserId());
2310    }
2311
2312    public final int startActivityAsUser(IApplicationThread caller,
2313            Intent intent, String resolvedType, IBinder resultTo,
2314            String resultWho, int requestCode, int startFlags,
2315            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2316        enforceNotIsolatedCaller("startActivity");
2317        if (userId != UserId.getCallingUserId()) {
2318            // Requesting a different user, make sure that they have the permission
2319            if (checkComponentPermission(
2320                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2321                    Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
2322                    == PackageManager.PERMISSION_GRANTED) {
2323                // Translate to the current user id, if caller wasn't aware
2324                if (userId == UserId.USER_CURRENT) {
2325                    userId = mCurrentUserId;
2326                }
2327            } else {
2328                String msg = "Permission Denial: "
2329                        + "Request to startActivity as user " + userId
2330                        + " but is calling from user " + UserId.getCallingUserId()
2331                        + "; this requires "
2332                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
2333                Slog.w(TAG, msg);
2334                throw new SecurityException(msg);
2335            }
2336        } else {
2337            if (intent.getCategories() != null
2338                    && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2339                // Requesting home, set the identity to the current user
2340                // HACK!
2341                userId = mCurrentUserId;
2342            } else {
2343                // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
2344                // the current user's userId
2345                if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
2346                    userId = 0;
2347                } else {
2348                    userId = Binder.getOrigCallingUser();
2349                }
2350            }
2351        }
2352        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2353                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2354                null, null, options, userId);
2355    }
2356
2357    public final WaitResult startActivityAndWait(IApplicationThread caller,
2358            Intent intent, String resolvedType, IBinder resultTo,
2359            String resultWho, int requestCode, int startFlags, String profileFile,
2360            ParcelFileDescriptor profileFd, Bundle options) {
2361        enforceNotIsolatedCaller("startActivityAndWait");
2362        WaitResult res = new WaitResult();
2363        int userId = Binder.getOrigCallingUser();
2364        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2365                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2366                res, null, options, userId);
2367        return res;
2368    }
2369
2370    public final int startActivityWithConfig(IApplicationThread caller,
2371            Intent intent, String resolvedType, IBinder resultTo,
2372            String resultWho, int requestCode, int startFlags, Configuration config,
2373            Bundle options) {
2374        enforceNotIsolatedCaller("startActivityWithConfig");
2375        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2376                resultTo, resultWho, requestCode, startFlags,
2377                null, null, null, config, options, Binder.getOrigCallingUser());
2378        return ret;
2379    }
2380
2381    public int startActivityIntentSender(IApplicationThread caller,
2382            IntentSender intent, Intent fillInIntent, String resolvedType,
2383            IBinder resultTo, String resultWho, int requestCode,
2384            int flagsMask, int flagsValues, Bundle options) {
2385        enforceNotIsolatedCaller("startActivityIntentSender");
2386        // Refuse possible leaked file descriptors
2387        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2388            throw new IllegalArgumentException("File descriptors passed in Intent");
2389        }
2390
2391        IIntentSender sender = intent.getTarget();
2392        if (!(sender instanceof PendingIntentRecord)) {
2393            throw new IllegalArgumentException("Bad PendingIntent object");
2394        }
2395
2396        PendingIntentRecord pir = (PendingIntentRecord)sender;
2397
2398        synchronized (this) {
2399            // If this is coming from the currently resumed activity, it is
2400            // effectively saying that app switches are allowed at this point.
2401            if (mMainStack.mResumedActivity != null
2402                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2403                            Binder.getCallingUid()) {
2404                mAppSwitchesAllowedTime = 0;
2405            }
2406        }
2407        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2408                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2409        return ret;
2410    }
2411
2412    public boolean startNextMatchingActivity(IBinder callingActivity,
2413            Intent intent, Bundle options) {
2414        // Refuse possible leaked file descriptors
2415        if (intent != null && intent.hasFileDescriptors() == true) {
2416            throw new IllegalArgumentException("File descriptors passed in Intent");
2417        }
2418
2419        synchronized (this) {
2420            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2421            if (r == null) {
2422                ActivityOptions.abort(options);
2423                return false;
2424            }
2425            if (r.app == null || r.app.thread == null) {
2426                // The caller is not running...  d'oh!
2427                ActivityOptions.abort(options);
2428                return false;
2429            }
2430            intent = new Intent(intent);
2431            // The caller is not allowed to change the data.
2432            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2433            // And we are resetting to find the next component...
2434            intent.setComponent(null);
2435
2436            ActivityInfo aInfo = null;
2437            try {
2438                List<ResolveInfo> resolves =
2439                    AppGlobals.getPackageManager().queryIntentActivities(
2440                            intent, r.resolvedType,
2441                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2442                            UserId.getCallingUserId());
2443
2444                // Look for the original activity in the list...
2445                final int N = resolves != null ? resolves.size() : 0;
2446                for (int i=0; i<N; i++) {
2447                    ResolveInfo rInfo = resolves.get(i);
2448                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2449                            && rInfo.activityInfo.name.equals(r.info.name)) {
2450                        // We found the current one...  the next matching is
2451                        // after it.
2452                        i++;
2453                        if (i<N) {
2454                            aInfo = resolves.get(i).activityInfo;
2455                        }
2456                        break;
2457                    }
2458                }
2459            } catch (RemoteException e) {
2460            }
2461
2462            if (aInfo == null) {
2463                // Nobody who is next!
2464                ActivityOptions.abort(options);
2465                return false;
2466            }
2467
2468            intent.setComponent(new ComponentName(
2469                    aInfo.applicationInfo.packageName, aInfo.name));
2470            intent.setFlags(intent.getFlags()&~(
2471                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2472                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2473                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2474                    Intent.FLAG_ACTIVITY_NEW_TASK));
2475
2476            // Okay now we need to start the new activity, replacing the
2477            // currently running activity.  This is a little tricky because
2478            // we want to start the new one as if the current one is finished,
2479            // but not finish the current one first so that there is no flicker.
2480            // And thus...
2481            final boolean wasFinishing = r.finishing;
2482            r.finishing = true;
2483
2484            // Propagate reply information over to the new activity.
2485            final ActivityRecord resultTo = r.resultTo;
2486            final String resultWho = r.resultWho;
2487            final int requestCode = r.requestCode;
2488            r.resultTo = null;
2489            if (resultTo != null) {
2490                resultTo.removeResultsLocked(r, resultWho, requestCode);
2491            }
2492
2493            final long origId = Binder.clearCallingIdentity();
2494            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2495                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2496                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2497                    options, false, null);
2498            Binder.restoreCallingIdentity(origId);
2499
2500            r.finishing = wasFinishing;
2501            if (res != ActivityManager.START_SUCCESS) {
2502                return false;
2503            }
2504            return true;
2505        }
2506    }
2507
2508    public final int startActivityInPackage(int uid,
2509            Intent intent, String resolvedType, IBinder resultTo,
2510            String resultWho, int requestCode, int startFlags, Bundle options) {
2511
2512        // This is so super not safe, that only the system (or okay root)
2513        // can do it.
2514        int userId = Binder.getOrigCallingUser();
2515        final int callingUid = Binder.getCallingUid();
2516        if (callingUid != 0 && callingUid != Process.myUid()) {
2517            throw new SecurityException(
2518                    "startActivityInPackage only available to the system");
2519        }
2520
2521        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2522                resultTo, resultWho, requestCode, startFlags,
2523                null, null, null, null, options, userId);
2524        return ret;
2525    }
2526
2527    public final int startActivities(IApplicationThread caller,
2528            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2529        enforceNotIsolatedCaller("startActivities");
2530        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2531                options, Binder.getOrigCallingUser());
2532        return ret;
2533    }
2534
2535    public final int startActivitiesInPackage(int uid,
2536            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2537            Bundle options) {
2538
2539        // This is so super not safe, that only the system (or okay root)
2540        // can do it.
2541        final int callingUid = Binder.getCallingUid();
2542        if (callingUid != 0 && callingUid != Process.myUid()) {
2543            throw new SecurityException(
2544                    "startActivityInPackage only available to the system");
2545        }
2546        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2547                options, UserId.getUserId(uid));
2548        return ret;
2549    }
2550
2551    final void addRecentTaskLocked(TaskRecord task) {
2552        int N = mRecentTasks.size();
2553        // Quick case: check if the top-most recent task is the same.
2554        if (N > 0 && mRecentTasks.get(0) == task) {
2555            return;
2556        }
2557        // Remove any existing entries that are the same kind of task.
2558        for (int i=0; i<N; i++) {
2559            TaskRecord tr = mRecentTasks.get(i);
2560            if (task.userId == tr.userId
2561                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2562                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2563                mRecentTasks.remove(i);
2564                i--;
2565                N--;
2566                if (task.intent == null) {
2567                    // If the new recent task we are adding is not fully
2568                    // specified, then replace it with the existing recent task.
2569                    task = tr;
2570                }
2571            }
2572        }
2573        if (N >= MAX_RECENT_TASKS) {
2574            mRecentTasks.remove(N-1);
2575        }
2576        mRecentTasks.add(0, task);
2577    }
2578
2579    public void setRequestedOrientation(IBinder token,
2580            int requestedOrientation) {
2581        synchronized (this) {
2582            ActivityRecord r = mMainStack.isInStackLocked(token);
2583            if (r == null) {
2584                return;
2585            }
2586            final long origId = Binder.clearCallingIdentity();
2587            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2588            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2589                    mConfiguration,
2590                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2591            if (config != null) {
2592                r.frozenBeforeDestroy = true;
2593                if (!updateConfigurationLocked(config, r, false, false)) {
2594                    mMainStack.resumeTopActivityLocked(null);
2595                }
2596            }
2597            Binder.restoreCallingIdentity(origId);
2598        }
2599    }
2600
2601    public int getRequestedOrientation(IBinder token) {
2602        synchronized (this) {
2603            ActivityRecord r = mMainStack.isInStackLocked(token);
2604            if (r == null) {
2605                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2606            }
2607            return mWindowManager.getAppOrientation(r.appToken);
2608        }
2609    }
2610
2611    /**
2612     * This is the internal entry point for handling Activity.finish().
2613     *
2614     * @param token The Binder token referencing the Activity we want to finish.
2615     * @param resultCode Result code, if any, from this Activity.
2616     * @param resultData Result data (Intent), if any, from this Activity.
2617     *
2618     * @return Returns true if the activity successfully finished, or false if it is still running.
2619     */
2620    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2621        // Refuse possible leaked file descriptors
2622        if (resultData != null && resultData.hasFileDescriptors() == true) {
2623            throw new IllegalArgumentException("File descriptors passed in Intent");
2624        }
2625
2626        synchronized(this) {
2627            if (mController != null) {
2628                // Find the first activity that is not finishing.
2629                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2630                if (next != null) {
2631                    // ask watcher if this is allowed
2632                    boolean resumeOK = true;
2633                    try {
2634                        resumeOK = mController.activityResuming(next.packageName);
2635                    } catch (RemoteException e) {
2636                        mController = null;
2637                    }
2638
2639                    if (!resumeOK) {
2640                        return false;
2641                    }
2642                }
2643            }
2644            final long origId = Binder.clearCallingIdentity();
2645            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2646                    resultData, "app-request");
2647            Binder.restoreCallingIdentity(origId);
2648            return res;
2649        }
2650    }
2651
2652    public final void finishHeavyWeightApp() {
2653        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2654                != PackageManager.PERMISSION_GRANTED) {
2655            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2656                    + Binder.getCallingPid()
2657                    + ", uid=" + Binder.getCallingUid()
2658                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2659            Slog.w(TAG, msg);
2660            throw new SecurityException(msg);
2661        }
2662
2663        synchronized(this) {
2664            if (mHeavyWeightProcess == null) {
2665                return;
2666            }
2667
2668            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2669                    mHeavyWeightProcess.activities);
2670            for (int i=0; i<activities.size(); i++) {
2671                ActivityRecord r = activities.get(i);
2672                if (!r.finishing) {
2673                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2674                    if (index >= 0) {
2675                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2676                                null, "finish-heavy");
2677                    }
2678                }
2679            }
2680
2681            mHeavyWeightProcess = null;
2682            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2683        }
2684    }
2685
2686    public void crashApplication(int uid, int initialPid, String packageName,
2687            String message) {
2688        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2689                != PackageManager.PERMISSION_GRANTED) {
2690            String msg = "Permission Denial: crashApplication() from pid="
2691                    + Binder.getCallingPid()
2692                    + ", uid=" + Binder.getCallingUid()
2693                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2694            Slog.w(TAG, msg);
2695            throw new SecurityException(msg);
2696        }
2697
2698        synchronized(this) {
2699            ProcessRecord proc = null;
2700
2701            // Figure out which process to kill.  We don't trust that initialPid
2702            // still has any relation to current pids, so must scan through the
2703            // list.
2704            synchronized (mPidsSelfLocked) {
2705                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2706                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2707                    if (p.uid != uid) {
2708                        continue;
2709                    }
2710                    if (p.pid == initialPid) {
2711                        proc = p;
2712                        break;
2713                    }
2714                    for (String str : p.pkgList) {
2715                        if (str.equals(packageName)) {
2716                            proc = p;
2717                        }
2718                    }
2719                }
2720            }
2721
2722            if (proc == null) {
2723                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2724                        + " initialPid=" + initialPid
2725                        + " packageName=" + packageName);
2726                return;
2727            }
2728
2729            if (proc.thread != null) {
2730                if (proc.pid == Process.myPid()) {
2731                    Log.w(TAG, "crashApplication: trying to crash self!");
2732                    return;
2733                }
2734                long ident = Binder.clearCallingIdentity();
2735                try {
2736                    proc.thread.scheduleCrash(message);
2737                } catch (RemoteException e) {
2738                }
2739                Binder.restoreCallingIdentity(ident);
2740            }
2741        }
2742    }
2743
2744    public final void finishSubActivity(IBinder token, String resultWho,
2745            int requestCode) {
2746        synchronized(this) {
2747            final long origId = Binder.clearCallingIdentity();
2748            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2749            Binder.restoreCallingIdentity(origId);
2750        }
2751    }
2752
2753    public boolean finishActivityAffinity(IBinder token) {
2754        synchronized(this) {
2755            final long origId = Binder.clearCallingIdentity();
2756            boolean res = mMainStack.finishActivityAffinityLocked(token);
2757            Binder.restoreCallingIdentity(origId);
2758            return res;
2759        }
2760    }
2761
2762    public boolean willActivityBeVisible(IBinder token) {
2763        synchronized(this) {
2764            int i;
2765            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2766                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2767                if (r.appToken == token) {
2768                    return true;
2769                }
2770                if (r.fullscreen && !r.finishing) {
2771                    return false;
2772                }
2773            }
2774            return true;
2775        }
2776    }
2777
2778    public void overridePendingTransition(IBinder token, String packageName,
2779            int enterAnim, int exitAnim) {
2780        synchronized(this) {
2781            ActivityRecord self = mMainStack.isInStackLocked(token);
2782            if (self == null) {
2783                return;
2784            }
2785
2786            final long origId = Binder.clearCallingIdentity();
2787
2788            if (self.state == ActivityState.RESUMED
2789                    || self.state == ActivityState.PAUSING) {
2790                mWindowManager.overridePendingAppTransition(packageName,
2791                        enterAnim, exitAnim, null);
2792            }
2793
2794            Binder.restoreCallingIdentity(origId);
2795        }
2796    }
2797
2798    /**
2799     * Main function for removing an existing process from the activity manager
2800     * as a result of that process going away.  Clears out all connections
2801     * to the process.
2802     */
2803    private final void handleAppDiedLocked(ProcessRecord app,
2804            boolean restarting, boolean allowRestart) {
2805        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2806        if (!restarting) {
2807            mLruProcesses.remove(app);
2808        }
2809
2810        if (mProfileProc == app) {
2811            clearProfilerLocked();
2812        }
2813
2814        // Just in case...
2815        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2816            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2817            mMainStack.mPausingActivity = null;
2818        }
2819        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2820            mMainStack.mLastPausedActivity = null;
2821        }
2822
2823        // Remove this application's activities from active lists.
2824        mMainStack.removeHistoryRecordsForAppLocked(app);
2825
2826        boolean atTop = true;
2827        boolean hasVisibleActivities = false;
2828
2829        // Clean out the history list.
2830        int i = mMainStack.mHistory.size();
2831        if (localLOGV) Slog.v(
2832            TAG, "Removing app " + app + " from history with " + i + " entries");
2833        while (i > 0) {
2834            i--;
2835            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2836            if (localLOGV) Slog.v(
2837                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2838            if (r.app == app) {
2839                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2840                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2841                        RuntimeException here = new RuntimeException("here");
2842                        here.fillInStackTrace();
2843                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2844                                + ": haveState=" + r.haveState
2845                                + " stateNotNeeded=" + r.stateNotNeeded
2846                                + " finishing=" + r.finishing
2847                                + " state=" + r.state, here);
2848                    }
2849                    if (!r.finishing) {
2850                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2851                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2852                                System.identityHashCode(r),
2853                                r.task.taskId, r.shortComponentName,
2854                                "proc died without state saved");
2855                    }
2856                    mMainStack.removeActivityFromHistoryLocked(r);
2857
2858                } else {
2859                    // We have the current state for this activity, so
2860                    // it can be restarted later when needed.
2861                    if (localLOGV) Slog.v(
2862                        TAG, "Keeping entry, setting app to null");
2863                    if (r.visible) {
2864                        hasVisibleActivities = true;
2865                    }
2866                    r.app = null;
2867                    r.nowVisible = false;
2868                    if (!r.haveState) {
2869                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2870                                "App died, clearing saved state of " + r);
2871                        r.icicle = null;
2872                    }
2873                }
2874
2875                r.stack.cleanUpActivityLocked(r, true, true);
2876            }
2877            atTop = false;
2878        }
2879
2880        app.activities.clear();
2881
2882        if (app.instrumentationClass != null) {
2883            Slog.w(TAG, "Crash of app " + app.processName
2884                  + " running instrumentation " + app.instrumentationClass);
2885            Bundle info = new Bundle();
2886            info.putString("shortMsg", "Process crashed.");
2887            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2888        }
2889
2890        if (!restarting) {
2891            if (!mMainStack.resumeTopActivityLocked(null)) {
2892                // If there was nothing to resume, and we are not already
2893                // restarting this process, but there is a visible activity that
2894                // is hosted by the process...  then make sure all visible
2895                // activities are running, taking care of restarting this
2896                // process.
2897                if (hasVisibleActivities) {
2898                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2899                }
2900            }
2901        }
2902    }
2903
2904    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2905        IBinder threadBinder = thread.asBinder();
2906        // Find the application record.
2907        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2908            ProcessRecord rec = mLruProcesses.get(i);
2909            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2910                return i;
2911            }
2912        }
2913        return -1;
2914    }
2915
2916    final ProcessRecord getRecordForAppLocked(
2917            IApplicationThread thread) {
2918        if (thread == null) {
2919            return null;
2920        }
2921
2922        int appIndex = getLRURecordIndexForAppLocked(thread);
2923        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2924    }
2925
2926    final void appDiedLocked(ProcessRecord app, int pid,
2927            IApplicationThread thread) {
2928
2929        mProcDeaths[0]++;
2930
2931        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2932        synchronized (stats) {
2933            stats.noteProcessDiedLocked(app.info.uid, pid);
2934        }
2935
2936        // Clean up already done if the process has been re-started.
2937        if (app.pid == pid && app.thread != null &&
2938                app.thread.asBinder() == thread.asBinder()) {
2939            if (!app.killedBackground) {
2940                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2941                        + ") has died.");
2942            }
2943            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2944            if (localLOGV) Slog.v(
2945                TAG, "Dying app: " + app + ", pid: " + pid
2946                + ", thread: " + thread.asBinder());
2947            boolean doLowMem = app.instrumentationClass == null;
2948            handleAppDiedLocked(app, false, true);
2949
2950            if (doLowMem) {
2951                // If there are no longer any background processes running,
2952                // and the app that died was not running instrumentation,
2953                // then tell everyone we are now low on memory.
2954                boolean haveBg = false;
2955                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2956                    ProcessRecord rec = mLruProcesses.get(i);
2957                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2958                        haveBg = true;
2959                        break;
2960                    }
2961                }
2962
2963                if (!haveBg) {
2964                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2965                    long now = SystemClock.uptimeMillis();
2966                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2967                        ProcessRecord rec = mLruProcesses.get(i);
2968                        if (rec != app && rec.thread != null &&
2969                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2970                            // The low memory report is overriding any current
2971                            // state for a GC request.  Make sure to do
2972                            // heavy/important/visible/foreground processes first.
2973                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
2974                                rec.lastRequestedGc = 0;
2975                            } else {
2976                                rec.lastRequestedGc = rec.lastLowMemory;
2977                            }
2978                            rec.reportLowMemory = true;
2979                            rec.lastLowMemory = now;
2980                            mProcessesToGc.remove(rec);
2981                            addProcessToGcListLocked(rec);
2982                        }
2983                    }
2984                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
2985                    scheduleAppGcsLocked();
2986                }
2987            }
2988        } else if (app.pid != pid) {
2989            // A new process has already been started.
2990            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2991                    + ") has died and restarted (pid " + app.pid + ").");
2992            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2993        } else if (DEBUG_PROCESSES) {
2994            Slog.d(TAG, "Received spurious death notification for thread "
2995                    + thread.asBinder());
2996        }
2997    }
2998
2999    /**
3000     * If a stack trace dump file is configured, dump process stack traces.
3001     * @param clearTraces causes the dump file to be erased prior to the new
3002     *    traces being written, if true; when false, the new traces will be
3003     *    appended to any existing file content.
3004     * @param firstPids of dalvik VM processes to dump stack traces for first
3005     * @param lastPids of dalvik VM processes to dump stack traces for last
3006     * @param nativeProcs optional list of native process names to dump stack crawls
3007     * @return file containing stack traces, or null if no dump file is configured
3008     */
3009    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3010            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3011        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3012        if (tracesPath == null || tracesPath.length() == 0) {
3013            return null;
3014        }
3015
3016        File tracesFile = new File(tracesPath);
3017        try {
3018            File tracesDir = tracesFile.getParentFile();
3019            if (!tracesDir.exists()) tracesFile.mkdirs();
3020            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3021
3022            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3023            tracesFile.createNewFile();
3024            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3025        } catch (IOException e) {
3026            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3027            return null;
3028        }
3029
3030        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3031        return tracesFile;
3032    }
3033
3034    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3035            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3036        // Use a FileObserver to detect when traces finish writing.
3037        // The order of traces is considered important to maintain for legibility.
3038        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3039            public synchronized void onEvent(int event, String path) { notify(); }
3040        };
3041
3042        try {
3043            observer.startWatching();
3044
3045            // First collect all of the stacks of the most important pids.
3046            if (firstPids != null) {
3047                try {
3048                    int num = firstPids.size();
3049                    for (int i = 0; i < num; i++) {
3050                        synchronized (observer) {
3051                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3052                            observer.wait(200);  // Wait for write-close, give up after 200msec
3053                        }
3054                    }
3055                } catch (InterruptedException e) {
3056                    Log.wtf(TAG, e);
3057                }
3058            }
3059
3060            // Next measure CPU usage.
3061            if (processStats != null) {
3062                processStats.init();
3063                System.gc();
3064                processStats.update();
3065                try {
3066                    synchronized (processStats) {
3067                        processStats.wait(500); // measure over 1/2 second.
3068                    }
3069                } catch (InterruptedException e) {
3070                }
3071                processStats.update();
3072
3073                // We'll take the stack crawls of just the top apps using CPU.
3074                final int N = processStats.countWorkingStats();
3075                int numProcs = 0;
3076                for (int i=0; i<N && numProcs<5; i++) {
3077                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3078                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3079                        numProcs++;
3080                        try {
3081                            synchronized (observer) {
3082                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3083                                observer.wait(200);  // Wait for write-close, give up after 200msec
3084                            }
3085                        } catch (InterruptedException e) {
3086                            Log.wtf(TAG, e);
3087                        }
3088
3089                    }
3090                }
3091            }
3092
3093        } finally {
3094            observer.stopWatching();
3095        }
3096
3097        if (nativeProcs != null) {
3098            int[] pids = Process.getPidsForCommands(nativeProcs);
3099            if (pids != null) {
3100                for (int pid : pids) {
3101                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3102                }
3103            }
3104        }
3105    }
3106
3107    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3108        if (true || IS_USER_BUILD) {
3109            return;
3110        }
3111        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3112        if (tracesPath == null || tracesPath.length() == 0) {
3113            return;
3114        }
3115
3116        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3117        StrictMode.allowThreadDiskWrites();
3118        try {
3119            final File tracesFile = new File(tracesPath);
3120            final File tracesDir = tracesFile.getParentFile();
3121            final File tracesTmp = new File(tracesDir, "__tmp__");
3122            try {
3123                if (!tracesDir.exists()) tracesFile.mkdirs();
3124                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3125
3126                if (tracesFile.exists()) {
3127                    tracesTmp.delete();
3128                    tracesFile.renameTo(tracesTmp);
3129                }
3130                StringBuilder sb = new StringBuilder();
3131                Time tobj = new Time();
3132                tobj.set(System.currentTimeMillis());
3133                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3134                sb.append(": ");
3135                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3136                sb.append(" since ");
3137                sb.append(msg);
3138                FileOutputStream fos = new FileOutputStream(tracesFile);
3139                fos.write(sb.toString().getBytes());
3140                if (app == null) {
3141                    fos.write("\n*** No application process!".getBytes());
3142                }
3143                fos.close();
3144                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3145            } catch (IOException e) {
3146                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3147                return;
3148            }
3149
3150            if (app != null) {
3151                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3152                firstPids.add(app.pid);
3153                dumpStackTraces(tracesPath, firstPids, null, null, null);
3154            }
3155
3156            File lastTracesFile = null;
3157            File curTracesFile = null;
3158            for (int i=9; i>=0; i--) {
3159                String name = String.format("slow%02d.txt", i);
3160                curTracesFile = new File(tracesDir, name);
3161                if (curTracesFile.exists()) {
3162                    if (lastTracesFile != null) {
3163                        curTracesFile.renameTo(lastTracesFile);
3164                    } else {
3165                        curTracesFile.delete();
3166                    }
3167                }
3168                lastTracesFile = curTracesFile;
3169            }
3170            tracesFile.renameTo(curTracesFile);
3171            if (tracesTmp.exists()) {
3172                tracesTmp.renameTo(tracesFile);
3173            }
3174        } finally {
3175            StrictMode.setThreadPolicy(oldPolicy);
3176        }
3177    }
3178
3179    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3180            ActivityRecord parent, final String annotation) {
3181        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3182        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3183
3184        if (mController != null) {
3185            try {
3186                // 0 == continue, -1 = kill process immediately
3187                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3188                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3189            } catch (RemoteException e) {
3190                mController = null;
3191            }
3192        }
3193
3194        long anrTime = SystemClock.uptimeMillis();
3195        if (MONITOR_CPU_USAGE) {
3196            updateCpuStatsNow();
3197        }
3198
3199        synchronized (this) {
3200            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3201            if (mShuttingDown) {
3202                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3203                return;
3204            } else if (app.notResponding) {
3205                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3206                return;
3207            } else if (app.crashing) {
3208                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3209                return;
3210            }
3211
3212            // In case we come through here for the same app before completing
3213            // this one, mark as anring now so we will bail out.
3214            app.notResponding = true;
3215
3216            // Log the ANR to the event log.
3217            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3218                    annotation);
3219
3220            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3221            firstPids.add(app.pid);
3222
3223            int parentPid = app.pid;
3224            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3225            if (parentPid != app.pid) firstPids.add(parentPid);
3226
3227            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3228
3229            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3230                ProcessRecord r = mLruProcesses.get(i);
3231                if (r != null && r.thread != null) {
3232                    int pid = r.pid;
3233                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3234                        if (r.persistent) {
3235                            firstPids.add(pid);
3236                        } else {
3237                            lastPids.put(pid, Boolean.TRUE);
3238                        }
3239                    }
3240                }
3241            }
3242        }
3243
3244        // Log the ANR to the main log.
3245        StringBuilder info = new StringBuilder();
3246        info.setLength(0);
3247        info.append("ANR in ").append(app.processName);
3248        if (activity != null && activity.shortComponentName != null) {
3249            info.append(" (").append(activity.shortComponentName).append(")");
3250        }
3251        info.append("\n");
3252        if (annotation != null) {
3253            info.append("Reason: ").append(annotation).append("\n");
3254        }
3255        if (parent != null && parent != activity) {
3256            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3257        }
3258
3259        final ProcessStats processStats = new ProcessStats(true);
3260
3261        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3262
3263        String cpuInfo = null;
3264        if (MONITOR_CPU_USAGE) {
3265            updateCpuStatsNow();
3266            synchronized (mProcessStatsThread) {
3267                cpuInfo = mProcessStats.printCurrentState(anrTime);
3268            }
3269            info.append(processStats.printCurrentLoad());
3270            info.append(cpuInfo);
3271        }
3272
3273        info.append(processStats.printCurrentState(anrTime));
3274
3275        Slog.e(TAG, info.toString());
3276        if (tracesFile == null) {
3277            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3278            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3279        }
3280
3281        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3282                cpuInfo, tracesFile, null);
3283
3284        if (mController != null) {
3285            try {
3286                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3287                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3288                if (res != 0) {
3289                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3290                    return;
3291                }
3292            } catch (RemoteException e) {
3293                mController = null;
3294            }
3295        }
3296
3297        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3298        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3299                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3300
3301        synchronized (this) {
3302            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3303                Slog.w(TAG, "Killing " + app + ": background ANR");
3304                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3305                        app.processName, app.setAdj, "background ANR");
3306                Process.killProcessQuiet(app.pid);
3307                return;
3308            }
3309
3310            // Set the app's notResponding state, and look up the errorReportReceiver
3311            makeAppNotRespondingLocked(app,
3312                    activity != null ? activity.shortComponentName : null,
3313                    annotation != null ? "ANR " + annotation : "ANR",
3314                    info.toString());
3315
3316            // Bring up the infamous App Not Responding dialog
3317            Message msg = Message.obtain();
3318            HashMap map = new HashMap();
3319            msg.what = SHOW_NOT_RESPONDING_MSG;
3320            msg.obj = map;
3321            map.put("app", app);
3322            if (activity != null) {
3323                map.put("activity", activity);
3324            }
3325
3326            mHandler.sendMessage(msg);
3327        }
3328    }
3329
3330    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3331        if (!mLaunchWarningShown) {
3332            mLaunchWarningShown = true;
3333            mHandler.post(new Runnable() {
3334                @Override
3335                public void run() {
3336                    synchronized (ActivityManagerService.this) {
3337                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3338                        d.show();
3339                        mHandler.postDelayed(new Runnable() {
3340                            @Override
3341                            public void run() {
3342                                synchronized (ActivityManagerService.this) {
3343                                    d.dismiss();
3344                                    mLaunchWarningShown = false;
3345                                }
3346                            }
3347                        }, 4000);
3348                    }
3349                }
3350            });
3351        }
3352    }
3353
3354    public boolean clearApplicationUserData(final String packageName,
3355            final IPackageDataObserver observer, final int userId) {
3356        enforceNotIsolatedCaller("clearApplicationUserData");
3357        int uid = Binder.getCallingUid();
3358        int pid = Binder.getCallingPid();
3359        long callingId = Binder.clearCallingIdentity();
3360        try {
3361            IPackageManager pm = AppGlobals.getPackageManager();
3362            int pkgUid = -1;
3363            synchronized(this) {
3364                try {
3365                    pkgUid = pm.getPackageUid(packageName, userId);
3366                } catch (RemoteException e) {
3367                }
3368                if (pkgUid == -1) {
3369                    Slog.w(TAG, "Invalid packageName:" + packageName);
3370                    return false;
3371                }
3372                if (uid == pkgUid || checkComponentPermission(
3373                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3374                        pid, uid, -1, true)
3375                        == PackageManager.PERMISSION_GRANTED) {
3376                    forceStopPackageLocked(packageName, pkgUid);
3377                } else {
3378                    throw new SecurityException(pid+" does not have permission:"+
3379                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3380                                    "for process:"+packageName);
3381                }
3382            }
3383
3384            try {
3385                //clear application user data
3386                pm.clearApplicationUserData(packageName, observer, userId);
3387                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3388                        Uri.fromParts("package", packageName, null));
3389                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3390                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3391                        null, null, 0, null, null, null, false, false, userId);
3392            } catch (RemoteException e) {
3393            }
3394        } finally {
3395            Binder.restoreCallingIdentity(callingId);
3396        }
3397        return true;
3398    }
3399
3400    public void killBackgroundProcesses(final String packageName) {
3401        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3402                != PackageManager.PERMISSION_GRANTED &&
3403                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3404                        != PackageManager.PERMISSION_GRANTED) {
3405            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3406                    + Binder.getCallingPid()
3407                    + ", uid=" + Binder.getCallingUid()
3408                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3409            Slog.w(TAG, msg);
3410            throw new SecurityException(msg);
3411        }
3412
3413        int userId = UserId.getCallingUserId();
3414        long callingId = Binder.clearCallingIdentity();
3415        try {
3416            IPackageManager pm = AppGlobals.getPackageManager();
3417            int pkgUid = -1;
3418            synchronized(this) {
3419                try {
3420                    pkgUid = pm.getPackageUid(packageName, userId);
3421                } catch (RemoteException e) {
3422                }
3423                if (pkgUid == -1) {
3424                    Slog.w(TAG, "Invalid packageName: " + packageName);
3425                    return;
3426                }
3427                killPackageProcessesLocked(packageName, pkgUid,
3428                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3429            }
3430        } finally {
3431            Binder.restoreCallingIdentity(callingId);
3432        }
3433    }
3434
3435    public void killAllBackgroundProcesses() {
3436        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3437                != PackageManager.PERMISSION_GRANTED) {
3438            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3439                    + Binder.getCallingPid()
3440                    + ", uid=" + Binder.getCallingUid()
3441                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3442            Slog.w(TAG, msg);
3443            throw new SecurityException(msg);
3444        }
3445
3446        long callingId = Binder.clearCallingIdentity();
3447        try {
3448            synchronized(this) {
3449                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3450                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3451                    final int NA = apps.size();
3452                    for (int ia=0; ia<NA; ia++) {
3453                        ProcessRecord app = apps.valueAt(ia);
3454                        if (app.persistent) {
3455                            // we don't kill persistent processes
3456                            continue;
3457                        }
3458                        if (app.removed) {
3459                            procs.add(app);
3460                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3461                            app.removed = true;
3462                            procs.add(app);
3463                        }
3464                    }
3465                }
3466
3467                int N = procs.size();
3468                for (int i=0; i<N; i++) {
3469                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3470                }
3471            }
3472        } finally {
3473            Binder.restoreCallingIdentity(callingId);
3474        }
3475    }
3476
3477    public void forceStopPackage(final String packageName) {
3478        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3479                != PackageManager.PERMISSION_GRANTED) {
3480            String msg = "Permission Denial: forceStopPackage() from pid="
3481                    + Binder.getCallingPid()
3482                    + ", uid=" + Binder.getCallingUid()
3483                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3484            Slog.w(TAG, msg);
3485            throw new SecurityException(msg);
3486        }
3487        final int userId = UserId.getCallingUserId();
3488        long callingId = Binder.clearCallingIdentity();
3489        try {
3490            IPackageManager pm = AppGlobals.getPackageManager();
3491            int pkgUid = -1;
3492            synchronized(this) {
3493                try {
3494                    pkgUid = pm.getPackageUid(packageName, userId);
3495                } catch (RemoteException e) {
3496                }
3497                if (pkgUid == -1) {
3498                    Slog.w(TAG, "Invalid packageName: " + packageName);
3499                    return;
3500                }
3501                forceStopPackageLocked(packageName, pkgUid);
3502                try {
3503                    pm.setPackageStoppedState(packageName, true, userId);
3504                } catch (RemoteException e) {
3505                } catch (IllegalArgumentException e) {
3506                    Slog.w(TAG, "Failed trying to unstop package "
3507                            + packageName + ": " + e);
3508                }
3509            }
3510        } finally {
3511            Binder.restoreCallingIdentity(callingId);
3512        }
3513    }
3514
3515    /*
3516     * The pkg name and uid have to be specified.
3517     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3518     */
3519    public void killApplicationWithUid(String pkg, int uid) {
3520        if (pkg == null) {
3521            return;
3522        }
3523        // Make sure the uid is valid.
3524        if (uid < 0) {
3525            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3526            return;
3527        }
3528        int callerUid = Binder.getCallingUid();
3529        // Only the system server can kill an application
3530        if (callerUid == Process.SYSTEM_UID) {
3531            // Post an aysnc message to kill the application
3532            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3533            msg.arg1 = uid;
3534            msg.arg2 = 0;
3535            msg.obj = pkg;
3536            mHandler.sendMessage(msg);
3537        } else {
3538            throw new SecurityException(callerUid + " cannot kill pkg: " +
3539                    pkg);
3540        }
3541    }
3542
3543    public void closeSystemDialogs(String reason) {
3544        enforceNotIsolatedCaller("closeSystemDialogs");
3545
3546        final int uid = Binder.getCallingUid();
3547        final long origId = Binder.clearCallingIdentity();
3548        synchronized (this) {
3549            closeSystemDialogsLocked(uid, reason);
3550        }
3551        Binder.restoreCallingIdentity(origId);
3552    }
3553
3554    void closeSystemDialogsLocked(int callingUid, String reason) {
3555        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3556        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3557        if (reason != null) {
3558            intent.putExtra("reason", reason);
3559        }
3560        mWindowManager.closeSystemDialogs(reason);
3561
3562        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3563            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3564            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3565                r.stack.finishActivityLocked(r, i,
3566                        Activity.RESULT_CANCELED, null, "close-sys");
3567            }
3568        }
3569
3570        broadcastIntentLocked(null, null, intent, null,
3571                null, 0, null, null, null, false, false, -1,
3572                callingUid, 0 /* TODO: Verify */);
3573    }
3574
3575    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3576            throws RemoteException {
3577        enforceNotIsolatedCaller("getProcessMemoryInfo");
3578        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3579        for (int i=pids.length-1; i>=0; i--) {
3580            infos[i] = new Debug.MemoryInfo();
3581            Debug.getMemoryInfo(pids[i], infos[i]);
3582        }
3583        return infos;
3584    }
3585
3586    public long[] getProcessPss(int[] pids) throws RemoteException {
3587        enforceNotIsolatedCaller("getProcessPss");
3588        long[] pss = new long[pids.length];
3589        for (int i=pids.length-1; i>=0; i--) {
3590            pss[i] = Debug.getPss(pids[i]);
3591        }
3592        return pss;
3593    }
3594
3595    public void killApplicationProcess(String processName, int uid) {
3596        if (processName == null) {
3597            return;
3598        }
3599
3600        int callerUid = Binder.getCallingUid();
3601        // Only the system server can kill an application
3602        if (callerUid == Process.SYSTEM_UID) {
3603            synchronized (this) {
3604                ProcessRecord app = getProcessRecordLocked(processName, uid);
3605                if (app != null && app.thread != null) {
3606                    try {
3607                        app.thread.scheduleSuicide();
3608                    } catch (RemoteException e) {
3609                        // If the other end already died, then our work here is done.
3610                    }
3611                } else {
3612                    Slog.w(TAG, "Process/uid not found attempting kill of "
3613                            + processName + " / " + uid);
3614                }
3615            }
3616        } else {
3617            throw new SecurityException(callerUid + " cannot kill app process: " +
3618                    processName);
3619        }
3620    }
3621
3622    private void forceStopPackageLocked(final String packageName, int uid) {
3623        forceStopPackageLocked(packageName, uid, false, false, true, false, UserId.getUserId(uid));
3624        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3625                Uri.fromParts("package", packageName, null));
3626        if (!mProcessesReady) {
3627            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3628        }
3629        intent.putExtra(Intent.EXTRA_UID, uid);
3630        broadcastIntentLocked(null, null, intent,
3631                null, null, 0, null, null, null,
3632                false, false,
3633                MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid));
3634    }
3635
3636    private final boolean killPackageProcessesLocked(String packageName, int uid,
3637            int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3638            boolean evenPersistent, String reason) {
3639        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3640
3641        // Remove all processes this package may have touched: all with the
3642        // same UID (except for the system or root user), and all whose name
3643        // matches the package name.
3644        final String procNamePrefix = packageName + ":";
3645        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3646            final int NA = apps.size();
3647            for (int ia=0; ia<NA; ia++) {
3648                ProcessRecord app = apps.valueAt(ia);
3649                if (app.persistent && !evenPersistent) {
3650                    // we don't kill persistent processes
3651                    continue;
3652                }
3653                if (app.removed) {
3654                    if (doit) {
3655                        procs.add(app);
3656                    }
3657                // If uid is specified and the uid and process name match
3658                // Or, the uid is not specified and the process name matches
3659                } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3660                            || ((app.processName.equals(packageName)
3661                                 || app.processName.startsWith(procNamePrefix))
3662                                && uid < 0))) {
3663                    if (app.setAdj >= minOomAdj) {
3664                        if (!doit) {
3665                            return true;
3666                        }
3667                        app.removed = true;
3668                        procs.add(app);
3669                    }
3670                }
3671            }
3672        }
3673
3674        int N = procs.size();
3675        for (int i=0; i<N; i++) {
3676            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3677        }
3678        return N > 0;
3679    }
3680
3681    private final boolean forceStopPackageLocked(String name, int uid,
3682            boolean callerWillRestart, boolean purgeCache, boolean doit,
3683            boolean evenPersistent, int userId) {
3684        int i;
3685        int N;
3686
3687        if (uid < 0) {
3688            try {
3689                uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
3690            } catch (RemoteException e) {
3691            }
3692        }
3693
3694        if (doit) {
3695            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3696
3697            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3698            while (badApps.hasNext()) {
3699                SparseArray<Long> ba = badApps.next();
3700                if (ba.get(uid) != null) {
3701                    badApps.remove();
3702                }
3703            }
3704        }
3705
3706        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3707                callerWillRestart, false, doit, evenPersistent, "force stop");
3708
3709        TaskRecord lastTask = null;
3710        for (i=0; i<mMainStack.mHistory.size(); i++) {
3711            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3712            final boolean samePackage = r.packageName.equals(name);
3713            if (r.userId == userId
3714                    && (samePackage || r.task == lastTask)
3715                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3716                if (!doit) {
3717                    if (r.finishing) {
3718                        // If this activity is just finishing, then it is not
3719                        // interesting as far as something to stop.
3720                        continue;
3721                    }
3722                    return true;
3723                }
3724                didSomething = true;
3725                Slog.i(TAG, "  Force finishing activity " + r);
3726                if (samePackage) {
3727                    if (r.app != null) {
3728                        r.app.removed = true;
3729                    }
3730                    r.app = null;
3731                }
3732                lastTask = r.task;
3733                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3734                        null, "force-stop", true)) {
3735                    i--;
3736                }
3737            }
3738        }
3739
3740        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3741            if (!doit) {
3742                return true;
3743            }
3744            didSomething = true;
3745        }
3746
3747        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3748        for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
3749            if (provider.info.packageName.equals(name)
3750                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3751                if (!doit) {
3752                    return true;
3753                }
3754                didSomething = true;
3755                providers.add(provider);
3756            }
3757        }
3758
3759        N = providers.size();
3760        for (i=0; i<N; i++) {
3761            removeDyingProviderLocked(null, providers.get(i), true);
3762        }
3763
3764        if (doit) {
3765            if (purgeCache) {
3766                AttributeCache ac = AttributeCache.instance();
3767                if (ac != null) {
3768                    ac.removePackage(name);
3769                }
3770            }
3771            if (mBooted) {
3772                mMainStack.resumeTopActivityLocked(null);
3773                mMainStack.scheduleIdleLocked();
3774            }
3775        }
3776
3777        return didSomething;
3778    }
3779
3780    private final boolean removeProcessLocked(ProcessRecord app,
3781            boolean callerWillRestart, boolean allowRestart, String reason) {
3782        final String name = app.processName;
3783        final int uid = app.uid;
3784        if (DEBUG_PROCESSES) Slog.d(
3785            TAG, "Force removing proc " + app.toShortString() + " (" + name
3786            + "/" + uid + ")");
3787
3788        mProcessNames.remove(name, uid);
3789        mIsolatedProcesses.remove(app.uid);
3790        if (mHeavyWeightProcess == app) {
3791            mHeavyWeightProcess = null;
3792            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3793        }
3794        boolean needRestart = false;
3795        if (app.pid > 0 && app.pid != MY_PID) {
3796            int pid = app.pid;
3797            synchronized (mPidsSelfLocked) {
3798                mPidsSelfLocked.remove(pid);
3799                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3800            }
3801            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3802            handleAppDiedLocked(app, true, allowRestart);
3803            mLruProcesses.remove(app);
3804            Process.killProcessQuiet(pid);
3805
3806            if (app.persistent && !app.isolated) {
3807                if (!callerWillRestart) {
3808                    addAppLocked(app.info, false);
3809                } else {
3810                    needRestart = true;
3811                }
3812            }
3813        } else {
3814            mRemovedProcesses.add(app);
3815        }
3816
3817        return needRestart;
3818    }
3819
3820    private final void processStartTimedOutLocked(ProcessRecord app) {
3821        final int pid = app.pid;
3822        boolean gone = false;
3823        synchronized (mPidsSelfLocked) {
3824            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3825            if (knownApp != null && knownApp.thread == null) {
3826                mPidsSelfLocked.remove(pid);
3827                gone = true;
3828            }
3829        }
3830
3831        if (gone) {
3832            Slog.w(TAG, "Process " + app + " failed to attach");
3833            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
3834                    app.processName);
3835            mProcessNames.remove(app.processName, app.uid);
3836            mIsolatedProcesses.remove(app.uid);
3837            if (mHeavyWeightProcess == app) {
3838                mHeavyWeightProcess = null;
3839                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3840            }
3841            // Take care of any launching providers waiting for this process.
3842            checkAppInLaunchingProvidersLocked(app, true);
3843            // Take care of any services that are waiting for the process.
3844            mServices.processStartTimedOutLocked(app);
3845            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3846                    app.processName, app.setAdj, "start timeout");
3847            Process.killProcessQuiet(pid);
3848            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3849                Slog.w(TAG, "Unattached app died before backup, skipping");
3850                try {
3851                    IBackupManager bm = IBackupManager.Stub.asInterface(
3852                            ServiceManager.getService(Context.BACKUP_SERVICE));
3853                    bm.agentDisconnected(app.info.packageName);
3854                } catch (RemoteException e) {
3855                    // Can't happen; the backup manager is local
3856                }
3857            }
3858            if (isPendingBroadcastProcessLocked(pid)) {
3859                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3860                skipPendingBroadcastLocked(pid);
3861            }
3862        } else {
3863            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3864        }
3865    }
3866
3867    private final boolean attachApplicationLocked(IApplicationThread thread,
3868            int pid) {
3869
3870        // Find the application record that is being attached...  either via
3871        // the pid if we are running in multiple processes, or just pull the
3872        // next app record if we are emulating process with anonymous threads.
3873        ProcessRecord app;
3874        if (pid != MY_PID && pid >= 0) {
3875            synchronized (mPidsSelfLocked) {
3876                app = mPidsSelfLocked.get(pid);
3877            }
3878        } else {
3879            app = null;
3880        }
3881
3882        if (app == null) {
3883            Slog.w(TAG, "No pending application record for pid " + pid
3884                    + " (IApplicationThread " + thread + "); dropping process");
3885            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3886            if (pid > 0 && pid != MY_PID) {
3887                Process.killProcessQuiet(pid);
3888            } else {
3889                try {
3890                    thread.scheduleExit();
3891                } catch (Exception e) {
3892                    // Ignore exceptions.
3893                }
3894            }
3895            return false;
3896        }
3897
3898        // If this application record is still attached to a previous
3899        // process, clean it up now.
3900        if (app.thread != null) {
3901            handleAppDiedLocked(app, true, true);
3902        }
3903
3904        // Tell the process all about itself.
3905
3906        if (localLOGV) Slog.v(
3907                TAG, "Binding process pid " + pid + " to record " + app);
3908
3909        String processName = app.processName;
3910        try {
3911            AppDeathRecipient adr = new AppDeathRecipient(
3912                    app, pid, thread);
3913            thread.asBinder().linkToDeath(adr, 0);
3914            app.deathRecipient = adr;
3915        } catch (RemoteException e) {
3916            app.resetPackageList();
3917            startProcessLocked(app, "link fail", processName);
3918            return false;
3919        }
3920
3921        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3922
3923        app.thread = thread;
3924        app.curAdj = app.setAdj = -100;
3925        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3926        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3927        app.forcingToForeground = null;
3928        app.foregroundServices = false;
3929        app.hasShownUi = false;
3930        app.debugging = false;
3931
3932        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3933
3934        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3935        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3936
3937        if (!normalMode) {
3938            Slog.i(TAG, "Launching preboot mode app: " + app);
3939        }
3940
3941        if (localLOGV) Slog.v(
3942            TAG, "New app record " + app
3943            + " thread=" + thread.asBinder() + " pid=" + pid);
3944        try {
3945            int testMode = IApplicationThread.DEBUG_OFF;
3946            if (mDebugApp != null && mDebugApp.equals(processName)) {
3947                testMode = mWaitForDebugger
3948                    ? IApplicationThread.DEBUG_WAIT
3949                    : IApplicationThread.DEBUG_ON;
3950                app.debugging = true;
3951                if (mDebugTransient) {
3952                    mDebugApp = mOrigDebugApp;
3953                    mWaitForDebugger = mOrigWaitForDebugger;
3954                }
3955            }
3956            String profileFile = app.instrumentationProfileFile;
3957            ParcelFileDescriptor profileFd = null;
3958            boolean profileAutoStop = false;
3959            if (mProfileApp != null && mProfileApp.equals(processName)) {
3960                mProfileProc = app;
3961                profileFile = mProfileFile;
3962                profileFd = mProfileFd;
3963                profileAutoStop = mAutoStopProfiler;
3964            }
3965            boolean enableOpenGlTrace = false;
3966            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
3967                enableOpenGlTrace = true;
3968                mOpenGlTraceApp = null;
3969            }
3970
3971            // If the app is being launched for restore or full backup, set it up specially
3972            boolean isRestrictedBackupMode = false;
3973            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3974                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3975                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
3976                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3977            }
3978
3979            ensurePackageDexOpt(app.instrumentationInfo != null
3980                    ? app.instrumentationInfo.packageName
3981                    : app.info.packageName);
3982            if (app.instrumentationClass != null) {
3983                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
3984            }
3985            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
3986                    + processName + " with config " + mConfiguration);
3987            ApplicationInfo appInfo = app.instrumentationInfo != null
3988                    ? app.instrumentationInfo : app.info;
3989            app.compat = compatibilityInfoForPackageLocked(appInfo);
3990            if (profileFd != null) {
3991                profileFd = profileFd.dup();
3992            }
3993            thread.bindApplication(processName, appInfo, providers,
3994                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
3995                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
3996                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
3997                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
3998                    mCoreSettingsObserver.getCoreSettingsLocked());
3999            updateLruProcessLocked(app, false, true);
4000            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4001        } catch (Exception e) {
4002            // todo: Yikes!  What should we do?  For now we will try to
4003            // start another process, but that could easily get us in
4004            // an infinite loop of restarting processes...
4005            Slog.w(TAG, "Exception thrown during bind!", e);
4006
4007            app.resetPackageList();
4008            app.unlinkDeathRecipient();
4009            startProcessLocked(app, "bind fail", processName);
4010            return false;
4011        }
4012
4013        // Remove this record from the list of starting applications.
4014        mPersistentStartingProcesses.remove(app);
4015        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4016                "Attach application locked removing on hold: " + app);
4017        mProcessesOnHold.remove(app);
4018
4019        boolean badApp = false;
4020        boolean didSomething = false;
4021
4022        // See if the top visible activity is waiting to run in this process...
4023        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4024        if (hr != null && normalMode) {
4025            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4026                    && processName.equals(hr.processName)) {
4027                try {
4028                    if (mHeadless) {
4029                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4030                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4031                        didSomething = true;
4032                    }
4033                } catch (Exception e) {
4034                    Slog.w(TAG, "Exception in new application when starting activity "
4035                          + hr.intent.getComponent().flattenToShortString(), e);
4036                    badApp = true;
4037                }
4038            } else {
4039                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4040            }
4041        }
4042
4043        // Find any services that should be running in this process...
4044        if (!badApp) {
4045            try {
4046                didSomething |= mServices.attachApplicationLocked(app, processName);
4047            } catch (Exception e) {
4048                badApp = true;
4049            }
4050        }
4051
4052        // Check if a next-broadcast receiver is in this process...
4053        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4054            try {
4055                didSomething = sendPendingBroadcastsLocked(app);
4056            } catch (Exception e) {
4057                // If the app died trying to launch the receiver we declare it 'bad'
4058                badApp = true;
4059            }
4060        }
4061
4062        // Check whether the next backup agent is in this process...
4063        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4064            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4065            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4066            try {
4067                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4068                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4069                        mBackupTarget.backupMode);
4070            } catch (Exception e) {
4071                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4072                e.printStackTrace();
4073            }
4074        }
4075
4076        if (badApp) {
4077            // todo: Also need to kill application to deal with all
4078            // kinds of exceptions.
4079            handleAppDiedLocked(app, false, true);
4080            return false;
4081        }
4082
4083        if (!didSomething) {
4084            updateOomAdjLocked();
4085        }
4086
4087        return true;
4088    }
4089
4090    public final void attachApplication(IApplicationThread thread) {
4091        synchronized (this) {
4092            int callingPid = Binder.getCallingPid();
4093            final long origId = Binder.clearCallingIdentity();
4094            attachApplicationLocked(thread, callingPid);
4095            Binder.restoreCallingIdentity(origId);
4096        }
4097    }
4098
4099    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4100        final long origId = Binder.clearCallingIdentity();
4101        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4102        if (stopProfiling) {
4103            synchronized (this) {
4104                if (mProfileProc == r.app) {
4105                    if (mProfileFd != null) {
4106                        try {
4107                            mProfileFd.close();
4108                        } catch (IOException e) {
4109                        }
4110                        clearProfilerLocked();
4111                    }
4112                }
4113            }
4114        }
4115        Binder.restoreCallingIdentity(origId);
4116    }
4117
4118    void enableScreenAfterBoot() {
4119        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4120                SystemClock.uptimeMillis());
4121        mWindowManager.enableScreenAfterBoot();
4122
4123        synchronized (this) {
4124            updateEventDispatchingLocked();
4125        }
4126    }
4127
4128    public void showBootMessage(final CharSequence msg, final boolean always) {
4129        enforceNotIsolatedCaller("showBootMessage");
4130        mWindowManager.showBootMessage(msg, always);
4131    }
4132
4133    public void dismissKeyguardOnNextActivity() {
4134        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4135        final long token = Binder.clearCallingIdentity();
4136        try {
4137            synchronized (this) {
4138                if (mLockScreenShown) {
4139                    mLockScreenShown = false;
4140                    comeOutOfSleepIfNeededLocked();
4141                }
4142                mMainStack.dismissKeyguardOnNextActivityLocked();
4143            }
4144        } finally {
4145            Binder.restoreCallingIdentity(token);
4146        }
4147    }
4148
4149    final void finishBooting() {
4150        IntentFilter pkgFilter = new IntentFilter();
4151        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4152        pkgFilter.addDataScheme("package");
4153        mContext.registerReceiver(new BroadcastReceiver() {
4154            @Override
4155            public void onReceive(Context context, Intent intent) {
4156                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4157                if (pkgs != null) {
4158                    for (String pkg : pkgs) {
4159                        synchronized (ActivityManagerService.this) {
4160                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4161                                setResultCode(Activity.RESULT_OK);
4162                                return;
4163                            }
4164                        }
4165                    }
4166                }
4167            }
4168        }, pkgFilter);
4169
4170        IntentFilter userFilter = new IntentFilter();
4171        userFilter.addAction(Intent.ACTION_USER_REMOVED);
4172        mContext.registerReceiver(new BroadcastReceiver() {
4173            @Override
4174            public void onReceive(Context context, Intent intent) {
4175                onUserRemoved(intent);
4176            }
4177        }, userFilter);
4178
4179        synchronized (this) {
4180            // Ensure that any processes we had put on hold are now started
4181            // up.
4182            final int NP = mProcessesOnHold.size();
4183            if (NP > 0) {
4184                ArrayList<ProcessRecord> procs =
4185                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4186                for (int ip=0; ip<NP; ip++) {
4187                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4188                            + procs.get(ip));
4189                    startProcessLocked(procs.get(ip), "on-hold", null);
4190                }
4191            }
4192
4193            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4194                // Start looking for apps that are abusing wake locks.
4195                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4196                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4197                // Tell anyone interested that we are done booting!
4198                SystemProperties.set("sys.boot_completed", "1");
4199                SystemProperties.set("dev.bootcomplete", "1");
4200                /* TODO: Send this to all users that are to be logged in on startup */
4201                broadcastIntentLocked(null, null,
4202                        new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4203                        null, null, 0, null, null,
4204                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4205                        false, false, MY_PID, Process.SYSTEM_UID, Binder.getOrigCallingUser());
4206            }
4207        }
4208    }
4209
4210    final void ensureBootCompleted() {
4211        boolean booting;
4212        boolean enableScreen;
4213        synchronized (this) {
4214            booting = mBooting;
4215            mBooting = false;
4216            enableScreen = !mBooted;
4217            mBooted = true;
4218        }
4219
4220        if (booting) {
4221            finishBooting();
4222        }
4223
4224        if (enableScreen) {
4225            enableScreenAfterBoot();
4226        }
4227    }
4228
4229    public final void activityPaused(IBinder token) {
4230        final long origId = Binder.clearCallingIdentity();
4231        mMainStack.activityPaused(token, false);
4232        Binder.restoreCallingIdentity(origId);
4233    }
4234
4235    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4236            CharSequence description) {
4237        if (localLOGV) Slog.v(
4238            TAG, "Activity stopped: token=" + token);
4239
4240        // Refuse possible leaked file descriptors
4241        if (icicle != null && icicle.hasFileDescriptors()) {
4242            throw new IllegalArgumentException("File descriptors passed in Bundle");
4243        }
4244
4245        ActivityRecord r = null;
4246
4247        final long origId = Binder.clearCallingIdentity();
4248
4249        synchronized (this) {
4250            r = mMainStack.isInStackLocked(token);
4251            if (r != null) {
4252                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4253            }
4254        }
4255
4256        if (r != null) {
4257            sendPendingThumbnail(r, null, null, null, false);
4258        }
4259
4260        trimApplications();
4261
4262        Binder.restoreCallingIdentity(origId);
4263    }
4264
4265    public final void activityDestroyed(IBinder token) {
4266        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4267        mMainStack.activityDestroyed(token);
4268    }
4269
4270    public String getCallingPackage(IBinder token) {
4271        synchronized (this) {
4272            ActivityRecord r = getCallingRecordLocked(token);
4273            return r != null && r.app != null ? r.info.packageName : null;
4274        }
4275    }
4276
4277    public ComponentName getCallingActivity(IBinder token) {
4278        synchronized (this) {
4279            ActivityRecord r = getCallingRecordLocked(token);
4280            return r != null ? r.intent.getComponent() : null;
4281        }
4282    }
4283
4284    private ActivityRecord getCallingRecordLocked(IBinder token) {
4285        ActivityRecord r = mMainStack.isInStackLocked(token);
4286        if (r == null) {
4287            return null;
4288        }
4289        return r.resultTo;
4290    }
4291
4292    public ComponentName getActivityClassForToken(IBinder token) {
4293        synchronized(this) {
4294            ActivityRecord r = mMainStack.isInStackLocked(token);
4295            if (r == null) {
4296                return null;
4297            }
4298            return r.intent.getComponent();
4299        }
4300    }
4301
4302    public String getPackageForToken(IBinder token) {
4303        synchronized(this) {
4304            ActivityRecord r = mMainStack.isInStackLocked(token);
4305            if (r == null) {
4306                return null;
4307            }
4308            return r.packageName;
4309        }
4310    }
4311
4312    public IIntentSender getIntentSender(int type,
4313            String packageName, IBinder token, String resultWho,
4314            int requestCode, Intent[] intents, String[] resolvedTypes,
4315            int flags, Bundle options) {
4316        enforceNotIsolatedCaller("getIntentSender");
4317        // Refuse possible leaked file descriptors
4318        if (intents != null) {
4319            if (intents.length < 1) {
4320                throw new IllegalArgumentException("Intents array length must be >= 1");
4321            }
4322            for (int i=0; i<intents.length; i++) {
4323                Intent intent = intents[i];
4324                if (intent != null) {
4325                    if (intent.hasFileDescriptors()) {
4326                        throw new IllegalArgumentException("File descriptors passed in Intent");
4327                    }
4328                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4329                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4330                        throw new IllegalArgumentException(
4331                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4332                    }
4333                    intents[i] = new Intent(intent);
4334                }
4335            }
4336            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4337                throw new IllegalArgumentException(
4338                        "Intent array length does not match resolvedTypes length");
4339            }
4340        }
4341        if (options != null) {
4342            if (options.hasFileDescriptors()) {
4343                throw new IllegalArgumentException("File descriptors passed in options");
4344            }
4345        }
4346
4347        synchronized(this) {
4348            int callingUid = Binder.getCallingUid();
4349            try {
4350                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4351                    int uid = AppGlobals.getPackageManager()
4352                            .getPackageUid(packageName, UserId.getUserId(callingUid));
4353                    if (!UserId.isSameApp(callingUid, uid)) {
4354                        String msg = "Permission Denial: getIntentSender() from pid="
4355                            + Binder.getCallingPid()
4356                            + ", uid=" + Binder.getCallingUid()
4357                            + ", (need uid=" + uid + ")"
4358                            + " is not allowed to send as package " + packageName;
4359                        Slog.w(TAG, msg);
4360                        throw new SecurityException(msg);
4361                    }
4362                }
4363
4364                if (DEBUG_MU)
4365                    Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
4366                            + Binder.getOrigCallingUid());
4367                return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
4368                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4369
4370            } catch (RemoteException e) {
4371                throw new SecurityException(e);
4372            }
4373        }
4374    }
4375
4376    IIntentSender getIntentSenderLocked(int type,
4377            String packageName, int callingUid, IBinder token, String resultWho,
4378            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4379            Bundle options) {
4380        if (DEBUG_MU)
4381            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4382        ActivityRecord activity = null;
4383        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4384            activity = mMainStack.isInStackLocked(token);
4385            if (activity == null) {
4386                return null;
4387            }
4388            if (activity.finishing) {
4389                return null;
4390            }
4391        }
4392
4393        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4394        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4395        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4396        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4397                |PendingIntent.FLAG_UPDATE_CURRENT);
4398
4399        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4400                type, packageName, activity, resultWho,
4401                requestCode, intents, resolvedTypes, flags, options);
4402        WeakReference<PendingIntentRecord> ref;
4403        ref = mIntentSenderRecords.get(key);
4404        PendingIntentRecord rec = ref != null ? ref.get() : null;
4405        if (rec != null) {
4406            if (!cancelCurrent) {
4407                if (updateCurrent) {
4408                    if (rec.key.requestIntent != null) {
4409                        rec.key.requestIntent.replaceExtras(intents != null ?
4410                                intents[intents.length - 1] : null);
4411                    }
4412                    if (intents != null) {
4413                        intents[intents.length-1] = rec.key.requestIntent;
4414                        rec.key.allIntents = intents;
4415                        rec.key.allResolvedTypes = resolvedTypes;
4416                    } else {
4417                        rec.key.allIntents = null;
4418                        rec.key.allResolvedTypes = null;
4419                    }
4420                }
4421                return rec;
4422            }
4423            rec.canceled = true;
4424            mIntentSenderRecords.remove(key);
4425        }
4426        if (noCreate) {
4427            return rec;
4428        }
4429        rec = new PendingIntentRecord(this, key, callingUid);
4430        mIntentSenderRecords.put(key, rec.ref);
4431        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4432            if (activity.pendingResults == null) {
4433                activity.pendingResults
4434                        = new HashSet<WeakReference<PendingIntentRecord>>();
4435            }
4436            activity.pendingResults.add(rec.ref);
4437        }
4438        return rec;
4439    }
4440
4441    public void cancelIntentSender(IIntentSender sender) {
4442        if (!(sender instanceof PendingIntentRecord)) {
4443            return;
4444        }
4445        synchronized(this) {
4446            PendingIntentRecord rec = (PendingIntentRecord)sender;
4447            try {
4448                int uid = AppGlobals.getPackageManager()
4449                        .getPackageUid(rec.key.packageName, UserId.getCallingUserId());
4450                if (!UserId.isSameApp(uid, Binder.getCallingUid())) {
4451                    String msg = "Permission Denial: cancelIntentSender() from pid="
4452                        + Binder.getCallingPid()
4453                        + ", uid=" + Binder.getCallingUid()
4454                        + " is not allowed to cancel packges "
4455                        + rec.key.packageName;
4456                    Slog.w(TAG, msg);
4457                    throw new SecurityException(msg);
4458                }
4459            } catch (RemoteException e) {
4460                throw new SecurityException(e);
4461            }
4462            cancelIntentSenderLocked(rec, true);
4463        }
4464    }
4465
4466    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4467        rec.canceled = true;
4468        mIntentSenderRecords.remove(rec.key);
4469        if (cleanActivity && rec.key.activity != null) {
4470            rec.key.activity.pendingResults.remove(rec.ref);
4471        }
4472    }
4473
4474    public String getPackageForIntentSender(IIntentSender pendingResult) {
4475        if (!(pendingResult instanceof PendingIntentRecord)) {
4476            return null;
4477        }
4478        try {
4479            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4480            return res.key.packageName;
4481        } catch (ClassCastException e) {
4482        }
4483        return null;
4484    }
4485
4486    public int getUidForIntentSender(IIntentSender sender) {
4487        if (sender instanceof PendingIntentRecord) {
4488            try {
4489                PendingIntentRecord res = (PendingIntentRecord)sender;
4490                return res.uid;
4491            } catch (ClassCastException e) {
4492            }
4493        }
4494        return -1;
4495    }
4496
4497    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4498        if (!(pendingResult instanceof PendingIntentRecord)) {
4499            return false;
4500        }
4501        try {
4502            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4503            if (res.key.allIntents == null) {
4504                return false;
4505            }
4506            for (int i=0; i<res.key.allIntents.length; i++) {
4507                Intent intent = res.key.allIntents[i];
4508                if (intent.getPackage() != null && intent.getComponent() != null) {
4509                    return false;
4510                }
4511            }
4512            return true;
4513        } catch (ClassCastException e) {
4514        }
4515        return false;
4516    }
4517
4518    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4519        if (!(pendingResult instanceof PendingIntentRecord)) {
4520            return false;
4521        }
4522        try {
4523            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4524            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4525                return true;
4526            }
4527            return false;
4528        } catch (ClassCastException e) {
4529        }
4530        return false;
4531    }
4532
4533    public void setProcessLimit(int max) {
4534        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4535                "setProcessLimit()");
4536        synchronized (this) {
4537            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4538            mProcessLimitOverride = max;
4539        }
4540        trimApplications();
4541    }
4542
4543    public int getProcessLimit() {
4544        synchronized (this) {
4545            return mProcessLimitOverride;
4546        }
4547    }
4548
4549    void foregroundTokenDied(ForegroundToken token) {
4550        synchronized (ActivityManagerService.this) {
4551            synchronized (mPidsSelfLocked) {
4552                ForegroundToken cur
4553                    = mForegroundProcesses.get(token.pid);
4554                if (cur != token) {
4555                    return;
4556                }
4557                mForegroundProcesses.remove(token.pid);
4558                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4559                if (pr == null) {
4560                    return;
4561                }
4562                pr.forcingToForeground = null;
4563                pr.foregroundServices = false;
4564            }
4565            updateOomAdjLocked();
4566        }
4567    }
4568
4569    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4570        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4571                "setProcessForeground()");
4572        synchronized(this) {
4573            boolean changed = false;
4574
4575            synchronized (mPidsSelfLocked) {
4576                ProcessRecord pr = mPidsSelfLocked.get(pid);
4577                if (pr == null && isForeground) {
4578                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4579                    return;
4580                }
4581                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4582                if (oldToken != null) {
4583                    oldToken.token.unlinkToDeath(oldToken, 0);
4584                    mForegroundProcesses.remove(pid);
4585                    if (pr != null) {
4586                        pr.forcingToForeground = null;
4587                    }
4588                    changed = true;
4589                }
4590                if (isForeground && token != null) {
4591                    ForegroundToken newToken = new ForegroundToken() {
4592                        public void binderDied() {
4593                            foregroundTokenDied(this);
4594                        }
4595                    };
4596                    newToken.pid = pid;
4597                    newToken.token = token;
4598                    try {
4599                        token.linkToDeath(newToken, 0);
4600                        mForegroundProcesses.put(pid, newToken);
4601                        pr.forcingToForeground = token;
4602                        changed = true;
4603                    } catch (RemoteException e) {
4604                        // If the process died while doing this, we will later
4605                        // do the cleanup with the process death link.
4606                    }
4607                }
4608            }
4609
4610            if (changed) {
4611                updateOomAdjLocked();
4612            }
4613        }
4614    }
4615
4616    // =========================================================
4617    // PERMISSIONS
4618    // =========================================================
4619
4620    static class PermissionController extends IPermissionController.Stub {
4621        ActivityManagerService mActivityManagerService;
4622        PermissionController(ActivityManagerService activityManagerService) {
4623            mActivityManagerService = activityManagerService;
4624        }
4625
4626        public boolean checkPermission(String permission, int pid, int uid) {
4627            return mActivityManagerService.checkPermission(permission, pid,
4628                    uid) == PackageManager.PERMISSION_GRANTED;
4629        }
4630    }
4631
4632    /**
4633     * This can be called with or without the global lock held.
4634     */
4635    int checkComponentPermission(String permission, int pid, int uid,
4636            int owningUid, boolean exported) {
4637        // We might be performing an operation on behalf of an indirect binder
4638        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4639        // client identity accordingly before proceeding.
4640        Identity tlsIdentity = sCallerIdentity.get();
4641        if (tlsIdentity != null) {
4642            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4643                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4644            uid = tlsIdentity.uid;
4645            pid = tlsIdentity.pid;
4646        }
4647
4648        if (pid == MY_PID) {
4649            return PackageManager.PERMISSION_GRANTED;
4650        }
4651
4652        return ActivityManager.checkComponentPermission(permission, uid,
4653                owningUid, exported);
4654    }
4655
4656    /**
4657     * As the only public entry point for permissions checking, this method
4658     * can enforce the semantic that requesting a check on a null global
4659     * permission is automatically denied.  (Internally a null permission
4660     * string is used when calling {@link #checkComponentPermission} in cases
4661     * when only uid-based security is needed.)
4662     *
4663     * This can be called with or without the global lock held.
4664     */
4665    public int checkPermission(String permission, int pid, int uid) {
4666        if (permission == null) {
4667            return PackageManager.PERMISSION_DENIED;
4668        }
4669        return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true);
4670    }
4671
4672    /**
4673     * Binder IPC calls go through the public entry point.
4674     * This can be called with or without the global lock held.
4675     */
4676    int checkCallingPermission(String permission) {
4677        return checkPermission(permission,
4678                Binder.getCallingPid(),
4679                UserId.getAppId(Binder.getCallingUid()));
4680    }
4681
4682    /**
4683     * This can be called with or without the global lock held.
4684     */
4685    void enforceCallingPermission(String permission, String func) {
4686        if (checkCallingPermission(permission)
4687                == PackageManager.PERMISSION_GRANTED) {
4688            return;
4689        }
4690
4691        String msg = "Permission Denial: " + func + " from pid="
4692                + Binder.getCallingPid()
4693                + ", uid=" + Binder.getCallingUid()
4694                + " requires " + permission;
4695        Slog.w(TAG, msg);
4696        throw new SecurityException(msg);
4697    }
4698
4699    /**
4700     * Determine if UID is holding permissions required to access {@link Uri} in
4701     * the given {@link ProviderInfo}. Final permission checking is always done
4702     * in {@link ContentProvider}.
4703     */
4704    private final boolean checkHoldingPermissionsLocked(
4705            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4706        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4707                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4708
4709        if (pi.applicationInfo.uid == uid) {
4710            return true;
4711        } else if (!pi.exported) {
4712            return false;
4713        }
4714
4715        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4716        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4717        try {
4718            // check if target holds top-level <provider> permissions
4719            if (!readMet && pi.readPermission != null
4720                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4721                readMet = true;
4722            }
4723            if (!writeMet && pi.writePermission != null
4724                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4725                writeMet = true;
4726            }
4727
4728            // track if unprotected read/write is allowed; any denied
4729            // <path-permission> below removes this ability
4730            boolean allowDefaultRead = pi.readPermission == null;
4731            boolean allowDefaultWrite = pi.writePermission == null;
4732
4733            // check if target holds any <path-permission> that match uri
4734            final PathPermission[] pps = pi.pathPermissions;
4735            if (pps != null) {
4736                final String path = uri.getPath();
4737                int i = pps.length;
4738                while (i > 0 && (!readMet || !writeMet)) {
4739                    i--;
4740                    PathPermission pp = pps[i];
4741                    if (pp.match(path)) {
4742                        if (!readMet) {
4743                            final String pprperm = pp.getReadPermission();
4744                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4745                                    + pprperm + " for " + pp.getPath()
4746                                    + ": match=" + pp.match(path)
4747                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4748                            if (pprperm != null) {
4749                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4750                                    readMet = true;
4751                                } else {
4752                                    allowDefaultRead = false;
4753                                }
4754                            }
4755                        }
4756                        if (!writeMet) {
4757                            final String ppwperm = pp.getWritePermission();
4758                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4759                                    + ppwperm + " for " + pp.getPath()
4760                                    + ": match=" + pp.match(path)
4761                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4762                            if (ppwperm != null) {
4763                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4764                                    writeMet = true;
4765                                } else {
4766                                    allowDefaultWrite = false;
4767                                }
4768                            }
4769                        }
4770                    }
4771                }
4772            }
4773
4774            // grant unprotected <provider> read/write, if not blocked by
4775            // <path-permission> above
4776            if (allowDefaultRead) readMet = true;
4777            if (allowDefaultWrite) writeMet = true;
4778
4779        } catch (RemoteException e) {
4780            return false;
4781        }
4782
4783        return readMet && writeMet;
4784    }
4785
4786    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4787            int modeFlags) {
4788        // Root gets to do everything.
4789        if (uid == 0) {
4790            return true;
4791        }
4792        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4793        if (perms == null) return false;
4794        UriPermission perm = perms.get(uri);
4795        if (perm == null) return false;
4796        return (modeFlags&perm.modeFlags) == modeFlags;
4797    }
4798
4799    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4800        enforceNotIsolatedCaller("checkUriPermission");
4801
4802        // Another redirected-binder-call permissions check as in
4803        // {@link checkComponentPermission}.
4804        Identity tlsIdentity = sCallerIdentity.get();
4805        if (tlsIdentity != null) {
4806            uid = tlsIdentity.uid;
4807            pid = tlsIdentity.pid;
4808        }
4809
4810        uid = UserId.getAppId(uid);
4811        // Our own process gets to do everything.
4812        if (pid == MY_PID) {
4813            return PackageManager.PERMISSION_GRANTED;
4814        }
4815        synchronized(this) {
4816            return checkUriPermissionLocked(uri, uid, modeFlags)
4817                    ? PackageManager.PERMISSION_GRANTED
4818                    : PackageManager.PERMISSION_DENIED;
4819        }
4820    }
4821
4822    /**
4823     * Check if the targetPkg can be granted permission to access uri by
4824     * the callingUid using the given modeFlags.  Throws a security exception
4825     * if callingUid is not allowed to do this.  Returns the uid of the target
4826     * if the URI permission grant should be performed; returns -1 if it is not
4827     * needed (for example targetPkg already has permission to access the URI).
4828     * If you already know the uid of the target, you can supply it in
4829     * lastTargetUid else set that to -1.
4830     */
4831    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4832            Uri uri, int modeFlags, int lastTargetUid) {
4833        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4834                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4835        if (modeFlags == 0) {
4836            return -1;
4837        }
4838
4839        if (targetPkg != null) {
4840            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4841                    "Checking grant " + targetPkg + " permission to " + uri);
4842        }
4843
4844        final IPackageManager pm = AppGlobals.getPackageManager();
4845
4846        // If this is not a content: uri, we can't do anything with it.
4847        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4848            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4849                    "Can't grant URI permission for non-content URI: " + uri);
4850            return -1;
4851        }
4852
4853        String name = uri.getAuthority();
4854        ProviderInfo pi = null;
4855        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4856                UserId.getUserId(callingUid));
4857        if (cpr != null) {
4858            pi = cpr.info;
4859        } else {
4860            try {
4861                pi = pm.resolveContentProvider(name,
4862                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid));
4863            } catch (RemoteException ex) {
4864            }
4865        }
4866        if (pi == null) {
4867            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4868            return -1;
4869        }
4870
4871        int targetUid = lastTargetUid;
4872        if (targetUid < 0 && targetPkg != null) {
4873            try {
4874                targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid));
4875                if (targetUid < 0) {
4876                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4877                            "Can't grant URI permission no uid for: " + targetPkg);
4878                    return -1;
4879                }
4880            } catch (RemoteException ex) {
4881                return -1;
4882            }
4883        }
4884
4885        if (targetUid >= 0) {
4886            // First...  does the target actually need this permission?
4887            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4888                // No need to grant the target this permission.
4889                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4890                        "Target " + targetPkg + " already has full permission to " + uri);
4891                return -1;
4892            }
4893        } else {
4894            // First...  there is no target package, so can anyone access it?
4895            boolean allowed = pi.exported;
4896            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4897                if (pi.readPermission != null) {
4898                    allowed = false;
4899                }
4900            }
4901            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4902                if (pi.writePermission != null) {
4903                    allowed = false;
4904                }
4905            }
4906            if (allowed) {
4907                return -1;
4908            }
4909        }
4910
4911        // Second...  is the provider allowing granting of URI permissions?
4912        if (!pi.grantUriPermissions) {
4913            throw new SecurityException("Provider " + pi.packageName
4914                    + "/" + pi.name
4915                    + " does not allow granting of Uri permissions (uri "
4916                    + uri + ")");
4917        }
4918        if (pi.uriPermissionPatterns != null) {
4919            final int N = pi.uriPermissionPatterns.length;
4920            boolean allowed = false;
4921            for (int i=0; i<N; i++) {
4922                if (pi.uriPermissionPatterns[i] != null
4923                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4924                    allowed = true;
4925                    break;
4926                }
4927            }
4928            if (!allowed) {
4929                throw new SecurityException("Provider " + pi.packageName
4930                        + "/" + pi.name
4931                        + " does not allow granting of permission to path of Uri "
4932                        + uri);
4933            }
4934        }
4935
4936        // Third...  does the caller itself have permission to access
4937        // this uri?
4938        if (callingUid != Process.myUid()) {
4939            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4940                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4941                    throw new SecurityException("Uid " + callingUid
4942                            + " does not have permission to uri " + uri);
4943                }
4944            }
4945        }
4946
4947        return targetUid;
4948    }
4949
4950    public int checkGrantUriPermission(int callingUid, String targetPkg,
4951            Uri uri, int modeFlags) {
4952        enforceNotIsolatedCaller("checkGrantUriPermission");
4953        synchronized(this) {
4954            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
4955        }
4956    }
4957
4958    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4959            Uri uri, int modeFlags, UriPermissionOwner owner) {
4960        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4961                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4962        if (modeFlags == 0) {
4963            return;
4964        }
4965
4966        // So here we are: the caller has the assumed permission
4967        // to the uri, and the target doesn't.  Let's now give this to
4968        // the target.
4969
4970        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4971                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
4972
4973        HashMap<Uri, UriPermission> targetUris
4974                = mGrantedUriPermissions.get(targetUid);
4975        if (targetUris == null) {
4976            targetUris = new HashMap<Uri, UriPermission>();
4977            mGrantedUriPermissions.put(targetUid, targetUris);
4978        }
4979
4980        UriPermission perm = targetUris.get(uri);
4981        if (perm == null) {
4982            perm = new UriPermission(targetUid, uri);
4983            targetUris.put(uri, perm);
4984        }
4985
4986        perm.modeFlags |= modeFlags;
4987        if (owner == null) {
4988            perm.globalModeFlags |= modeFlags;
4989        } else {
4990            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4991                 perm.readOwners.add(owner);
4992                 owner.addReadPermission(perm);
4993            }
4994            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4995                 perm.writeOwners.add(owner);
4996                 owner.addWritePermission(perm);
4997            }
4998        }
4999    }
5000
5001    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5002            int modeFlags, UriPermissionOwner owner) {
5003        if (targetPkg == null) {
5004            throw new NullPointerException("targetPkg");
5005        }
5006
5007        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5008        if (targetUid < 0) {
5009            return;
5010        }
5011
5012        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5013    }
5014
5015    static class NeededUriGrants extends ArrayList<Uri> {
5016        final String targetPkg;
5017        final int targetUid;
5018        final int flags;
5019
5020        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5021            targetPkg = _targetPkg;
5022            targetUid = _targetUid;
5023            flags = _flags;
5024        }
5025    }
5026
5027    /**
5028     * Like checkGrantUriPermissionLocked, but takes an Intent.
5029     */
5030    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5031            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5032        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5033                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5034                + " clip=" + (intent != null ? intent.getClipData() : null)
5035                + " from " + intent + "; flags=0x"
5036                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5037
5038        if (targetPkg == null) {
5039            throw new NullPointerException("targetPkg");
5040        }
5041
5042        if (intent == null) {
5043            return null;
5044        }
5045        Uri data = intent.getData();
5046        ClipData clip = intent.getClipData();
5047        if (data == null && clip == null) {
5048            return null;
5049        }
5050        if (data != null) {
5051            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5052                mode, needed != null ? needed.targetUid : -1);
5053            if (target > 0) {
5054                if (needed == null) {
5055                    needed = new NeededUriGrants(targetPkg, target, mode);
5056                }
5057                needed.add(data);
5058            }
5059        }
5060        if (clip != null) {
5061            for (int i=0; i<clip.getItemCount(); i++) {
5062                Uri uri = clip.getItemAt(i).getUri();
5063                if (uri != null) {
5064                    int target = -1;
5065                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5066                            mode, needed != null ? needed.targetUid : -1);
5067                    if (target > 0) {
5068                        if (needed == null) {
5069                            needed = new NeededUriGrants(targetPkg, target, mode);
5070                        }
5071                        needed.add(uri);
5072                    }
5073                } else {
5074                    Intent clipIntent = clip.getItemAt(i).getIntent();
5075                    if (clipIntent != null) {
5076                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5077                                callingUid, targetPkg, clipIntent, mode, needed);
5078                        if (newNeeded != null) {
5079                            needed = newNeeded;
5080                        }
5081                    }
5082                }
5083            }
5084        }
5085
5086        return needed;
5087    }
5088
5089    /**
5090     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5091     */
5092    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5093            UriPermissionOwner owner) {
5094        if (needed != null) {
5095            for (int i=0; i<needed.size(); i++) {
5096                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5097                        needed.get(i), needed.flags, owner);
5098            }
5099        }
5100    }
5101
5102    void grantUriPermissionFromIntentLocked(int callingUid,
5103            String targetPkg, Intent intent, UriPermissionOwner owner) {
5104        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5105                intent, intent != null ? intent.getFlags() : 0, null);
5106        if (needed == null) {
5107            return;
5108        }
5109
5110        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5111    }
5112
5113    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5114            Uri uri, int modeFlags) {
5115        enforceNotIsolatedCaller("grantUriPermission");
5116        synchronized(this) {
5117            final ProcessRecord r = getRecordForAppLocked(caller);
5118            if (r == null) {
5119                throw new SecurityException("Unable to find app for caller "
5120                        + caller
5121                        + " when granting permission to uri " + uri);
5122            }
5123            if (targetPkg == null) {
5124                throw new IllegalArgumentException("null target");
5125            }
5126            if (uri == null) {
5127                throw new IllegalArgumentException("null uri");
5128            }
5129
5130            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5131                    null);
5132        }
5133    }
5134
5135    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5136        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5137                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5138            HashMap<Uri, UriPermission> perms
5139                    = mGrantedUriPermissions.get(perm.uid);
5140            if (perms != null) {
5141                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5142                        "Removing " + perm.uid + " permission to " + perm.uri);
5143                perms.remove(perm.uri);
5144                if (perms.size() == 0) {
5145                    mGrantedUriPermissions.remove(perm.uid);
5146                }
5147            }
5148        }
5149    }
5150
5151    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5152            int modeFlags) {
5153        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5154                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5155        if (modeFlags == 0) {
5156            return;
5157        }
5158
5159        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5160                "Revoking all granted permissions to " + uri);
5161
5162        final IPackageManager pm = AppGlobals.getPackageManager();
5163
5164        final String authority = uri.getAuthority();
5165        ProviderInfo pi = null;
5166        int userId = UserId.getUserId(callingUid);
5167        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5168        if (cpr != null) {
5169            pi = cpr.info;
5170        } else {
5171            try {
5172                pi = pm.resolveContentProvider(authority,
5173                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5174            } catch (RemoteException ex) {
5175            }
5176        }
5177        if (pi == null) {
5178            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5179            return;
5180        }
5181
5182        // Does the caller have this permission on the URI?
5183        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5184            // Right now, if you are not the original owner of the permission,
5185            // you are not allowed to revoke it.
5186            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5187                throw new SecurityException("Uid " + callingUid
5188                        + " does not have permission to uri " + uri);
5189            //}
5190        }
5191
5192        // Go through all of the permissions and remove any that match.
5193        final List<String> SEGMENTS = uri.getPathSegments();
5194        if (SEGMENTS != null) {
5195            final int NS = SEGMENTS.size();
5196            int N = mGrantedUriPermissions.size();
5197            for (int i=0; i<N; i++) {
5198                HashMap<Uri, UriPermission> perms
5199                        = mGrantedUriPermissions.valueAt(i);
5200                Iterator<UriPermission> it = perms.values().iterator();
5201            toploop:
5202                while (it.hasNext()) {
5203                    UriPermission perm = it.next();
5204                    Uri targetUri = perm.uri;
5205                    if (!authority.equals(targetUri.getAuthority())) {
5206                        continue;
5207                    }
5208                    List<String> targetSegments = targetUri.getPathSegments();
5209                    if (targetSegments == null) {
5210                        continue;
5211                    }
5212                    if (targetSegments.size() < NS) {
5213                        continue;
5214                    }
5215                    for (int j=0; j<NS; j++) {
5216                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5217                            continue toploop;
5218                        }
5219                    }
5220                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5221                            "Revoking " + perm.uid + " permission to " + perm.uri);
5222                    perm.clearModes(modeFlags);
5223                    if (perm.modeFlags == 0) {
5224                        it.remove();
5225                    }
5226                }
5227                if (perms.size() == 0) {
5228                    mGrantedUriPermissions.remove(
5229                            mGrantedUriPermissions.keyAt(i));
5230                    N--;
5231                    i--;
5232                }
5233            }
5234        }
5235    }
5236
5237    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5238            int modeFlags) {
5239        enforceNotIsolatedCaller("revokeUriPermission");
5240        synchronized(this) {
5241            final ProcessRecord r = getRecordForAppLocked(caller);
5242            if (r == null) {
5243                throw new SecurityException("Unable to find app for caller "
5244                        + caller
5245                        + " when revoking permission to uri " + uri);
5246            }
5247            if (uri == null) {
5248                Slog.w(TAG, "revokeUriPermission: null uri");
5249                return;
5250            }
5251
5252            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5253                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5254            if (modeFlags == 0) {
5255                return;
5256            }
5257
5258            final IPackageManager pm = AppGlobals.getPackageManager();
5259
5260            final String authority = uri.getAuthority();
5261            ProviderInfo pi = null;
5262            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5263            if (cpr != null) {
5264                pi = cpr.info;
5265            } else {
5266                try {
5267                    pi = pm.resolveContentProvider(authority,
5268                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5269                } catch (RemoteException ex) {
5270                }
5271            }
5272            if (pi == null) {
5273                Slog.w(TAG, "No content provider found for permission revoke: "
5274                        + uri.toSafeString());
5275                return;
5276            }
5277
5278            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5279        }
5280    }
5281
5282    @Override
5283    public IBinder newUriPermissionOwner(String name) {
5284        enforceNotIsolatedCaller("newUriPermissionOwner");
5285        synchronized(this) {
5286            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5287            return owner.getExternalTokenLocked();
5288        }
5289    }
5290
5291    @Override
5292    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5293            Uri uri, int modeFlags) {
5294        synchronized(this) {
5295            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5296            if (owner == null) {
5297                throw new IllegalArgumentException("Unknown owner: " + token);
5298            }
5299            if (fromUid != Binder.getCallingUid()) {
5300                if (Binder.getCallingUid() != Process.myUid()) {
5301                    // Only system code can grant URI permissions on behalf
5302                    // of other users.
5303                    throw new SecurityException("nice try");
5304                }
5305            }
5306            if (targetPkg == null) {
5307                throw new IllegalArgumentException("null target");
5308            }
5309            if (uri == null) {
5310                throw new IllegalArgumentException("null uri");
5311            }
5312
5313            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5314        }
5315    }
5316
5317    @Override
5318    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5319        synchronized(this) {
5320            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5321            if (owner == null) {
5322                throw new IllegalArgumentException("Unknown owner: " + token);
5323            }
5324
5325            if (uri == null) {
5326                owner.removeUriPermissionsLocked(mode);
5327            } else {
5328                owner.removeUriPermissionLocked(uri, mode);
5329            }
5330        }
5331    }
5332
5333    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5334        synchronized (this) {
5335            ProcessRecord app =
5336                who != null ? getRecordForAppLocked(who) : null;
5337            if (app == null) return;
5338
5339            Message msg = Message.obtain();
5340            msg.what = WAIT_FOR_DEBUGGER_MSG;
5341            msg.obj = app;
5342            msg.arg1 = waiting ? 1 : 0;
5343            mHandler.sendMessage(msg);
5344        }
5345    }
5346
5347    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5348        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5349        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5350        outInfo.availMem = Process.getFreeMemory();
5351        outInfo.totalMem = Process.getTotalMemory();
5352        outInfo.threshold = homeAppMem;
5353        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5354        outInfo.hiddenAppThreshold = hiddenAppMem;
5355        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5356                ProcessList.SERVICE_ADJ);
5357        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5358                ProcessList.VISIBLE_APP_ADJ);
5359        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5360                ProcessList.FOREGROUND_APP_ADJ);
5361    }
5362
5363    // =========================================================
5364    // TASK MANAGEMENT
5365    // =========================================================
5366
5367    public List getTasks(int maxNum, int flags,
5368                         IThumbnailReceiver receiver) {
5369        ArrayList list = new ArrayList();
5370
5371        PendingThumbnailsRecord pending = null;
5372        IApplicationThread topThumbnail = null;
5373        ActivityRecord topRecord = null;
5374
5375        synchronized(this) {
5376            if (localLOGV) Slog.v(
5377                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5378                + ", receiver=" + receiver);
5379
5380            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5381                    != PackageManager.PERMISSION_GRANTED) {
5382                if (receiver != null) {
5383                    // If the caller wants to wait for pending thumbnails,
5384                    // it ain't gonna get them.
5385                    try {
5386                        receiver.finished();
5387                    } catch (RemoteException ex) {
5388                    }
5389                }
5390                String msg = "Permission Denial: getTasks() from pid="
5391                        + Binder.getCallingPid()
5392                        + ", uid=" + Binder.getCallingUid()
5393                        + " requires " + android.Manifest.permission.GET_TASKS;
5394                Slog.w(TAG, msg);
5395                throw new SecurityException(msg);
5396            }
5397
5398            int pos = mMainStack.mHistory.size()-1;
5399            ActivityRecord next =
5400                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5401            ActivityRecord top = null;
5402            TaskRecord curTask = null;
5403            int numActivities = 0;
5404            int numRunning = 0;
5405            while (pos >= 0 && maxNum > 0) {
5406                final ActivityRecord r = next;
5407                pos--;
5408                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5409
5410                // Initialize state for next task if needed.
5411                if (top == null ||
5412                        (top.state == ActivityState.INITIALIZING
5413                            && top.task == r.task)) {
5414                    top = r;
5415                    curTask = r.task;
5416                    numActivities = numRunning = 0;
5417                }
5418
5419                // Add 'r' into the current task.
5420                numActivities++;
5421                if (r.app != null && r.app.thread != null) {
5422                    numRunning++;
5423                }
5424
5425                if (localLOGV) Slog.v(
5426                    TAG, r.intent.getComponent().flattenToShortString()
5427                    + ": task=" + r.task);
5428
5429                // If the next one is a different task, generate a new
5430                // TaskInfo entry for what we have.
5431                if (next == null || next.task != curTask) {
5432                    ActivityManager.RunningTaskInfo ci
5433                            = new ActivityManager.RunningTaskInfo();
5434                    ci.id = curTask.taskId;
5435                    ci.baseActivity = r.intent.getComponent();
5436                    ci.topActivity = top.intent.getComponent();
5437                    if (top.thumbHolder != null) {
5438                        ci.description = top.thumbHolder.lastDescription;
5439                    }
5440                    ci.numActivities = numActivities;
5441                    ci.numRunning = numRunning;
5442                    //System.out.println(
5443                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5444                    if (ci.thumbnail == null && receiver != null) {
5445                        if (localLOGV) Slog.v(
5446                            TAG, "State=" + top.state + "Idle=" + top.idle
5447                            + " app=" + top.app
5448                            + " thr=" + (top.app != null ? top.app.thread : null));
5449                        if (top.state == ActivityState.RESUMED
5450                                || top.state == ActivityState.PAUSING) {
5451                            if (top.idle && top.app != null
5452                                && top.app.thread != null) {
5453                                topRecord = top;
5454                                topThumbnail = top.app.thread;
5455                            } else {
5456                                top.thumbnailNeeded = true;
5457                            }
5458                        }
5459                        if (pending == null) {
5460                            pending = new PendingThumbnailsRecord(receiver);
5461                        }
5462                        pending.pendingRecords.add(top);
5463                    }
5464                    list.add(ci);
5465                    maxNum--;
5466                    top = null;
5467                }
5468            }
5469
5470            if (pending != null) {
5471                mPendingThumbnails.add(pending);
5472            }
5473        }
5474
5475        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5476
5477        if (topThumbnail != null) {
5478            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5479            try {
5480                topThumbnail.requestThumbnail(topRecord.appToken);
5481            } catch (Exception e) {
5482                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5483                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5484            }
5485        }
5486
5487        if (pending == null && receiver != null) {
5488            // In this case all thumbnails were available and the client
5489            // is being asked to be told when the remaining ones come in...
5490            // which is unusually, since the top-most currently running
5491            // activity should never have a canned thumbnail!  Oh well.
5492            try {
5493                receiver.finished();
5494            } catch (RemoteException ex) {
5495            }
5496        }
5497
5498        return list;
5499    }
5500
5501    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5502            int flags, int userId) {
5503        final int callingUid = Binder.getCallingUid();
5504        if (userId != UserId.getCallingUserId()) {
5505            // Check if the caller is holding permissions for cross-user requests.
5506            if (checkComponentPermission(
5507                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5508                    Binder.getCallingPid(), callingUid, -1, true)
5509                    != PackageManager.PERMISSION_GRANTED) {
5510                String msg = "Permission Denial: "
5511                        + "Request to get recent tasks for user " + userId
5512                        + " but is calling from user " + UserId.getUserId(callingUid)
5513                        + "; this requires "
5514                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5515                Slog.w(TAG, msg);
5516                throw new SecurityException(msg);
5517            } else {
5518                if (userId == UserId.USER_CURRENT) {
5519                    userId = mCurrentUserId;
5520                }
5521            }
5522        }
5523
5524        synchronized (this) {
5525            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5526                    "getRecentTasks()");
5527            final boolean detailed = checkCallingPermission(
5528                    android.Manifest.permission.GET_DETAILED_TASKS)
5529                    == PackageManager.PERMISSION_GRANTED;
5530
5531            IPackageManager pm = AppGlobals.getPackageManager();
5532
5533            final int N = mRecentTasks.size();
5534            ArrayList<ActivityManager.RecentTaskInfo> res
5535                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5536                            maxNum < N ? maxNum : N);
5537            for (int i=0; i<N && maxNum > 0; i++) {
5538                TaskRecord tr = mRecentTasks.get(i);
5539                // Only add calling user's recent tasks
5540                if (tr.userId != userId) continue;
5541                // Return the entry if desired by the caller.  We always return
5542                // the first entry, because callers always expect this to be the
5543                // foreground app.  We may filter others if the caller has
5544                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5545                // we should exclude the entry.
5546
5547                if (i == 0
5548                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5549                        || (tr.intent == null)
5550                        || ((tr.intent.getFlags()
5551                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5552                    ActivityManager.RecentTaskInfo rti
5553                            = new ActivityManager.RecentTaskInfo();
5554                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5555                    rti.persistentId = tr.taskId;
5556                    rti.baseIntent = new Intent(
5557                            tr.intent != null ? tr.intent : tr.affinityIntent);
5558                    if (!detailed) {
5559                        rti.baseIntent.replaceExtras((Bundle)null);
5560                    }
5561                    rti.origActivity = tr.origActivity;
5562                    rti.description = tr.lastDescription;
5563
5564                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5565                        // Check whether this activity is currently available.
5566                        try {
5567                            if (rti.origActivity != null) {
5568                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5569                                        == null) {
5570                                    continue;
5571                                }
5572                            } else if (rti.baseIntent != null) {
5573                                if (pm.queryIntentActivities(rti.baseIntent,
5574                                        null, 0, userId) == null) {
5575                                    continue;
5576                                }
5577                            }
5578                        } catch (RemoteException e) {
5579                            // Will never happen.
5580                        }
5581                    }
5582
5583                    res.add(rti);
5584                    maxNum--;
5585                }
5586            }
5587            return res;
5588        }
5589    }
5590
5591    private TaskRecord taskForIdLocked(int id) {
5592        final int N = mRecentTasks.size();
5593        for (int i=0; i<N; i++) {
5594            TaskRecord tr = mRecentTasks.get(i);
5595            if (tr.taskId == id) {
5596                return tr;
5597            }
5598        }
5599        return null;
5600    }
5601
5602    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5603        synchronized (this) {
5604            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5605                    "getTaskThumbnails()");
5606            TaskRecord tr = taskForIdLocked(id);
5607            if (tr != null) {
5608                return mMainStack.getTaskThumbnailsLocked(tr);
5609            }
5610        }
5611        return null;
5612    }
5613
5614    public boolean removeSubTask(int taskId, int subTaskIndex) {
5615        synchronized (this) {
5616            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5617                    "removeSubTask()");
5618            long ident = Binder.clearCallingIdentity();
5619            try {
5620                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5621                        true) != null;
5622            } finally {
5623                Binder.restoreCallingIdentity(ident);
5624            }
5625        }
5626    }
5627
5628    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5629        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5630        Intent baseIntent = new Intent(
5631                tr.intent != null ? tr.intent : tr.affinityIntent);
5632        ComponentName component = baseIntent.getComponent();
5633        if (component == null) {
5634            Slog.w(TAG, "Now component for base intent of task: " + tr);
5635            return;
5636        }
5637
5638        // Find any running services associated with this app.
5639        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5640
5641        if (killProcesses) {
5642            // Find any running processes associated with this app.
5643            final String pkg = component.getPackageName();
5644            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5645            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5646            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5647                for (int i=0; i<uids.size(); i++) {
5648                    ProcessRecord proc = uids.valueAt(i);
5649                    if (proc.userId != tr.userId) {
5650                        continue;
5651                    }
5652                    if (!proc.pkgList.contains(pkg)) {
5653                        continue;
5654                    }
5655                    procs.add(proc);
5656                }
5657            }
5658
5659            // Kill the running processes.
5660            for (int i=0; i<procs.size(); i++) {
5661                ProcessRecord pr = procs.get(i);
5662                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5663                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5664                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5665                            pr.processName, pr.setAdj, "remove task");
5666                    pr.killedBackground = true;
5667                    Process.killProcessQuiet(pr.pid);
5668                } else {
5669                    pr.waitingToKill = "remove task";
5670                }
5671            }
5672        }
5673    }
5674
5675    public boolean removeTask(int taskId, int flags) {
5676        synchronized (this) {
5677            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5678                    "removeTask()");
5679            long ident = Binder.clearCallingIdentity();
5680            try {
5681                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5682                        false);
5683                if (r != null) {
5684                    mRecentTasks.remove(r.task);
5685                    cleanUpRemovedTaskLocked(r.task, flags);
5686                    return true;
5687                } else {
5688                    TaskRecord tr = null;
5689                    int i=0;
5690                    while (i < mRecentTasks.size()) {
5691                        TaskRecord t = mRecentTasks.get(i);
5692                        if (t.taskId == taskId) {
5693                            tr = t;
5694                            break;
5695                        }
5696                        i++;
5697                    }
5698                    if (tr != null) {
5699                        if (tr.numActivities <= 0) {
5700                            // Caller is just removing a recent task that is
5701                            // not actively running.  That is easy!
5702                            mRecentTasks.remove(i);
5703                            cleanUpRemovedTaskLocked(tr, flags);
5704                            return true;
5705                        } else {
5706                            Slog.w(TAG, "removeTask: task " + taskId
5707                                    + " does not have activities to remove, "
5708                                    + " but numActivities=" + tr.numActivities
5709                                    + ": " + tr);
5710                        }
5711                    }
5712                }
5713            } finally {
5714                Binder.restoreCallingIdentity(ident);
5715            }
5716        }
5717        return false;
5718    }
5719
5720    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5721        int j;
5722        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5723        TaskRecord jt = startTask;
5724
5725        // First look backwards
5726        for (j=startIndex-1; j>=0; j--) {
5727            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5728            if (r.task != jt) {
5729                jt = r.task;
5730                if (affinity.equals(jt.affinity)) {
5731                    return j;
5732                }
5733            }
5734        }
5735
5736        // Now look forwards
5737        final int N = mMainStack.mHistory.size();
5738        jt = startTask;
5739        for (j=startIndex+1; j<N; j++) {
5740            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5741            if (r.task != jt) {
5742                if (affinity.equals(jt.affinity)) {
5743                    return j;
5744                }
5745                jt = r.task;
5746            }
5747        }
5748
5749        // Might it be at the top?
5750        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5751            return N-1;
5752        }
5753
5754        return -1;
5755    }
5756
5757    /**
5758     * TODO: Add mController hook
5759     */
5760    public void moveTaskToFront(int task, int flags, Bundle options) {
5761        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5762                "moveTaskToFront()");
5763
5764        synchronized(this) {
5765            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5766                    Binder.getCallingUid(), "Task to front")) {
5767                ActivityOptions.abort(options);
5768                return;
5769            }
5770            final long origId = Binder.clearCallingIdentity();
5771            try {
5772                TaskRecord tr = taskForIdLocked(task);
5773                if (tr != null) {
5774                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5775                        mMainStack.mUserLeaving = true;
5776                    }
5777                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5778                        // Caller wants the home activity moved with it.  To accomplish this,
5779                        // we'll just move the home task to the top first.
5780                        mMainStack.moveHomeToFrontLocked();
5781                    }
5782                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5783                    return;
5784                }
5785                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5786                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5787                    if (hr.task.taskId == task) {
5788                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5789                            mMainStack.mUserLeaving = true;
5790                        }
5791                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5792                            // Caller wants the home activity moved with it.  To accomplish this,
5793                            // we'll just move the home task to the top first.
5794                            mMainStack.moveHomeToFrontLocked();
5795                        }
5796                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5797                        return;
5798                    }
5799                }
5800            } finally {
5801                Binder.restoreCallingIdentity(origId);
5802            }
5803            ActivityOptions.abort(options);
5804        }
5805    }
5806
5807    public void moveTaskToBack(int task) {
5808        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5809                "moveTaskToBack()");
5810
5811        synchronized(this) {
5812            if (mMainStack.mResumedActivity != null
5813                    && mMainStack.mResumedActivity.task.taskId == task) {
5814                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5815                        Binder.getCallingUid(), "Task to back")) {
5816                    return;
5817                }
5818            }
5819            final long origId = Binder.clearCallingIdentity();
5820            mMainStack.moveTaskToBackLocked(task, null);
5821            Binder.restoreCallingIdentity(origId);
5822        }
5823    }
5824
5825    /**
5826     * Moves an activity, and all of the other activities within the same task, to the bottom
5827     * of the history stack.  The activity's order within the task is unchanged.
5828     *
5829     * @param token A reference to the activity we wish to move
5830     * @param nonRoot If false then this only works if the activity is the root
5831     *                of a task; if true it will work for any activity in a task.
5832     * @return Returns true if the move completed, false if not.
5833     */
5834    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5835        enforceNotIsolatedCaller("moveActivityTaskToBack");
5836        synchronized(this) {
5837            final long origId = Binder.clearCallingIdentity();
5838            int taskId = getTaskForActivityLocked(token, !nonRoot);
5839            if (taskId >= 0) {
5840                return mMainStack.moveTaskToBackLocked(taskId, null);
5841            }
5842            Binder.restoreCallingIdentity(origId);
5843        }
5844        return false;
5845    }
5846
5847    public void moveTaskBackwards(int task) {
5848        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5849                "moveTaskBackwards()");
5850
5851        synchronized(this) {
5852            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5853                    Binder.getCallingUid(), "Task backwards")) {
5854                return;
5855            }
5856            final long origId = Binder.clearCallingIdentity();
5857            moveTaskBackwardsLocked(task);
5858            Binder.restoreCallingIdentity(origId);
5859        }
5860    }
5861
5862    private final void moveTaskBackwardsLocked(int task) {
5863        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5864    }
5865
5866    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5867        synchronized(this) {
5868            return getTaskForActivityLocked(token, onlyRoot);
5869        }
5870    }
5871
5872    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5873        final int N = mMainStack.mHistory.size();
5874        TaskRecord lastTask = null;
5875        for (int i=0; i<N; i++) {
5876            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5877            if (r.appToken == token) {
5878                if (!onlyRoot || lastTask != r.task) {
5879                    return r.task.taskId;
5880                }
5881                return -1;
5882            }
5883            lastTask = r.task;
5884        }
5885
5886        return -1;
5887    }
5888
5889    // =========================================================
5890    // THUMBNAILS
5891    // =========================================================
5892
5893    public void reportThumbnail(IBinder token,
5894            Bitmap thumbnail, CharSequence description) {
5895        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5896        final long origId = Binder.clearCallingIdentity();
5897        sendPendingThumbnail(null, token, thumbnail, description, true);
5898        Binder.restoreCallingIdentity(origId);
5899    }
5900
5901    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5902            Bitmap thumbnail, CharSequence description, boolean always) {
5903        TaskRecord task = null;
5904        ArrayList receivers = null;
5905
5906        //System.out.println("Send pending thumbnail: " + r);
5907
5908        synchronized(this) {
5909            if (r == null) {
5910                r = mMainStack.isInStackLocked(token);
5911                if (r == null) {
5912                    return;
5913                }
5914            }
5915            if (thumbnail == null && r.thumbHolder != null) {
5916                thumbnail = r.thumbHolder.lastThumbnail;
5917                description = r.thumbHolder.lastDescription;
5918            }
5919            if (thumbnail == null && !always) {
5920                // If there is no thumbnail, and this entry is not actually
5921                // going away, then abort for now and pick up the next
5922                // thumbnail we get.
5923                return;
5924            }
5925            task = r.task;
5926
5927            int N = mPendingThumbnails.size();
5928            int i=0;
5929            while (i<N) {
5930                PendingThumbnailsRecord pr =
5931                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5932                //System.out.println("Looking in " + pr.pendingRecords);
5933                if (pr.pendingRecords.remove(r)) {
5934                    if (receivers == null) {
5935                        receivers = new ArrayList();
5936                    }
5937                    receivers.add(pr);
5938                    if (pr.pendingRecords.size() == 0) {
5939                        pr.finished = true;
5940                        mPendingThumbnails.remove(i);
5941                        N--;
5942                        continue;
5943                    }
5944                }
5945                i++;
5946            }
5947        }
5948
5949        if (receivers != null) {
5950            final int N = receivers.size();
5951            for (int i=0; i<N; i++) {
5952                try {
5953                    PendingThumbnailsRecord pr =
5954                        (PendingThumbnailsRecord)receivers.get(i);
5955                    pr.receiver.newThumbnail(
5956                        task != null ? task.taskId : -1, thumbnail, description);
5957                    if (pr.finished) {
5958                        pr.receiver.finished();
5959                    }
5960                } catch (Exception e) {
5961                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
5962                }
5963            }
5964        }
5965    }
5966
5967    // =========================================================
5968    // CONTENT PROVIDERS
5969    // =========================================================
5970
5971    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5972        List<ProviderInfo> providers = null;
5973        try {
5974            providers = AppGlobals.getPackageManager().
5975                queryContentProviders(app.processName, app.uid,
5976                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
5977        } catch (RemoteException ex) {
5978        }
5979        if (DEBUG_MU)
5980            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
5981        int userId = app.userId;
5982        if (providers != null) {
5983            int N = providers.size();
5984            for (int i=0; i<N; i++) {
5985                ProviderInfo cpi =
5986                    (ProviderInfo)providers.get(i);
5987                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
5988                        cpi.name, cpi.flags);
5989                if (singleton && UserId.getUserId(app.uid) != 0) {
5990                    // This is a singleton provider, but a user besides the
5991                    // default user is asking to initialize a process it runs
5992                    // in...  well, no, it doesn't actually run in this process,
5993                    // it runs in the process of the default user.  Get rid of it.
5994                    providers.remove(i);
5995                    N--;
5996                    continue;
5997                }
5998
5999                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6000                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6001                if (cpr == null) {
6002                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6003                    mProviderMap.putProviderByClass(comp, cpr);
6004                }
6005                if (DEBUG_MU)
6006                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6007                app.pubProviders.put(cpi.name, cpr);
6008                app.addPackage(cpi.applicationInfo.packageName);
6009                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6010            }
6011        }
6012        return providers;
6013    }
6014
6015    /**
6016     * Check if {@link ProcessRecord} has a possible chance at accessing the
6017     * given {@link ProviderInfo}. Final permission checking is always done
6018     * in {@link ContentProvider}.
6019     */
6020    private final String checkContentProviderPermissionLocked(
6021            ProviderInfo cpi, ProcessRecord r) {
6022        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6023        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6024        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6025                cpi.applicationInfo.uid, cpi.exported)
6026                == PackageManager.PERMISSION_GRANTED) {
6027            return null;
6028        }
6029        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6030                cpi.applicationInfo.uid, cpi.exported)
6031                == PackageManager.PERMISSION_GRANTED) {
6032            return null;
6033        }
6034
6035        PathPermission[] pps = cpi.pathPermissions;
6036        if (pps != null) {
6037            int i = pps.length;
6038            while (i > 0) {
6039                i--;
6040                PathPermission pp = pps[i];
6041                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6042                        cpi.applicationInfo.uid, cpi.exported)
6043                        == PackageManager.PERMISSION_GRANTED) {
6044                    return null;
6045                }
6046                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6047                        cpi.applicationInfo.uid, cpi.exported)
6048                        == PackageManager.PERMISSION_GRANTED) {
6049                    return null;
6050                }
6051            }
6052        }
6053
6054        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6055        if (perms != null) {
6056            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6057                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6058                    return null;
6059                }
6060            }
6061        }
6062
6063        String msg;
6064        if (!cpi.exported) {
6065            msg = "Permission Denial: opening provider " + cpi.name
6066                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6067                    + ", uid=" + callingUid + ") that is not exported from uid "
6068                    + cpi.applicationInfo.uid;
6069        } else {
6070            msg = "Permission Denial: opening provider " + cpi.name
6071                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6072                    + ", uid=" + callingUid + ") requires "
6073                    + cpi.readPermission + " or " + cpi.writePermission;
6074        }
6075        Slog.w(TAG, msg);
6076        return msg;
6077    }
6078
6079    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6080            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6081        if (r != null) {
6082            for (int i=0; i<r.conProviders.size(); i++) {
6083                ContentProviderConnection conn = r.conProviders.get(i);
6084                if (conn.provider == cpr) {
6085                    if (DEBUG_PROVIDER) Slog.v(TAG,
6086                            "Adding provider requested by "
6087                            + r.processName + " from process "
6088                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6089                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6090                    if (stable) {
6091                        conn.stableCount++;
6092                        conn.numStableIncs++;
6093                    } else {
6094                        conn.unstableCount++;
6095                        conn.numUnstableIncs++;
6096                    }
6097                    return conn;
6098                }
6099            }
6100            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6101            if (stable) {
6102                conn.stableCount = 1;
6103                conn.numStableIncs = 1;
6104            } else {
6105                conn.unstableCount = 1;
6106                conn.numUnstableIncs = 1;
6107            }
6108            cpr.connections.add(conn);
6109            r.conProviders.add(conn);
6110            return conn;
6111        }
6112        cpr.addExternalProcessHandleLocked(externalProcessToken);
6113        return null;
6114    }
6115
6116    boolean decProviderCountLocked(ContentProviderConnection conn,
6117            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6118        if (conn != null) {
6119            cpr = conn.provider;
6120            if (DEBUG_PROVIDER) Slog.v(TAG,
6121                    "Removing provider requested by "
6122                    + conn.client.processName + " from process "
6123                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6124                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6125            if (stable) {
6126                conn.stableCount--;
6127            } else {
6128                conn.unstableCount--;
6129            }
6130            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6131                cpr.connections.remove(conn);
6132                conn.client.conProviders.remove(conn);
6133                return true;
6134            }
6135            return false;
6136        }
6137        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6138        return false;
6139    }
6140
6141    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6142            String name, IBinder token, boolean stable) {
6143        ContentProviderRecord cpr;
6144        ContentProviderConnection conn = null;
6145        ProviderInfo cpi = null;
6146
6147        synchronized(this) {
6148            ProcessRecord r = null;
6149            if (caller != null) {
6150                r = getRecordForAppLocked(caller);
6151                if (r == null) {
6152                    throw new SecurityException(
6153                            "Unable to find app for caller " + caller
6154                          + " (pid=" + Binder.getCallingPid()
6155                          + ") when getting content provider " + name);
6156                }
6157            }
6158
6159            // First check if this content provider has been published...
6160            int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid());
6161            cpr = mProviderMap.getProviderByName(name, userId);
6162            boolean providerRunning = cpr != null;
6163            if (providerRunning) {
6164                cpi = cpr.info;
6165                String msg;
6166                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6167                    throw new SecurityException(msg);
6168                }
6169
6170                if (r != null && cpr.canRunHere(r)) {
6171                    // This provider has been published or is in the process
6172                    // of being published...  but it is also allowed to run
6173                    // in the caller's process, so don't make a connection
6174                    // and just let the caller instantiate its own instance.
6175                    ContentProviderHolder holder = cpr.newHolder(null);
6176                    // don't give caller the provider object, it needs
6177                    // to make its own.
6178                    holder.provider = null;
6179                    return holder;
6180                }
6181
6182                final long origId = Binder.clearCallingIdentity();
6183
6184                // In this case the provider instance already exists, so we can
6185                // return it right away.
6186                conn = incProviderCountLocked(r, cpr, token, stable);
6187                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6188                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6189                        // If this is a perceptible app accessing the provider,
6190                        // make sure to count it as being accessed and thus
6191                        // back up on the LRU list.  This is good because
6192                        // content providers are often expensive to start.
6193                        updateLruProcessLocked(cpr.proc, false, true);
6194                    }
6195                }
6196
6197                if (cpr.proc != null) {
6198                    if (false) {
6199                        if (cpr.name.flattenToShortString().equals(
6200                                "com.android.providers.calendar/.CalendarProvider2")) {
6201                            Slog.v(TAG, "****************** KILLING "
6202                                + cpr.name.flattenToShortString());
6203                            Process.killProcess(cpr.proc.pid);
6204                        }
6205                    }
6206                    boolean success = updateOomAdjLocked(cpr.proc);
6207                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6208                    // NOTE: there is still a race here where a signal could be
6209                    // pending on the process even though we managed to update its
6210                    // adj level.  Not sure what to do about this, but at least
6211                    // the race is now smaller.
6212                    if (!success) {
6213                        // Uh oh...  it looks like the provider's process
6214                        // has been killed on us.  We need to wait for a new
6215                        // process to be started, and make sure its death
6216                        // doesn't kill our process.
6217                        Slog.i(TAG,
6218                                "Existing provider " + cpr.name.flattenToShortString()
6219                                + " is crashing; detaching " + r);
6220                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6221                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6222                        if (!lastRef) {
6223                            // This wasn't the last ref our process had on
6224                            // the provider...  we have now been killed, bail.
6225                            return null;
6226                        }
6227                        providerRunning = false;
6228                        conn = null;
6229                    }
6230                }
6231
6232                Binder.restoreCallingIdentity(origId);
6233            }
6234
6235            boolean singleton;
6236            if (!providerRunning) {
6237                try {
6238                    cpi = AppGlobals.getPackageManager().
6239                        resolveContentProvider(name,
6240                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6241                } catch (RemoteException ex) {
6242                }
6243                if (cpi == null) {
6244                    return null;
6245                }
6246                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6247                        cpi.name, cpi.flags);
6248                if (singleton) {
6249                    userId = 0;
6250                }
6251                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6252
6253                String msg;
6254                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6255                    throw new SecurityException(msg);
6256                }
6257
6258                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6259                        && !cpi.processName.equals("system")) {
6260                    // If this content provider does not run in the system
6261                    // process, and the system is not yet ready to run other
6262                    // processes, then fail fast instead of hanging.
6263                    throw new IllegalArgumentException(
6264                            "Attempt to launch content provider before system ready");
6265                }
6266
6267                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6268                cpr = mProviderMap.getProviderByClass(comp, userId);
6269                final boolean firstClass = cpr == null;
6270                if (firstClass) {
6271                    try {
6272                        ApplicationInfo ai =
6273                            AppGlobals.getPackageManager().
6274                                getApplicationInfo(
6275                                        cpi.applicationInfo.packageName,
6276                                        STOCK_PM_FLAGS, userId);
6277                        if (ai == null) {
6278                            Slog.w(TAG, "No package info for content provider "
6279                                    + cpi.name);
6280                            return null;
6281                        }
6282                        ai = getAppInfoForUser(ai, userId);
6283                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6284                    } catch (RemoteException ex) {
6285                        // pm is in same process, this will never happen.
6286                    }
6287                }
6288
6289                if (r != null && cpr.canRunHere(r)) {
6290                    // If this is a multiprocess provider, then just return its
6291                    // info and allow the caller to instantiate it.  Only do
6292                    // this if the provider is the same user as the caller's
6293                    // process, or can run as root (so can be in any process).
6294                    return cpr.newHolder(null);
6295                }
6296
6297                if (DEBUG_PROVIDER) {
6298                    RuntimeException e = new RuntimeException("here");
6299                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6300                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6301                }
6302
6303                // This is single process, and our app is now connecting to it.
6304                // See if we are already in the process of launching this
6305                // provider.
6306                final int N = mLaunchingProviders.size();
6307                int i;
6308                for (i=0; i<N; i++) {
6309                    if (mLaunchingProviders.get(i) == cpr) {
6310                        break;
6311                    }
6312                }
6313
6314                // If the provider is not already being launched, then get it
6315                // started.
6316                if (i >= N) {
6317                    final long origId = Binder.clearCallingIdentity();
6318
6319                    try {
6320                        // Content provider is now in use, its package can't be stopped.
6321                        try {
6322                            AppGlobals.getPackageManager().setPackageStoppedState(
6323                                    cpr.appInfo.packageName, false, userId);
6324                        } catch (RemoteException e) {
6325                        } catch (IllegalArgumentException e) {
6326                            Slog.w(TAG, "Failed trying to unstop package "
6327                                    + cpr.appInfo.packageName + ": " + e);
6328                        }
6329
6330                        ProcessRecord proc = startProcessLocked(cpi.processName,
6331                                cpr.appInfo, false, 0, "content provider",
6332                                new ComponentName(cpi.applicationInfo.packageName,
6333                                        cpi.name), false, false);
6334                        if (proc == null) {
6335                            Slog.w(TAG, "Unable to launch app "
6336                                    + cpi.applicationInfo.packageName + "/"
6337                                    + cpi.applicationInfo.uid + " for provider "
6338                                    + name + ": process is bad");
6339                            return null;
6340                        }
6341                        cpr.launchingApp = proc;
6342                        mLaunchingProviders.add(cpr);
6343                    } finally {
6344                        Binder.restoreCallingIdentity(origId);
6345                    }
6346                }
6347
6348                // Make sure the provider is published (the same provider class
6349                // may be published under multiple names).
6350                if (firstClass) {
6351                    mProviderMap.putProviderByClass(comp, cpr);
6352                }
6353
6354                mProviderMap.putProviderByName(name, cpr);
6355                conn = incProviderCountLocked(r, cpr, token, stable);
6356                if (conn != null) {
6357                    conn.waiting = true;
6358                }
6359            }
6360        }
6361
6362        // Wait for the provider to be published...
6363        synchronized (cpr) {
6364            while (cpr.provider == null) {
6365                if (cpr.launchingApp == null) {
6366                    Slog.w(TAG, "Unable to launch app "
6367                            + cpi.applicationInfo.packageName + "/"
6368                            + cpi.applicationInfo.uid + " for provider "
6369                            + name + ": launching app became null");
6370                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6371                            cpi.applicationInfo.packageName,
6372                            cpi.applicationInfo.uid, name);
6373                    return null;
6374                }
6375                try {
6376                    if (DEBUG_MU) {
6377                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6378                                + cpr.launchingApp);
6379                    }
6380                    if (conn != null) {
6381                        conn.waiting = true;
6382                    }
6383                    cpr.wait();
6384                } catch (InterruptedException ex) {
6385                } finally {
6386                    if (conn != null) {
6387                        conn.waiting = false;
6388                    }
6389                }
6390            }
6391        }
6392        return cpr != null ? cpr.newHolder(conn) : null;
6393    }
6394
6395    public final ContentProviderHolder getContentProvider(
6396            IApplicationThread caller, String name, boolean stable) {
6397        enforceNotIsolatedCaller("getContentProvider");
6398        if (caller == null) {
6399            String msg = "null IApplicationThread when getting content provider "
6400                    + name;
6401            Slog.w(TAG, msg);
6402            throw new SecurityException(msg);
6403        }
6404
6405        return getContentProviderImpl(caller, name, null, stable);
6406    }
6407
6408    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6409        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6410            "Do not have permission in call getContentProviderExternal()");
6411        return getContentProviderExternalUnchecked(name, token);
6412    }
6413
6414    private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
6415        return getContentProviderImpl(null, name, token, true);
6416    }
6417
6418    /**
6419     * Drop a content provider from a ProcessRecord's bookkeeping
6420     * @param cpr
6421     */
6422    public void removeContentProvider(IBinder connection, boolean stable) {
6423        enforceNotIsolatedCaller("removeContentProvider");
6424        synchronized (this) {
6425            ContentProviderConnection conn;
6426            try {
6427                conn = (ContentProviderConnection)connection;
6428            } catch (ClassCastException e) {
6429                String msg ="removeContentProvider: " + connection
6430                        + " not a ContentProviderConnection";
6431                Slog.w(TAG, msg);
6432                throw new IllegalArgumentException(msg);
6433            }
6434            if (conn == null) {
6435                throw new NullPointerException("connection is null");
6436            }
6437            if (decProviderCountLocked(conn, null, null, stable)) {
6438                updateOomAdjLocked();
6439            }
6440        }
6441    }
6442
6443    public void removeContentProviderExternal(String name, IBinder token) {
6444        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6445            "Do not have permission in call removeContentProviderExternal()");
6446        removeContentProviderExternalUnchecked(name, token);
6447    }
6448
6449    private void removeContentProviderExternalUnchecked(String name, IBinder token) {
6450        synchronized (this) {
6451            ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6452                    Binder.getOrigCallingUser());
6453            if(cpr == null) {
6454                //remove from mProvidersByClass
6455                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6456                return;
6457            }
6458
6459            //update content provider record entry info
6460            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6461            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6462                    Binder.getOrigCallingUser());
6463            if (localCpr.hasExternalProcessHandles()) {
6464                if (localCpr.removeExternalProcessHandleLocked(token)) {
6465                    updateOomAdjLocked();
6466                } else {
6467                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6468                            + " with no external reference for token: "
6469                            + token + ".");
6470                }
6471            } else {
6472                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6473                        + " with no external references.");
6474            }
6475        }
6476    }
6477
6478    public final void publishContentProviders(IApplicationThread caller,
6479            List<ContentProviderHolder> providers) {
6480        if (providers == null) {
6481            return;
6482        }
6483
6484        enforceNotIsolatedCaller("publishContentProviders");
6485        synchronized (this) {
6486            final ProcessRecord r = getRecordForAppLocked(caller);
6487            if (DEBUG_MU)
6488                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6489            if (r == null) {
6490                throw new SecurityException(
6491                        "Unable to find app for caller " + caller
6492                      + " (pid=" + Binder.getCallingPid()
6493                      + ") when publishing content providers");
6494            }
6495
6496            final long origId = Binder.clearCallingIdentity();
6497
6498            final int N = providers.size();
6499            for (int i=0; i<N; i++) {
6500                ContentProviderHolder src = providers.get(i);
6501                if (src == null || src.info == null || src.provider == null) {
6502                    continue;
6503                }
6504                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6505                if (DEBUG_MU)
6506                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6507                if (dst != null) {
6508                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6509                    mProviderMap.putProviderByClass(comp, dst);
6510                    String names[] = dst.info.authority.split(";");
6511                    for (int j = 0; j < names.length; j++) {
6512                        mProviderMap.putProviderByName(names[j], dst);
6513                    }
6514
6515                    int NL = mLaunchingProviders.size();
6516                    int j;
6517                    for (j=0; j<NL; j++) {
6518                        if (mLaunchingProviders.get(j) == dst) {
6519                            mLaunchingProviders.remove(j);
6520                            j--;
6521                            NL--;
6522                        }
6523                    }
6524                    synchronized (dst) {
6525                        dst.provider = src.provider;
6526                        dst.proc = r;
6527                        dst.notifyAll();
6528                    }
6529                    updateOomAdjLocked(r);
6530                }
6531            }
6532
6533            Binder.restoreCallingIdentity(origId);
6534        }
6535    }
6536
6537    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6538        ContentProviderConnection conn;
6539        try {
6540            conn = (ContentProviderConnection)connection;
6541        } catch (ClassCastException e) {
6542            String msg ="refContentProvider: " + connection
6543                    + " not a ContentProviderConnection";
6544            Slog.w(TAG, msg);
6545            throw new IllegalArgumentException(msg);
6546        }
6547        if (conn == null) {
6548            throw new NullPointerException("connection is null");
6549        }
6550
6551        synchronized (this) {
6552            if (stable > 0) {
6553                conn.numStableIncs += stable;
6554            }
6555            stable = conn.stableCount + stable;
6556            if (stable < 0) {
6557                throw new IllegalStateException("stableCount < 0: " + stable);
6558            }
6559
6560            if (unstable > 0) {
6561                conn.numUnstableIncs += unstable;
6562            }
6563            unstable = conn.unstableCount + unstable;
6564            if (unstable < 0) {
6565                throw new IllegalStateException("unstableCount < 0: " + unstable);
6566            }
6567
6568            if ((stable+unstable) <= 0) {
6569                throw new IllegalStateException("ref counts can't go to zero here: stable="
6570                        + stable + " unstable=" + unstable);
6571            }
6572            conn.stableCount = stable;
6573            conn.unstableCount = unstable;
6574            return !conn.dead;
6575        }
6576    }
6577
6578    public void unstableProviderDied(IBinder connection) {
6579        ContentProviderConnection conn;
6580        try {
6581            conn = (ContentProviderConnection)connection;
6582        } catch (ClassCastException e) {
6583            String msg ="refContentProvider: " + connection
6584                    + " not a ContentProviderConnection";
6585            Slog.w(TAG, msg);
6586            throw new IllegalArgumentException(msg);
6587        }
6588        if (conn == null) {
6589            throw new NullPointerException("connection is null");
6590        }
6591
6592        // Safely retrieve the content provider associated with the connection.
6593        IContentProvider provider;
6594        synchronized (this) {
6595            provider = conn.provider.provider;
6596        }
6597
6598        if (provider == null) {
6599            // Um, yeah, we're way ahead of you.
6600            return;
6601        }
6602
6603        // Make sure the caller is being honest with us.
6604        if (provider.asBinder().pingBinder()) {
6605            // Er, no, still looks good to us.
6606            synchronized (this) {
6607                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6608                        + " says " + conn + " died, but we don't agree");
6609                return;
6610            }
6611        }
6612
6613        // Well look at that!  It's dead!
6614        synchronized (this) {
6615            if (conn.provider.provider != provider) {
6616                // But something changed...  good enough.
6617                return;
6618            }
6619
6620            ProcessRecord proc = conn.provider.proc;
6621            if (proc == null || proc.thread == null) {
6622                // Seems like the process is already cleaned up.
6623                return;
6624            }
6625
6626            // As far as we're concerned, this is just like receiving a
6627            // death notification...  just a bit prematurely.
6628            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6629                    + ") early provider death");
6630            final long ident = Binder.clearCallingIdentity();
6631            try {
6632                appDiedLocked(proc, proc.pid, proc.thread);
6633            } finally {
6634                Binder.restoreCallingIdentity(ident);
6635            }
6636        }
6637    }
6638
6639    public static final void installSystemProviders() {
6640        List<ProviderInfo> providers;
6641        synchronized (mSelf) {
6642            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6643            providers = mSelf.generateApplicationProvidersLocked(app);
6644            if (providers != null) {
6645                for (int i=providers.size()-1; i>=0; i--) {
6646                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6647                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6648                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6649                                + ": not system .apk");
6650                        providers.remove(i);
6651                    }
6652                }
6653            }
6654        }
6655        if (providers != null) {
6656            mSystemThread.installSystemProviders(providers);
6657        }
6658
6659        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6660
6661        mSelf.mUsageStatsService.monitorPackages();
6662    }
6663
6664    /**
6665     * Allows app to retrieve the MIME type of a URI without having permission
6666     * to access its content provider.
6667     *
6668     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6669     *
6670     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6671     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6672     */
6673    public String getProviderMimeType(Uri uri) {
6674        enforceNotIsolatedCaller("getProviderMimeType");
6675        final String name = uri.getAuthority();
6676        final long ident = Binder.clearCallingIdentity();
6677        ContentProviderHolder holder = null;
6678
6679        try {
6680            holder = getContentProviderExternalUnchecked(name, null);
6681            if (holder != null) {
6682                return holder.provider.getType(uri);
6683            }
6684        } catch (RemoteException e) {
6685            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6686            return null;
6687        } finally {
6688            if (holder != null) {
6689                removeContentProviderExternalUnchecked(name, null);
6690            }
6691            Binder.restoreCallingIdentity(ident);
6692        }
6693
6694        return null;
6695    }
6696
6697    // =========================================================
6698    // GLOBAL MANAGEMENT
6699    // =========================================================
6700
6701    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6702            ApplicationInfo info, String customProcess, boolean isolated) {
6703        String proc = customProcess != null ? customProcess : info.processName;
6704        BatteryStatsImpl.Uid.Proc ps = null;
6705        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6706        int uid = info.uid;
6707        if (isolated) {
6708            int userId = UserId.getUserId(uid);
6709            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6710            uid = 0;
6711            while (true) {
6712                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6713                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6714                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6715                }
6716                uid = UserId.getUid(userId, mNextIsolatedProcessUid);
6717                mNextIsolatedProcessUid++;
6718                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6719                    // No process for this uid, use it.
6720                    break;
6721                }
6722                stepsLeft--;
6723                if (stepsLeft <= 0) {
6724                    return null;
6725                }
6726            }
6727        }
6728        synchronized (stats) {
6729            ps = stats.getProcessStatsLocked(info.uid, proc);
6730        }
6731        return new ProcessRecord(ps, thread, info, proc, uid);
6732    }
6733
6734    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6735        ProcessRecord app;
6736        if (!isolated) {
6737            app = getProcessRecordLocked(info.processName, info.uid);
6738        } else {
6739            app = null;
6740        }
6741
6742        if (app == null) {
6743            app = newProcessRecordLocked(null, info, null, isolated);
6744            mProcessNames.put(info.processName, app.uid, app);
6745            if (isolated) {
6746                mIsolatedProcesses.put(app.uid, app);
6747            }
6748            updateLruProcessLocked(app, true, true);
6749        }
6750
6751        // This package really, really can not be stopped.
6752        try {
6753            AppGlobals.getPackageManager().setPackageStoppedState(
6754                    info.packageName, false, UserId.getUserId(app.uid));
6755        } catch (RemoteException e) {
6756        } catch (IllegalArgumentException e) {
6757            Slog.w(TAG, "Failed trying to unstop package "
6758                    + info.packageName + ": " + e);
6759        }
6760
6761        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6762                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6763            app.persistent = true;
6764            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6765        }
6766        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6767            mPersistentStartingProcesses.add(app);
6768            startProcessLocked(app, "added application", app.processName);
6769        }
6770
6771        return app;
6772    }
6773
6774    public void unhandledBack() {
6775        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6776                "unhandledBack()");
6777
6778        synchronized(this) {
6779            int count = mMainStack.mHistory.size();
6780            if (DEBUG_SWITCH) Slog.d(
6781                TAG, "Performing unhandledBack(): stack size = " + count);
6782            if (count > 1) {
6783                final long origId = Binder.clearCallingIdentity();
6784                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6785                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6786                Binder.restoreCallingIdentity(origId);
6787            }
6788        }
6789    }
6790
6791    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6792        enforceNotIsolatedCaller("openContentUri");
6793        String name = uri.getAuthority();
6794        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
6795        ParcelFileDescriptor pfd = null;
6796        if (cph != null) {
6797            // We record the binder invoker's uid in thread-local storage before
6798            // going to the content provider to open the file.  Later, in the code
6799            // that handles all permissions checks, we look for this uid and use
6800            // that rather than the Activity Manager's own uid.  The effect is that
6801            // we do the check against the caller's permissions even though it looks
6802            // to the content provider like the Activity Manager itself is making
6803            // the request.
6804            sCallerIdentity.set(new Identity(
6805                    Binder.getCallingPid(), Binder.getCallingUid()));
6806            try {
6807                pfd = cph.provider.openFile(uri, "r");
6808            } catch (FileNotFoundException e) {
6809                // do nothing; pfd will be returned null
6810            } finally {
6811                // Ensure that whatever happens, we clean up the identity state
6812                sCallerIdentity.remove();
6813            }
6814
6815            // We've got the fd now, so we're done with the provider.
6816            removeContentProviderExternalUnchecked(name, null);
6817        } else {
6818            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6819        }
6820        return pfd;
6821    }
6822
6823    // Actually is sleeping or shutting down or whatever else in the future
6824    // is an inactive state.
6825    public boolean isSleeping() {
6826        return mSleeping || mShuttingDown;
6827    }
6828
6829    public void goingToSleep() {
6830        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6831                != PackageManager.PERMISSION_GRANTED) {
6832            throw new SecurityException("Requires permission "
6833                    + android.Manifest.permission.DEVICE_POWER);
6834        }
6835
6836        synchronized(this) {
6837            mWentToSleep = true;
6838            updateEventDispatchingLocked();
6839
6840            if (!mSleeping) {
6841                mSleeping = true;
6842                mMainStack.stopIfSleepingLocked();
6843
6844                // Initialize the wake times of all processes.
6845                checkExcessivePowerUsageLocked(false);
6846                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6847                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6848                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6849            }
6850        }
6851    }
6852
6853    public boolean shutdown(int timeout) {
6854        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6855                != PackageManager.PERMISSION_GRANTED) {
6856            throw new SecurityException("Requires permission "
6857                    + android.Manifest.permission.SHUTDOWN);
6858        }
6859
6860        boolean timedout = false;
6861
6862        synchronized(this) {
6863            mShuttingDown = true;
6864            updateEventDispatchingLocked();
6865
6866            if (mMainStack.mResumedActivity != null) {
6867                mMainStack.stopIfSleepingLocked();
6868                final long endTime = System.currentTimeMillis() + timeout;
6869                while (mMainStack.mResumedActivity != null
6870                        || mMainStack.mPausingActivity != null) {
6871                    long delay = endTime - System.currentTimeMillis();
6872                    if (delay <= 0) {
6873                        Slog.w(TAG, "Activity manager shutdown timed out");
6874                        timedout = true;
6875                        break;
6876                    }
6877                    try {
6878                        this.wait();
6879                    } catch (InterruptedException e) {
6880                    }
6881                }
6882            }
6883        }
6884
6885        mUsageStatsService.shutdown();
6886        mBatteryStatsService.shutdown();
6887
6888        return timedout;
6889    }
6890
6891    public final void activitySlept(IBinder token) {
6892        if (localLOGV) Slog.v(
6893            TAG, "Activity slept: token=" + token);
6894
6895        ActivityRecord r = null;
6896
6897        final long origId = Binder.clearCallingIdentity();
6898
6899        synchronized (this) {
6900            r = mMainStack.isInStackLocked(token);
6901            if (r != null) {
6902                mMainStack.activitySleptLocked(r);
6903            }
6904        }
6905
6906        Binder.restoreCallingIdentity(origId);
6907    }
6908
6909    private void comeOutOfSleepIfNeededLocked() {
6910        if (!mWentToSleep && !mLockScreenShown) {
6911            if (mSleeping) {
6912                mSleeping = false;
6913                mMainStack.awakeFromSleepingLocked();
6914                mMainStack.resumeTopActivityLocked(null);
6915            }
6916        }
6917    }
6918
6919    public void wakingUp() {
6920        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6921                != PackageManager.PERMISSION_GRANTED) {
6922            throw new SecurityException("Requires permission "
6923                    + android.Manifest.permission.DEVICE_POWER);
6924        }
6925
6926        synchronized(this) {
6927            mWentToSleep = false;
6928            updateEventDispatchingLocked();
6929            comeOutOfSleepIfNeededLocked();
6930        }
6931    }
6932
6933    private void updateEventDispatchingLocked() {
6934        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
6935    }
6936
6937    public void setLockScreenShown(boolean shown) {
6938        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6939                != PackageManager.PERMISSION_GRANTED) {
6940            throw new SecurityException("Requires permission "
6941                    + android.Manifest.permission.DEVICE_POWER);
6942        }
6943
6944        synchronized(this) {
6945            mLockScreenShown = shown;
6946            comeOutOfSleepIfNeededLocked();
6947        }
6948    }
6949
6950    public void stopAppSwitches() {
6951        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6952                != PackageManager.PERMISSION_GRANTED) {
6953            throw new SecurityException("Requires permission "
6954                    + android.Manifest.permission.STOP_APP_SWITCHES);
6955        }
6956
6957        synchronized(this) {
6958            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6959                    + APP_SWITCH_DELAY_TIME;
6960            mDidAppSwitch = false;
6961            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6962            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6963            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6964        }
6965    }
6966
6967    public void resumeAppSwitches() {
6968        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6969                != PackageManager.PERMISSION_GRANTED) {
6970            throw new SecurityException("Requires permission "
6971                    + android.Manifest.permission.STOP_APP_SWITCHES);
6972        }
6973
6974        synchronized(this) {
6975            // Note that we don't execute any pending app switches... we will
6976            // let those wait until either the timeout, or the next start
6977            // activity request.
6978            mAppSwitchesAllowedTime = 0;
6979        }
6980    }
6981
6982    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6983            String name) {
6984        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6985            return true;
6986        }
6987
6988        final int perm = checkComponentPermission(
6989                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
6990                callingUid, -1, true);
6991        if (perm == PackageManager.PERMISSION_GRANTED) {
6992            return true;
6993        }
6994
6995        Slog.w(TAG, name + " request from " + callingUid + " stopped");
6996        return false;
6997    }
6998
6999    public void setDebugApp(String packageName, boolean waitForDebugger,
7000            boolean persistent) {
7001        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7002                "setDebugApp()");
7003
7004        // Note that this is not really thread safe if there are multiple
7005        // callers into it at the same time, but that's not a situation we
7006        // care about.
7007        if (persistent) {
7008            final ContentResolver resolver = mContext.getContentResolver();
7009            Settings.System.putString(
7010                resolver, Settings.System.DEBUG_APP,
7011                packageName);
7012            Settings.System.putInt(
7013                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7014                waitForDebugger ? 1 : 0);
7015        }
7016
7017        synchronized (this) {
7018            if (!persistent) {
7019                mOrigDebugApp = mDebugApp;
7020                mOrigWaitForDebugger = mWaitForDebugger;
7021            }
7022            mDebugApp = packageName;
7023            mWaitForDebugger = waitForDebugger;
7024            mDebugTransient = !persistent;
7025            if (packageName != null) {
7026                final long origId = Binder.clearCallingIdentity();
7027                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
7028                Binder.restoreCallingIdentity(origId);
7029            }
7030        }
7031    }
7032
7033    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7034        synchronized (this) {
7035            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7036            if (!isDebuggable) {
7037                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7038                    throw new SecurityException("Process not debuggable: " + app.packageName);
7039                }
7040            }
7041
7042            mOpenGlTraceApp = processName;
7043        }
7044    }
7045
7046    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7047            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7048        synchronized (this) {
7049            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7050            if (!isDebuggable) {
7051                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7052                    throw new SecurityException("Process not debuggable: " + app.packageName);
7053                }
7054            }
7055            mProfileApp = processName;
7056            mProfileFile = profileFile;
7057            if (mProfileFd != null) {
7058                try {
7059                    mProfileFd.close();
7060                } catch (IOException e) {
7061                }
7062                mProfileFd = null;
7063            }
7064            mProfileFd = profileFd;
7065            mProfileType = 0;
7066            mAutoStopProfiler = autoStopProfiler;
7067        }
7068    }
7069
7070    public void setAlwaysFinish(boolean enabled) {
7071        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7072                "setAlwaysFinish()");
7073
7074        Settings.System.putInt(
7075                mContext.getContentResolver(),
7076                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7077
7078        synchronized (this) {
7079            mAlwaysFinishActivities = enabled;
7080        }
7081    }
7082
7083    public void setActivityController(IActivityController controller) {
7084        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7085                "setActivityController()");
7086        synchronized (this) {
7087            mController = controller;
7088        }
7089    }
7090
7091    public boolean isUserAMonkey() {
7092        // For now the fact that there is a controller implies
7093        // we have a monkey.
7094        synchronized (this) {
7095            return mController != null;
7096        }
7097    }
7098
7099    public void registerProcessObserver(IProcessObserver observer) {
7100        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7101                "registerProcessObserver()");
7102        synchronized (this) {
7103            mProcessObservers.register(observer);
7104        }
7105    }
7106
7107    public void unregisterProcessObserver(IProcessObserver observer) {
7108        synchronized (this) {
7109            mProcessObservers.unregister(observer);
7110        }
7111    }
7112
7113    public void setImmersive(IBinder token, boolean immersive) {
7114        synchronized(this) {
7115            ActivityRecord r = mMainStack.isInStackLocked(token);
7116            if (r == null) {
7117                throw new IllegalArgumentException();
7118            }
7119            r.immersive = immersive;
7120        }
7121    }
7122
7123    public boolean isImmersive(IBinder token) {
7124        synchronized (this) {
7125            ActivityRecord r = mMainStack.isInStackLocked(token);
7126            if (r == null) {
7127                throw new IllegalArgumentException();
7128            }
7129            return r.immersive;
7130        }
7131    }
7132
7133    public boolean isTopActivityImmersive() {
7134        enforceNotIsolatedCaller("startActivity");
7135        synchronized (this) {
7136            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7137            return (r != null) ? r.immersive : false;
7138        }
7139    }
7140
7141    public final void enterSafeMode() {
7142        synchronized(this) {
7143            // It only makes sense to do this before the system is ready
7144            // and started launching other packages.
7145            if (!mSystemReady) {
7146                try {
7147                    AppGlobals.getPackageManager().enterSafeMode();
7148                } catch (RemoteException e) {
7149                }
7150            }
7151        }
7152    }
7153
7154    public final void showSafeModeOverlay() {
7155        View v = LayoutInflater.from(mContext).inflate(
7156                com.android.internal.R.layout.safe_mode, null);
7157        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7158        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7159        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7160        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7161        lp.gravity = Gravity.BOTTOM | Gravity.START;
7162        lp.format = v.getBackground().getOpacity();
7163        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7164                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7165        ((WindowManager)mContext.getSystemService(
7166                Context.WINDOW_SERVICE)).addView(v, lp);
7167    }
7168
7169    public void noteWakeupAlarm(IIntentSender sender) {
7170        if (!(sender instanceof PendingIntentRecord)) {
7171            return;
7172        }
7173        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7174        synchronized (stats) {
7175            if (mBatteryStatsService.isOnBattery()) {
7176                mBatteryStatsService.enforceCallingPermission();
7177                PendingIntentRecord rec = (PendingIntentRecord)sender;
7178                int MY_UID = Binder.getCallingUid();
7179                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7180                BatteryStatsImpl.Uid.Pkg pkg =
7181                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7182                pkg.incWakeupsLocked();
7183            }
7184        }
7185    }
7186
7187    public boolean killPids(int[] pids, String pReason, boolean secure) {
7188        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7189            throw new SecurityException("killPids only available to the system");
7190        }
7191        String reason = (pReason == null) ? "Unknown" : pReason;
7192        // XXX Note: don't acquire main activity lock here, because the window
7193        // manager calls in with its locks held.
7194
7195        boolean killed = false;
7196        synchronized (mPidsSelfLocked) {
7197            int[] types = new int[pids.length];
7198            int worstType = 0;
7199            for (int i=0; i<pids.length; i++) {
7200                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7201                if (proc != null) {
7202                    int type = proc.setAdj;
7203                    types[i] = type;
7204                    if (type > worstType) {
7205                        worstType = type;
7206                    }
7207                }
7208            }
7209
7210            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7211            // then constrain it so we will kill all hidden procs.
7212            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7213                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7214                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7215            }
7216
7217            // If this is not a secure call, don't let it kill processes that
7218            // are important.
7219            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7220                worstType = ProcessList.SERVICE_ADJ;
7221            }
7222
7223            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7224            for (int i=0; i<pids.length; i++) {
7225                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7226                if (proc == null) {
7227                    continue;
7228                }
7229                int adj = proc.setAdj;
7230                if (adj >= worstType && !proc.killedBackground) {
7231                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7232                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7233                            proc.processName, adj, reason);
7234                    killed = true;
7235                    proc.killedBackground = true;
7236                    Process.killProcessQuiet(pids[i]);
7237                }
7238            }
7239        }
7240        return killed;
7241    }
7242
7243    @Override
7244    public boolean killProcessesBelowForeground(String reason) {
7245        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7246            throw new SecurityException("killProcessesBelowForeground() only available to system");
7247        }
7248
7249        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7250    }
7251
7252    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7253        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7254            throw new SecurityException("killProcessesBelowAdj() only available to system");
7255        }
7256
7257        boolean killed = false;
7258        synchronized (mPidsSelfLocked) {
7259            final int size = mPidsSelfLocked.size();
7260            for (int i = 0; i < size; i++) {
7261                final int pid = mPidsSelfLocked.keyAt(i);
7262                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7263                if (proc == null) continue;
7264
7265                final int adj = proc.setAdj;
7266                if (adj > belowAdj && !proc.killedBackground) {
7267                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7268                    EventLog.writeEvent(
7269                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7270                    killed = true;
7271                    proc.killedBackground = true;
7272                    Process.killProcessQuiet(pid);
7273                }
7274            }
7275        }
7276        return killed;
7277    }
7278
7279    public final void startRunning(String pkg, String cls, String action,
7280            String data) {
7281        synchronized(this) {
7282            if (mStartRunning) {
7283                return;
7284            }
7285            mStartRunning = true;
7286            mTopComponent = pkg != null && cls != null
7287                    ? new ComponentName(pkg, cls) : null;
7288            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7289            mTopData = data;
7290            if (!mSystemReady) {
7291                return;
7292            }
7293        }
7294
7295        systemReady(null);
7296    }
7297
7298    private void retrieveSettings() {
7299        final ContentResolver resolver = mContext.getContentResolver();
7300        String debugApp = Settings.System.getString(
7301            resolver, Settings.System.DEBUG_APP);
7302        boolean waitForDebugger = Settings.System.getInt(
7303            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7304        boolean alwaysFinishActivities = Settings.System.getInt(
7305            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7306
7307        Configuration configuration = new Configuration();
7308        Settings.System.getConfiguration(resolver, configuration);
7309
7310        synchronized (this) {
7311            mDebugApp = mOrigDebugApp = debugApp;
7312            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7313            mAlwaysFinishActivities = alwaysFinishActivities;
7314            // This happens before any activities are started, so we can
7315            // change mConfiguration in-place.
7316            updateConfigurationLocked(configuration, null, false, true);
7317            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7318        }
7319    }
7320
7321    public boolean testIsSystemReady() {
7322        // no need to synchronize(this) just to read & return the value
7323        return mSystemReady;
7324    }
7325
7326    private static File getCalledPreBootReceiversFile() {
7327        File dataDir = Environment.getDataDirectory();
7328        File systemDir = new File(dataDir, "system");
7329        File fname = new File(systemDir, "called_pre_boots.dat");
7330        return fname;
7331    }
7332
7333    static final int LAST_DONE_VERSION = 10000;
7334
7335    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7336        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7337        File file = getCalledPreBootReceiversFile();
7338        FileInputStream fis = null;
7339        try {
7340            fis = new FileInputStream(file);
7341            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7342            int fvers = dis.readInt();
7343            if (fvers == LAST_DONE_VERSION) {
7344                String vers = dis.readUTF();
7345                String codename = dis.readUTF();
7346                String build = dis.readUTF();
7347                if (android.os.Build.VERSION.RELEASE.equals(vers)
7348                        && android.os.Build.VERSION.CODENAME.equals(codename)
7349                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7350                    int num = dis.readInt();
7351                    while (num > 0) {
7352                        num--;
7353                        String pkg = dis.readUTF();
7354                        String cls = dis.readUTF();
7355                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7356                    }
7357                }
7358            }
7359        } catch (FileNotFoundException e) {
7360        } catch (IOException e) {
7361            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7362        } finally {
7363            if (fis != null) {
7364                try {
7365                    fis.close();
7366                } catch (IOException e) {
7367                }
7368            }
7369        }
7370        return lastDoneReceivers;
7371    }
7372
7373    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7374        File file = getCalledPreBootReceiversFile();
7375        FileOutputStream fos = null;
7376        DataOutputStream dos = null;
7377        try {
7378            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7379            fos = new FileOutputStream(file);
7380            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7381            dos.writeInt(LAST_DONE_VERSION);
7382            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7383            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7384            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7385            dos.writeInt(list.size());
7386            for (int i=0; i<list.size(); i++) {
7387                dos.writeUTF(list.get(i).getPackageName());
7388                dos.writeUTF(list.get(i).getClassName());
7389            }
7390        } catch (IOException e) {
7391            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7392            file.delete();
7393        } finally {
7394            FileUtils.sync(fos);
7395            if (dos != null) {
7396                try {
7397                    dos.close();
7398                } catch (IOException e) {
7399                    // TODO Auto-generated catch block
7400                    e.printStackTrace();
7401                }
7402            }
7403        }
7404    }
7405
7406    public void systemReady(final Runnable goingCallback) {
7407        synchronized(this) {
7408            if (mSystemReady) {
7409                if (goingCallback != null) goingCallback.run();
7410                return;
7411            }
7412
7413            // Check to see if there are any update receivers to run.
7414            if (!mDidUpdate) {
7415                if (mWaitingUpdate) {
7416                    return;
7417                }
7418                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7419                List<ResolveInfo> ris = null;
7420                try {
7421                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7422                            intent, null, 0, 0);
7423                } catch (RemoteException e) {
7424                }
7425                if (ris != null) {
7426                    for (int i=ris.size()-1; i>=0; i--) {
7427                        if ((ris.get(i).activityInfo.applicationInfo.flags
7428                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7429                            ris.remove(i);
7430                        }
7431                    }
7432                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7433
7434                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7435
7436                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7437                    for (int i=0; i<ris.size(); i++) {
7438                        ActivityInfo ai = ris.get(i).activityInfo;
7439                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7440                        if (lastDoneReceivers.contains(comp)) {
7441                            ris.remove(i);
7442                            i--;
7443                        }
7444                    }
7445
7446                    for (int i=0; i<ris.size(); i++) {
7447                        ActivityInfo ai = ris.get(i).activityInfo;
7448                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7449                        doneReceivers.add(comp);
7450                        intent.setComponent(comp);
7451                        IIntentReceiver finisher = null;
7452                        if (i == ris.size()-1) {
7453                            finisher = new IIntentReceiver.Stub() {
7454                                public void performReceive(Intent intent, int resultCode,
7455                                        String data, Bundle extras, boolean ordered,
7456                                        boolean sticky) {
7457                                    // The raw IIntentReceiver interface is called
7458                                    // with the AM lock held, so redispatch to
7459                                    // execute our code without the lock.
7460                                    mHandler.post(new Runnable() {
7461                                        public void run() {
7462                                            synchronized (ActivityManagerService.this) {
7463                                                mDidUpdate = true;
7464                                            }
7465                                            writeLastDonePreBootReceivers(doneReceivers);
7466                                            showBootMessage(mContext.getText(
7467                                                    R.string.android_upgrading_complete),
7468                                                    false);
7469                                            systemReady(goingCallback);
7470                                        }
7471                                    });
7472                                }
7473                            };
7474                        }
7475                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7476                        /* TODO: Send this to all users */
7477                        broadcastIntentLocked(null, null, intent, null, finisher,
7478                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7479                                0 /* UserId zero */);
7480                        if (finisher != null) {
7481                            mWaitingUpdate = true;
7482                        }
7483                    }
7484                }
7485                if (mWaitingUpdate) {
7486                    return;
7487                }
7488                mDidUpdate = true;
7489            }
7490
7491            mSystemReady = true;
7492            if (!mStartRunning) {
7493                return;
7494            }
7495        }
7496
7497        ArrayList<ProcessRecord> procsToKill = null;
7498        synchronized(mPidsSelfLocked) {
7499            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7500                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7501                if (!isAllowedWhileBooting(proc.info)){
7502                    if (procsToKill == null) {
7503                        procsToKill = new ArrayList<ProcessRecord>();
7504                    }
7505                    procsToKill.add(proc);
7506                }
7507            }
7508        }
7509
7510        synchronized(this) {
7511            if (procsToKill != null) {
7512                for (int i=procsToKill.size()-1; i>=0; i--) {
7513                    ProcessRecord proc = procsToKill.get(i);
7514                    Slog.i(TAG, "Removing system update proc: " + proc);
7515                    removeProcessLocked(proc, true, false, "system update done");
7516                }
7517            }
7518
7519            // Now that we have cleaned up any update processes, we
7520            // are ready to start launching real processes and know that
7521            // we won't trample on them any more.
7522            mProcessesReady = true;
7523        }
7524
7525        Slog.i(TAG, "System now ready");
7526        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7527            SystemClock.uptimeMillis());
7528
7529        synchronized(this) {
7530            // Make sure we have no pre-ready processes sitting around.
7531
7532            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7533                ResolveInfo ri = mContext.getPackageManager()
7534                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7535                                STOCK_PM_FLAGS);
7536                CharSequence errorMsg = null;
7537                if (ri != null) {
7538                    ActivityInfo ai = ri.activityInfo;
7539                    ApplicationInfo app = ai.applicationInfo;
7540                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7541                        mTopAction = Intent.ACTION_FACTORY_TEST;
7542                        mTopData = null;
7543                        mTopComponent = new ComponentName(app.packageName,
7544                                ai.name);
7545                    } else {
7546                        errorMsg = mContext.getResources().getText(
7547                                com.android.internal.R.string.factorytest_not_system);
7548                    }
7549                } else {
7550                    errorMsg = mContext.getResources().getText(
7551                            com.android.internal.R.string.factorytest_no_action);
7552                }
7553                if (errorMsg != null) {
7554                    mTopAction = null;
7555                    mTopData = null;
7556                    mTopComponent = null;
7557                    Message msg = Message.obtain();
7558                    msg.what = SHOW_FACTORY_ERROR_MSG;
7559                    msg.getData().putCharSequence("msg", errorMsg);
7560                    mHandler.sendMessage(msg);
7561                }
7562            }
7563        }
7564
7565        retrieveSettings();
7566
7567        if (goingCallback != null) goingCallback.run();
7568
7569        synchronized (this) {
7570            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7571                try {
7572                    List apps = AppGlobals.getPackageManager().
7573                        getPersistentApplications(STOCK_PM_FLAGS);
7574                    if (apps != null) {
7575                        int N = apps.size();
7576                        int i;
7577                        for (i=0; i<N; i++) {
7578                            ApplicationInfo info
7579                                = (ApplicationInfo)apps.get(i);
7580                            if (info != null &&
7581                                    !info.packageName.equals("android")) {
7582                                addAppLocked(info, false);
7583                            }
7584                        }
7585                    }
7586                } catch (RemoteException ex) {
7587                    // pm is in same process, this will never happen.
7588                }
7589            }
7590
7591            // Start up initial activity.
7592            mBooting = true;
7593
7594            try {
7595                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7596                    Message msg = Message.obtain();
7597                    msg.what = SHOW_UID_ERROR_MSG;
7598                    mHandler.sendMessage(msg);
7599                }
7600            } catch (RemoteException e) {
7601            }
7602
7603            mMainStack.resumeTopActivityLocked(null);
7604        }
7605    }
7606
7607    private boolean makeAppCrashingLocked(ProcessRecord app,
7608            String shortMsg, String longMsg, String stackTrace) {
7609        app.crashing = true;
7610        app.crashingReport = generateProcessError(app,
7611                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7612        startAppProblemLocked(app);
7613        app.stopFreezingAllLocked();
7614        return handleAppCrashLocked(app);
7615    }
7616
7617    private void makeAppNotRespondingLocked(ProcessRecord app,
7618            String activity, String shortMsg, String longMsg) {
7619        app.notResponding = true;
7620        app.notRespondingReport = generateProcessError(app,
7621                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7622                activity, shortMsg, longMsg, null);
7623        startAppProblemLocked(app);
7624        app.stopFreezingAllLocked();
7625    }
7626
7627    /**
7628     * Generate a process error record, suitable for attachment to a ProcessRecord.
7629     *
7630     * @param app The ProcessRecord in which the error occurred.
7631     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7632     *                      ActivityManager.AppErrorStateInfo
7633     * @param activity The activity associated with the crash, if known.
7634     * @param shortMsg Short message describing the crash.
7635     * @param longMsg Long message describing the crash.
7636     * @param stackTrace Full crash stack trace, may be null.
7637     *
7638     * @return Returns a fully-formed AppErrorStateInfo record.
7639     */
7640    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7641            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7642        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7643
7644        report.condition = condition;
7645        report.processName = app.processName;
7646        report.pid = app.pid;
7647        report.uid = app.info.uid;
7648        report.tag = activity;
7649        report.shortMsg = shortMsg;
7650        report.longMsg = longMsg;
7651        report.stackTrace = stackTrace;
7652
7653        return report;
7654    }
7655
7656    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7657        synchronized (this) {
7658            app.crashing = false;
7659            app.crashingReport = null;
7660            app.notResponding = false;
7661            app.notRespondingReport = null;
7662            if (app.anrDialog == fromDialog) {
7663                app.anrDialog = null;
7664            }
7665            if (app.waitDialog == fromDialog) {
7666                app.waitDialog = null;
7667            }
7668            if (app.pid > 0 && app.pid != MY_PID) {
7669                handleAppCrashLocked(app);
7670                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7671                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7672                        app.processName, app.setAdj, "user's request after error");
7673                Process.killProcessQuiet(app.pid);
7674            }
7675        }
7676    }
7677
7678    private boolean handleAppCrashLocked(ProcessRecord app) {
7679        if (mHeadless) {
7680            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7681            return false;
7682        }
7683        long now = SystemClock.uptimeMillis();
7684
7685        Long crashTime;
7686        if (!app.isolated) {
7687            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7688        } else {
7689            crashTime = null;
7690        }
7691        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7692            // This process loses!
7693            Slog.w(TAG, "Process " + app.info.processName
7694                    + " has crashed too many times: killing!");
7695            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7696                    app.info.processName, app.uid);
7697            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7698                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7699                if (r.app == app) {
7700                    Slog.w(TAG, "  Force finishing activity "
7701                        + r.intent.getComponent().flattenToShortString());
7702                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7703                }
7704            }
7705            if (!app.persistent) {
7706                // We don't want to start this process again until the user
7707                // explicitly does so...  but for persistent process, we really
7708                // need to keep it running.  If a persistent process is actually
7709                // repeatedly crashing, then badness for everyone.
7710                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7711                        app.info.processName);
7712                if (!app.isolated) {
7713                    // XXX We don't have a way to mark isolated processes
7714                    // as bad, since they don't have a peristent identity.
7715                    mBadProcesses.put(app.info.processName, app.uid, now);
7716                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7717                }
7718                app.bad = true;
7719                app.removed = true;
7720                // Don't let services in this process be restarted and potentially
7721                // annoy the user repeatedly.  Unless it is persistent, since those
7722                // processes run critical code.
7723                removeProcessLocked(app, false, false, "crash");
7724                mMainStack.resumeTopActivityLocked(null);
7725                return false;
7726            }
7727            mMainStack.resumeTopActivityLocked(null);
7728        } else {
7729            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7730            if (r != null && r.app == app) {
7731                // If the top running activity is from this crashing
7732                // process, then terminate it to avoid getting in a loop.
7733                Slog.w(TAG, "  Force finishing activity "
7734                        + r.intent.getComponent().flattenToShortString());
7735                int index = mMainStack.indexOfActivityLocked(r);
7736                r.stack.finishActivityLocked(r, index,
7737                        Activity.RESULT_CANCELED, null, "crashed");
7738                // Also terminate any activities below it that aren't yet
7739                // stopped, to avoid a situation where one will get
7740                // re-start our crashing activity once it gets resumed again.
7741                index--;
7742                if (index >= 0) {
7743                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7744                    if (r.state == ActivityState.RESUMED
7745                            || r.state == ActivityState.PAUSING
7746                            || r.state == ActivityState.PAUSED) {
7747                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7748                            Slog.w(TAG, "  Force finishing activity "
7749                                    + r.intent.getComponent().flattenToShortString());
7750                            r.stack.finishActivityLocked(r, index,
7751                                    Activity.RESULT_CANCELED, null, "crashed");
7752                        }
7753                    }
7754                }
7755            }
7756        }
7757
7758        // Bump up the crash count of any services currently running in the proc.
7759        if (app.services.size() != 0) {
7760            // Any services running in the application need to be placed
7761            // back in the pending list.
7762            Iterator<ServiceRecord> it = app.services.iterator();
7763            while (it.hasNext()) {
7764                ServiceRecord sr = it.next();
7765                sr.crashCount++;
7766            }
7767        }
7768
7769        // If the crashing process is what we consider to be the "home process" and it has been
7770        // replaced by a third-party app, clear the package preferred activities from packages
7771        // with a home activity running in the process to prevent a repeatedly crashing app
7772        // from blocking the user to manually clear the list.
7773        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7774                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7775            Iterator it = mHomeProcess.activities.iterator();
7776            while (it.hasNext()) {
7777                ActivityRecord r = (ActivityRecord)it.next();
7778                if (r.isHomeActivity) {
7779                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7780                    try {
7781                        ActivityThread.getPackageManager()
7782                                .clearPackagePreferredActivities(r.packageName);
7783                    } catch (RemoteException c) {
7784                        // pm is in same process, this will never happen.
7785                    }
7786                }
7787            }
7788        }
7789
7790        if (!app.isolated) {
7791            // XXX Can't keep track of crash times for isolated processes,
7792            // because they don't have a perisistent identity.
7793            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7794        }
7795
7796        return true;
7797    }
7798
7799    void startAppProblemLocked(ProcessRecord app) {
7800        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7801                mContext, app.info.packageName, app.info.flags);
7802        skipCurrentReceiverLocked(app);
7803    }
7804
7805    void skipCurrentReceiverLocked(ProcessRecord app) {
7806        for (BroadcastQueue queue : mBroadcastQueues) {
7807            queue.skipCurrentReceiverLocked(app);
7808        }
7809    }
7810
7811    /**
7812     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7813     * The application process will exit immediately after this call returns.
7814     * @param app object of the crashing app, null for the system server
7815     * @param crashInfo describing the exception
7816     */
7817    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7818        ProcessRecord r = findAppProcess(app, "Crash");
7819        final String processName = app == null ? "system_server"
7820                : (r == null ? "unknown" : r.processName);
7821
7822        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7823                processName,
7824                r == null ? -1 : r.info.flags,
7825                crashInfo.exceptionClassName,
7826                crashInfo.exceptionMessage,
7827                crashInfo.throwFileName,
7828                crashInfo.throwLineNumber);
7829
7830        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7831
7832        crashApplication(r, crashInfo);
7833    }
7834
7835    public void handleApplicationStrictModeViolation(
7836            IBinder app,
7837            int violationMask,
7838            StrictMode.ViolationInfo info) {
7839        ProcessRecord r = findAppProcess(app, "StrictMode");
7840        if (r == null) {
7841            return;
7842        }
7843
7844        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7845            Integer stackFingerprint = info.hashCode();
7846            boolean logIt = true;
7847            synchronized (mAlreadyLoggedViolatedStacks) {
7848                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7849                    logIt = false;
7850                    // TODO: sub-sample into EventLog for these, with
7851                    // the info.durationMillis?  Then we'd get
7852                    // the relative pain numbers, without logging all
7853                    // the stack traces repeatedly.  We'd want to do
7854                    // likewise in the client code, which also does
7855                    // dup suppression, before the Binder call.
7856                } else {
7857                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7858                        mAlreadyLoggedViolatedStacks.clear();
7859                    }
7860                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7861                }
7862            }
7863            if (logIt) {
7864                logStrictModeViolationToDropBox(r, info);
7865            }
7866        }
7867
7868        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7869            AppErrorResult result = new AppErrorResult();
7870            synchronized (this) {
7871                final long origId = Binder.clearCallingIdentity();
7872
7873                Message msg = Message.obtain();
7874                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7875                HashMap<String, Object> data = new HashMap<String, Object>();
7876                data.put("result", result);
7877                data.put("app", r);
7878                data.put("violationMask", violationMask);
7879                data.put("info", info);
7880                msg.obj = data;
7881                mHandler.sendMessage(msg);
7882
7883                Binder.restoreCallingIdentity(origId);
7884            }
7885            int res = result.get();
7886            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7887        }
7888    }
7889
7890    // Depending on the policy in effect, there could be a bunch of
7891    // these in quick succession so we try to batch these together to
7892    // minimize disk writes, number of dropbox entries, and maximize
7893    // compression, by having more fewer, larger records.
7894    private void logStrictModeViolationToDropBox(
7895            ProcessRecord process,
7896            StrictMode.ViolationInfo info) {
7897        if (info == null) {
7898            return;
7899        }
7900        final boolean isSystemApp = process == null ||
7901                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7902                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7903        final String processName = process == null ? "unknown" : process.processName;
7904        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7905        final DropBoxManager dbox = (DropBoxManager)
7906                mContext.getSystemService(Context.DROPBOX_SERVICE);
7907
7908        // Exit early if the dropbox isn't configured to accept this report type.
7909        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7910
7911        boolean bufferWasEmpty;
7912        boolean needsFlush;
7913        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7914        synchronized (sb) {
7915            bufferWasEmpty = sb.length() == 0;
7916            appendDropBoxProcessHeaders(process, processName, sb);
7917            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7918            sb.append("System-App: ").append(isSystemApp).append("\n");
7919            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7920            if (info.violationNumThisLoop != 0) {
7921                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7922            }
7923            if (info.numAnimationsRunning != 0) {
7924                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7925            }
7926            if (info.broadcastIntentAction != null) {
7927                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7928            }
7929            if (info.durationMillis != -1) {
7930                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
7931            }
7932            if (info.numInstances != -1) {
7933                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7934            }
7935            if (info.tags != null) {
7936                for (String tag : info.tags) {
7937                    sb.append("Span-Tag: ").append(tag).append("\n");
7938                }
7939            }
7940            sb.append("\n");
7941            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7942                sb.append(info.crashInfo.stackTrace);
7943            }
7944            sb.append("\n");
7945
7946            // Only buffer up to ~64k.  Various logging bits truncate
7947            // things at 128k.
7948            needsFlush = (sb.length() > 64 * 1024);
7949        }
7950
7951        // Flush immediately if the buffer's grown too large, or this
7952        // is a non-system app.  Non-system apps are isolated with a
7953        // different tag & policy and not batched.
7954        //
7955        // Batching is useful during internal testing with
7956        // StrictMode settings turned up high.  Without batching,
7957        // thousands of separate files could be created on boot.
7958        if (!isSystemApp || needsFlush) {
7959            new Thread("Error dump: " + dropboxTag) {
7960                @Override
7961                public void run() {
7962                    String report;
7963                    synchronized (sb) {
7964                        report = sb.toString();
7965                        sb.delete(0, sb.length());
7966                        sb.trimToSize();
7967                    }
7968                    if (report.length() != 0) {
7969                        dbox.addText(dropboxTag, report);
7970                    }
7971                }
7972            }.start();
7973            return;
7974        }
7975
7976        // System app batching:
7977        if (!bufferWasEmpty) {
7978            // An existing dropbox-writing thread is outstanding, so
7979            // we don't need to start it up.  The existing thread will
7980            // catch the buffer appends we just did.
7981            return;
7982        }
7983
7984        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7985        // (After this point, we shouldn't access AMS internal data structures.)
7986        new Thread("Error dump: " + dropboxTag) {
7987            @Override
7988            public void run() {
7989                // 5 second sleep to let stacks arrive and be batched together
7990                try {
7991                    Thread.sleep(5000);  // 5 seconds
7992                } catch (InterruptedException e) {}
7993
7994                String errorReport;
7995                synchronized (mStrictModeBuffer) {
7996                    errorReport = mStrictModeBuffer.toString();
7997                    if (errorReport.length() == 0) {
7998                        return;
7999                    }
8000                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8001                    mStrictModeBuffer.trimToSize();
8002                }
8003                dbox.addText(dropboxTag, errorReport);
8004            }
8005        }.start();
8006    }
8007
8008    /**
8009     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8010     * @param app object of the crashing app, null for the system server
8011     * @param tag reported by the caller
8012     * @param crashInfo describing the context of the error
8013     * @return true if the process should exit immediately (WTF is fatal)
8014     */
8015    public boolean handleApplicationWtf(IBinder app, String tag,
8016            ApplicationErrorReport.CrashInfo crashInfo) {
8017        ProcessRecord r = findAppProcess(app, "WTF");
8018        final String processName = app == null ? "system_server"
8019                : (r == null ? "unknown" : r.processName);
8020
8021        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8022                processName,
8023                r == null ? -1 : r.info.flags,
8024                tag, crashInfo.exceptionMessage);
8025
8026        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8027
8028        if (r != null && r.pid != Process.myPid() &&
8029                Settings.Secure.getInt(mContext.getContentResolver(),
8030                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8031            crashApplication(r, crashInfo);
8032            return true;
8033        } else {
8034            return false;
8035        }
8036    }
8037
8038    /**
8039     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8040     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8041     */
8042    private ProcessRecord findAppProcess(IBinder app, String reason) {
8043        if (app == null) {
8044            return null;
8045        }
8046
8047        synchronized (this) {
8048            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8049                final int NA = apps.size();
8050                for (int ia=0; ia<NA; ia++) {
8051                    ProcessRecord p = apps.valueAt(ia);
8052                    if (p.thread != null && p.thread.asBinder() == app) {
8053                        return p;
8054                    }
8055                }
8056            }
8057
8058            Slog.w(TAG, "Can't find mystery application for " + reason
8059                    + " from pid=" + Binder.getCallingPid()
8060                    + " uid=" + Binder.getCallingUid() + ": " + app);
8061            return null;
8062        }
8063    }
8064
8065    /**
8066     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8067     * to append various headers to the dropbox log text.
8068     */
8069    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8070            StringBuilder sb) {
8071        // Watchdog thread ends up invoking this function (with
8072        // a null ProcessRecord) to add the stack file to dropbox.
8073        // Do not acquire a lock on this (am) in such cases, as it
8074        // could cause a potential deadlock, if and when watchdog
8075        // is invoked due to unavailability of lock on am and it
8076        // would prevent watchdog from killing system_server.
8077        if (process == null) {
8078            sb.append("Process: ").append(processName).append("\n");
8079            return;
8080        }
8081        // Note: ProcessRecord 'process' is guarded by the service
8082        // instance.  (notably process.pkgList, which could otherwise change
8083        // concurrently during execution of this method)
8084        synchronized (this) {
8085            sb.append("Process: ").append(processName).append("\n");
8086            int flags = process.info.flags;
8087            IPackageManager pm = AppGlobals.getPackageManager();
8088            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8089            for (String pkg : process.pkgList) {
8090                sb.append("Package: ").append(pkg);
8091                try {
8092                    PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
8093                    if (pi != null) {
8094                        sb.append(" v").append(pi.versionCode);
8095                        if (pi.versionName != null) {
8096                            sb.append(" (").append(pi.versionName).append(")");
8097                        }
8098                    }
8099                } catch (RemoteException e) {
8100                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8101                }
8102                sb.append("\n");
8103            }
8104        }
8105    }
8106
8107    private static String processClass(ProcessRecord process) {
8108        if (process == null || process.pid == MY_PID) {
8109            return "system_server";
8110        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8111            return "system_app";
8112        } else {
8113            return "data_app";
8114        }
8115    }
8116
8117    /**
8118     * Write a description of an error (crash, WTF, ANR) to the drop box.
8119     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8120     * @param process which caused the error, null means the system server
8121     * @param activity which triggered the error, null if unknown
8122     * @param parent activity related to the error, null if unknown
8123     * @param subject line related to the error, null if absent
8124     * @param report in long form describing the error, null if absent
8125     * @param logFile to include in the report, null if none
8126     * @param crashInfo giving an application stack trace, null if absent
8127     */
8128    public void addErrorToDropBox(String eventType,
8129            ProcessRecord process, String processName, ActivityRecord activity,
8130            ActivityRecord parent, String subject,
8131            final String report, final File logFile,
8132            final ApplicationErrorReport.CrashInfo crashInfo) {
8133        // NOTE -- this must never acquire the ActivityManagerService lock,
8134        // otherwise the watchdog may be prevented from resetting the system.
8135
8136        final String dropboxTag = processClass(process) + "_" + eventType;
8137        final DropBoxManager dbox = (DropBoxManager)
8138                mContext.getSystemService(Context.DROPBOX_SERVICE);
8139
8140        // Exit early if the dropbox isn't configured to accept this report type.
8141        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8142
8143        final StringBuilder sb = new StringBuilder(1024);
8144        appendDropBoxProcessHeaders(process, processName, sb);
8145        if (activity != null) {
8146            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8147        }
8148        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8149            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8150        }
8151        if (parent != null && parent != activity) {
8152            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8153        }
8154        if (subject != null) {
8155            sb.append("Subject: ").append(subject).append("\n");
8156        }
8157        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8158        if (Debug.isDebuggerConnected()) {
8159            sb.append("Debugger: Connected\n");
8160        }
8161        sb.append("\n");
8162
8163        // Do the rest in a worker thread to avoid blocking the caller on I/O
8164        // (After this point, we shouldn't access AMS internal data structures.)
8165        Thread worker = new Thread("Error dump: " + dropboxTag) {
8166            @Override
8167            public void run() {
8168                if (report != null) {
8169                    sb.append(report);
8170                }
8171                if (logFile != null) {
8172                    try {
8173                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8174                    } catch (IOException e) {
8175                        Slog.e(TAG, "Error reading " + logFile, e);
8176                    }
8177                }
8178                if (crashInfo != null && crashInfo.stackTrace != null) {
8179                    sb.append(crashInfo.stackTrace);
8180                }
8181
8182                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8183                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8184                if (lines > 0) {
8185                    sb.append("\n");
8186
8187                    // Merge several logcat streams, and take the last N lines
8188                    InputStreamReader input = null;
8189                    try {
8190                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8191                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8192                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8193
8194                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8195                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8196                        input = new InputStreamReader(logcat.getInputStream());
8197
8198                        int num;
8199                        char[] buf = new char[8192];
8200                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8201                    } catch (IOException e) {
8202                        Slog.e(TAG, "Error running logcat", e);
8203                    } finally {
8204                        if (input != null) try { input.close(); } catch (IOException e) {}
8205                    }
8206                }
8207
8208                dbox.addText(dropboxTag, sb.toString());
8209            }
8210        };
8211
8212        if (process == null) {
8213            // If process is null, we are being called from some internal code
8214            // and may be about to die -- run this synchronously.
8215            worker.run();
8216        } else {
8217            worker.start();
8218        }
8219    }
8220
8221    /**
8222     * Bring up the "unexpected error" dialog box for a crashing app.
8223     * Deal with edge cases (intercepts from instrumented applications,
8224     * ActivityController, error intent receivers, that sort of thing).
8225     * @param r the application crashing
8226     * @param crashInfo describing the failure
8227     */
8228    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8229        long timeMillis = System.currentTimeMillis();
8230        String shortMsg = crashInfo.exceptionClassName;
8231        String longMsg = crashInfo.exceptionMessage;
8232        String stackTrace = crashInfo.stackTrace;
8233        if (shortMsg != null && longMsg != null) {
8234            longMsg = shortMsg + ": " + longMsg;
8235        } else if (shortMsg != null) {
8236            longMsg = shortMsg;
8237        }
8238
8239        AppErrorResult result = new AppErrorResult();
8240        synchronized (this) {
8241            if (mController != null) {
8242                try {
8243                    String name = r != null ? r.processName : null;
8244                    int pid = r != null ? r.pid : Binder.getCallingPid();
8245                    if (!mController.appCrashed(name, pid,
8246                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8247                        Slog.w(TAG, "Force-killing crashed app " + name
8248                                + " at watcher's request");
8249                        Process.killProcess(pid);
8250                        return;
8251                    }
8252                } catch (RemoteException e) {
8253                    mController = null;
8254                }
8255            }
8256
8257            final long origId = Binder.clearCallingIdentity();
8258
8259            // If this process is running instrumentation, finish it.
8260            if (r != null && r.instrumentationClass != null) {
8261                Slog.w(TAG, "Error in app " + r.processName
8262                      + " running instrumentation " + r.instrumentationClass + ":");
8263                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8264                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8265                Bundle info = new Bundle();
8266                info.putString("shortMsg", shortMsg);
8267                info.putString("longMsg", longMsg);
8268                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8269                Binder.restoreCallingIdentity(origId);
8270                return;
8271            }
8272
8273            // If we can't identify the process or it's already exceeded its crash quota,
8274            // quit right away without showing a crash dialog.
8275            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8276                Binder.restoreCallingIdentity(origId);
8277                return;
8278            }
8279
8280            Message msg = Message.obtain();
8281            msg.what = SHOW_ERROR_MSG;
8282            HashMap data = new HashMap();
8283            data.put("result", result);
8284            data.put("app", r);
8285            msg.obj = data;
8286            mHandler.sendMessage(msg);
8287
8288            Binder.restoreCallingIdentity(origId);
8289        }
8290
8291        int res = result.get();
8292
8293        Intent appErrorIntent = null;
8294        synchronized (this) {
8295            if (r != null && !r.isolated) {
8296                // XXX Can't keep track of crash time for isolated processes,
8297                // since they don't have a persistent identity.
8298                mProcessCrashTimes.put(r.info.processName, r.uid,
8299                        SystemClock.uptimeMillis());
8300            }
8301            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8302                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8303            }
8304        }
8305
8306        if (appErrorIntent != null) {
8307            try {
8308                mContext.startActivity(appErrorIntent);
8309            } catch (ActivityNotFoundException e) {
8310                Slog.w(TAG, "bug report receiver dissappeared", e);
8311            }
8312        }
8313    }
8314
8315    Intent createAppErrorIntentLocked(ProcessRecord r,
8316            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8317        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8318        if (report == null) {
8319            return null;
8320        }
8321        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8322        result.setComponent(r.errorReportReceiver);
8323        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8324        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8325        return result;
8326    }
8327
8328    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8329            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8330        if (r.errorReportReceiver == null) {
8331            return null;
8332        }
8333
8334        if (!r.crashing && !r.notResponding) {
8335            return null;
8336        }
8337
8338        ApplicationErrorReport report = new ApplicationErrorReport();
8339        report.packageName = r.info.packageName;
8340        report.installerPackageName = r.errorReportReceiver.getPackageName();
8341        report.processName = r.processName;
8342        report.time = timeMillis;
8343        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8344
8345        if (r.crashing) {
8346            report.type = ApplicationErrorReport.TYPE_CRASH;
8347            report.crashInfo = crashInfo;
8348        } else if (r.notResponding) {
8349            report.type = ApplicationErrorReport.TYPE_ANR;
8350            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8351
8352            report.anrInfo.activity = r.notRespondingReport.tag;
8353            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8354            report.anrInfo.info = r.notRespondingReport.longMsg;
8355        }
8356
8357        return report;
8358    }
8359
8360    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8361        enforceNotIsolatedCaller("getProcessesInErrorState");
8362        // assume our apps are happy - lazy create the list
8363        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8364
8365        synchronized (this) {
8366
8367            // iterate across all processes
8368            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8369                ProcessRecord app = mLruProcesses.get(i);
8370                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8371                    // This one's in trouble, so we'll generate a report for it
8372                    // crashes are higher priority (in case there's a crash *and* an anr)
8373                    ActivityManager.ProcessErrorStateInfo report = null;
8374                    if (app.crashing) {
8375                        report = app.crashingReport;
8376                    } else if (app.notResponding) {
8377                        report = app.notRespondingReport;
8378                    }
8379
8380                    if (report != null) {
8381                        if (errList == null) {
8382                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8383                        }
8384                        errList.add(report);
8385                    } else {
8386                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8387                                " crashing = " + app.crashing +
8388                                " notResponding = " + app.notResponding);
8389                    }
8390                }
8391            }
8392        }
8393
8394        return errList;
8395    }
8396
8397    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8398        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8399            if (currApp != null) {
8400                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8401            }
8402            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8403        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8404            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8405        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8406            if (currApp != null) {
8407                currApp.lru = 0;
8408            }
8409            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8410        } else if (adj >= ProcessList.SERVICE_ADJ) {
8411            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8412        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8413            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8414        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8415            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8416        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8417            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8418        } else {
8419            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8420        }
8421    }
8422
8423    private void fillInProcMemInfo(ProcessRecord app,
8424            ActivityManager.RunningAppProcessInfo outInfo) {
8425        outInfo.pid = app.pid;
8426        outInfo.uid = app.info.uid;
8427        if (mHeavyWeightProcess == app) {
8428            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8429        }
8430        if (app.persistent) {
8431            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8432        }
8433        outInfo.lastTrimLevel = app.trimMemoryLevel;
8434        int adj = app.curAdj;
8435        outInfo.importance = oomAdjToImportance(adj, outInfo);
8436        outInfo.importanceReasonCode = app.adjTypeCode;
8437    }
8438
8439    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8440        enforceNotIsolatedCaller("getRunningAppProcesses");
8441        // Lazy instantiation of list
8442        List<ActivityManager.RunningAppProcessInfo> runList = null;
8443        synchronized (this) {
8444            // Iterate across all processes
8445            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8446                ProcessRecord app = mLruProcesses.get(i);
8447                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8448                    // Generate process state info for running application
8449                    ActivityManager.RunningAppProcessInfo currApp =
8450                        new ActivityManager.RunningAppProcessInfo(app.processName,
8451                                app.pid, app.getPackageList());
8452                    fillInProcMemInfo(app, currApp);
8453                    if (app.adjSource instanceof ProcessRecord) {
8454                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8455                        currApp.importanceReasonImportance = oomAdjToImportance(
8456                                app.adjSourceOom, null);
8457                    } else if (app.adjSource instanceof ActivityRecord) {
8458                        ActivityRecord r = (ActivityRecord)app.adjSource;
8459                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8460                    }
8461                    if (app.adjTarget instanceof ComponentName) {
8462                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8463                    }
8464                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8465                    //        + " lru=" + currApp.lru);
8466                    if (runList == null) {
8467                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8468                    }
8469                    runList.add(currApp);
8470                }
8471            }
8472        }
8473        return runList;
8474    }
8475
8476    public List<ApplicationInfo> getRunningExternalApplications() {
8477        enforceNotIsolatedCaller("getRunningExternalApplications");
8478        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8479        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8480        if (runningApps != null && runningApps.size() > 0) {
8481            Set<String> extList = new HashSet<String>();
8482            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8483                if (app.pkgList != null) {
8484                    for (String pkg : app.pkgList) {
8485                        extList.add(pkg);
8486                    }
8487                }
8488            }
8489            IPackageManager pm = AppGlobals.getPackageManager();
8490            for (String pkg : extList) {
8491                try {
8492                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId());
8493                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8494                        retList.add(info);
8495                    }
8496                } catch (RemoteException e) {
8497                }
8498            }
8499        }
8500        return retList;
8501    }
8502
8503    @Override
8504    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8505        enforceNotIsolatedCaller("getMyMemoryState");
8506        synchronized (this) {
8507            ProcessRecord proc;
8508            synchronized (mPidsSelfLocked) {
8509                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8510            }
8511            fillInProcMemInfo(proc, outInfo);
8512        }
8513    }
8514
8515    @Override
8516    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8517        if (checkCallingPermission(android.Manifest.permission.DUMP)
8518                != PackageManager.PERMISSION_GRANTED) {
8519            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8520                    + Binder.getCallingPid()
8521                    + ", uid=" + Binder.getCallingUid()
8522                    + " without permission "
8523                    + android.Manifest.permission.DUMP);
8524            return;
8525        }
8526
8527        boolean dumpAll = false;
8528        boolean dumpClient = false;
8529        String dumpPackage = null;
8530
8531        int opti = 0;
8532        while (opti < args.length) {
8533            String opt = args[opti];
8534            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8535                break;
8536            }
8537            opti++;
8538            if ("-a".equals(opt)) {
8539                dumpAll = true;
8540            } else if ("-c".equals(opt)) {
8541                dumpClient = true;
8542            } else if ("-h".equals(opt)) {
8543                pw.println("Activity manager dump options:");
8544                pw.println("  [-a] [-c] [-h] [cmd] ...");
8545                pw.println("  cmd may be one of:");
8546                pw.println("    a[ctivities]: activity stack state");
8547                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8548                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8549                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8550                pw.println("    o[om]: out of memory management");
8551                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8552                pw.println("    provider [COMP_SPEC]: provider client-side state");
8553                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8554                pw.println("    service [COMP_SPEC]: service client-side state");
8555                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8556                pw.println("    all: dump all activities");
8557                pw.println("    top: dump the top activity");
8558                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8559                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8560                pw.println("    a partial substring in a component name, a");
8561                pw.println("    hex object identifier.");
8562                pw.println("  -a: include all available server state.");
8563                pw.println("  -c: include client state.");
8564                return;
8565            } else {
8566                pw.println("Unknown argument: " + opt + "; use -h for help");
8567            }
8568        }
8569
8570        long origId = Binder.clearCallingIdentity();
8571        boolean more = false;
8572        // Is the caller requesting to dump a particular piece of data?
8573        if (opti < args.length) {
8574            String cmd = args[opti];
8575            opti++;
8576            if ("activities".equals(cmd) || "a".equals(cmd)) {
8577                synchronized (this) {
8578                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8579                }
8580            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8581                String[] newArgs;
8582                String name;
8583                if (opti >= args.length) {
8584                    name = null;
8585                    newArgs = EMPTY_STRING_ARRAY;
8586                } else {
8587                    name = args[opti];
8588                    opti++;
8589                    newArgs = new String[args.length - opti];
8590                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8591                            args.length - opti);
8592                }
8593                synchronized (this) {
8594                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8595                }
8596            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8597                String[] newArgs;
8598                String name;
8599                if (opti >= args.length) {
8600                    name = null;
8601                    newArgs = EMPTY_STRING_ARRAY;
8602                } else {
8603                    name = args[opti];
8604                    opti++;
8605                    newArgs = new String[args.length - opti];
8606                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8607                            args.length - opti);
8608                }
8609                synchronized (this) {
8610                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8611                }
8612            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8613                String[] newArgs;
8614                String name;
8615                if (opti >= args.length) {
8616                    name = null;
8617                    newArgs = EMPTY_STRING_ARRAY;
8618                } else {
8619                    name = args[opti];
8620                    opti++;
8621                    newArgs = new String[args.length - opti];
8622                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8623                            args.length - opti);
8624                }
8625                synchronized (this) {
8626                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8627                }
8628            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8629                synchronized (this) {
8630                    dumpOomLocked(fd, pw, args, opti, true);
8631                }
8632            } else if ("provider".equals(cmd)) {
8633                String[] newArgs;
8634                String name;
8635                if (opti >= args.length) {
8636                    name = null;
8637                    newArgs = EMPTY_STRING_ARRAY;
8638                } else {
8639                    name = args[opti];
8640                    opti++;
8641                    newArgs = new String[args.length - opti];
8642                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8643                }
8644                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8645                    pw.println("No providers match: " + name);
8646                    pw.println("Use -h for help.");
8647                }
8648            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8649                synchronized (this) {
8650                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8651                }
8652            } else if ("service".equals(cmd)) {
8653                String[] newArgs;
8654                String name;
8655                if (opti >= args.length) {
8656                    name = null;
8657                    newArgs = EMPTY_STRING_ARRAY;
8658                } else {
8659                    name = args[opti];
8660                    opti++;
8661                    newArgs = new String[args.length - opti];
8662                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8663                            args.length - opti);
8664                }
8665                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8666                    pw.println("No services match: " + name);
8667                    pw.println("Use -h for help.");
8668                }
8669            } else if ("package".equals(cmd)) {
8670                String[] newArgs;
8671                if (opti >= args.length) {
8672                    pw.println("package: no package name specified");
8673                    pw.println("Use -h for help.");
8674                } else {
8675                    dumpPackage = args[opti];
8676                    opti++;
8677                    newArgs = new String[args.length - opti];
8678                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8679                            args.length - opti);
8680                    args = newArgs;
8681                    opti = 0;
8682                    more = true;
8683                }
8684            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8685                synchronized (this) {
8686                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8687                }
8688            } else {
8689                // Dumping a single activity?
8690                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8691                    pw.println("Bad activity command, or no activities match: " + cmd);
8692                    pw.println("Use -h for help.");
8693                }
8694            }
8695            if (!more) {
8696                Binder.restoreCallingIdentity(origId);
8697                return;
8698            }
8699        }
8700
8701        // No piece of data specified, dump everything.
8702        synchronized (this) {
8703            boolean needSep;
8704            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8705            if (needSep) {
8706                pw.println(" ");
8707            }
8708            if (dumpAll) {
8709                pw.println("-------------------------------------------------------------------------------");
8710            }
8711            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8712            if (needSep) {
8713                pw.println(" ");
8714            }
8715            if (dumpAll) {
8716                pw.println("-------------------------------------------------------------------------------");
8717            }
8718            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8719            if (needSep) {
8720                pw.println(" ");
8721            }
8722            if (dumpAll) {
8723                pw.println("-------------------------------------------------------------------------------");
8724            }
8725            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8726            if (needSep) {
8727                pw.println(" ");
8728            }
8729            if (dumpAll) {
8730                pw.println("-------------------------------------------------------------------------------");
8731            }
8732            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8733            if (needSep) {
8734                pw.println(" ");
8735            }
8736            if (dumpAll) {
8737                pw.println("-------------------------------------------------------------------------------");
8738            }
8739            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8740        }
8741        Binder.restoreCallingIdentity(origId);
8742    }
8743
8744    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8745            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8746        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8747        pw.println("  Main stack:");
8748        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8749                dumpPackage);
8750        pw.println(" ");
8751        pw.println("  Running activities (most recent first):");
8752        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8753                dumpPackage);
8754        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8755            pw.println(" ");
8756            pw.println("  Activities waiting for another to become visible:");
8757            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8758                    !dumpAll, false, dumpPackage);
8759        }
8760        if (mMainStack.mStoppingActivities.size() > 0) {
8761            pw.println(" ");
8762            pw.println("  Activities waiting to stop:");
8763            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8764                    !dumpAll, false, dumpPackage);
8765        }
8766        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8767            pw.println(" ");
8768            pw.println("  Activities waiting to sleep:");
8769            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8770                    !dumpAll, false, dumpPackage);
8771        }
8772        if (mMainStack.mFinishingActivities.size() > 0) {
8773            pw.println(" ");
8774            pw.println("  Activities waiting to finish:");
8775            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8776                    !dumpAll, false, dumpPackage);
8777        }
8778
8779        pw.println(" ");
8780        if (mMainStack.mPausingActivity != null) {
8781            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8782        }
8783        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8784        pw.println("  mFocusedActivity: " + mFocusedActivity);
8785        if (dumpAll) {
8786            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8787            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8788            pw.println("  mDismissKeyguardOnNextActivity: "
8789                    + mMainStack.mDismissKeyguardOnNextActivity);
8790        }
8791
8792        if (mRecentTasks.size() > 0) {
8793            pw.println();
8794            pw.println("  Recent tasks:");
8795
8796            final int N = mRecentTasks.size();
8797            for (int i=0; i<N; i++) {
8798                TaskRecord tr = mRecentTasks.get(i);
8799                if (dumpPackage != null) {
8800                    if (tr.realActivity == null ||
8801                            !dumpPackage.equals(tr.realActivity)) {
8802                        continue;
8803                    }
8804                }
8805                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8806                        pw.println(tr);
8807                if (dumpAll) {
8808                    mRecentTasks.get(i).dump(pw, "    ");
8809                }
8810            }
8811        }
8812
8813        if (dumpAll) {
8814            pw.println(" ");
8815            pw.println("  mCurTask: " + mCurTask);
8816        }
8817
8818        return true;
8819    }
8820
8821    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8822            int opti, boolean dumpAll, String dumpPackage) {
8823        boolean needSep = false;
8824        int numPers = 0;
8825
8826        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8827
8828        if (dumpAll) {
8829            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8830                final int NA = procs.size();
8831                for (int ia=0; ia<NA; ia++) {
8832                    ProcessRecord r = procs.valueAt(ia);
8833                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8834                        continue;
8835                    }
8836                    if (!needSep) {
8837                        pw.println("  All known processes:");
8838                        needSep = true;
8839                    }
8840                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8841                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8842                        pw.print(" "); pw.println(r);
8843                    r.dump(pw, "    ");
8844                    if (r.persistent) {
8845                        numPers++;
8846                    }
8847                }
8848            }
8849        }
8850
8851        if (mIsolatedProcesses.size() > 0) {
8852            if (needSep) pw.println(" ");
8853            needSep = true;
8854            pw.println("  Isolated process list (sorted by uid):");
8855            for (int i=0; i<mIsolatedProcesses.size(); i++) {
8856                ProcessRecord r = mIsolatedProcesses.valueAt(i);
8857                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8858                    continue;
8859                }
8860                pw.println(String.format("%sIsolated #%2d: %s",
8861                        "    ", i, r.toString()));
8862            }
8863        }
8864
8865        if (mLruProcesses.size() > 0) {
8866            if (needSep) pw.println(" ");
8867            needSep = true;
8868            pw.println("  Process LRU list (sorted by oom_adj):");
8869            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8870                    "Proc", "PERS", false, dumpPackage);
8871            needSep = true;
8872        }
8873
8874        if (dumpAll) {
8875            synchronized (mPidsSelfLocked) {
8876                boolean printed = false;
8877                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8878                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8879                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8880                        continue;
8881                    }
8882                    if (!printed) {
8883                        if (needSep) pw.println(" ");
8884                        needSep = true;
8885                        pw.println("  PID mappings:");
8886                        printed = true;
8887                    }
8888                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8889                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8890                }
8891            }
8892        }
8893
8894        if (mForegroundProcesses.size() > 0) {
8895            synchronized (mPidsSelfLocked) {
8896                boolean printed = false;
8897                for (int i=0; i<mForegroundProcesses.size(); i++) {
8898                    ProcessRecord r = mPidsSelfLocked.get(
8899                            mForegroundProcesses.valueAt(i).pid);
8900                    if (dumpPackage != null && (r == null
8901                            || !dumpPackage.equals(r.info.packageName))) {
8902                        continue;
8903                    }
8904                    if (!printed) {
8905                        if (needSep) pw.println(" ");
8906                        needSep = true;
8907                        pw.println("  Foreground Processes:");
8908                        printed = true;
8909                    }
8910                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
8911                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8912                }
8913            }
8914        }
8915
8916        if (mPersistentStartingProcesses.size() > 0) {
8917            if (needSep) pw.println(" ");
8918            needSep = true;
8919            pw.println("  Persisent processes that are starting:");
8920            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
8921                    "Starting Norm", "Restarting PERS", dumpPackage);
8922        }
8923
8924        if (mRemovedProcesses.size() > 0) {
8925            if (needSep) pw.println(" ");
8926            needSep = true;
8927            pw.println("  Processes that are being removed:");
8928            dumpProcessList(pw, this, mRemovedProcesses, "    ",
8929                    "Removed Norm", "Removed PERS", dumpPackage);
8930        }
8931
8932        if (mProcessesOnHold.size() > 0) {
8933            if (needSep) pw.println(" ");
8934            needSep = true;
8935            pw.println("  Processes that are on old until the system is ready:");
8936            dumpProcessList(pw, this, mProcessesOnHold, "    ",
8937                    "OnHold Norm", "OnHold PERS", dumpPackage);
8938        }
8939
8940        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
8941
8942        if (mProcessCrashTimes.getMap().size() > 0) {
8943            boolean printed = false;
8944            long now = SystemClock.uptimeMillis();
8945            for (Map.Entry<String, SparseArray<Long>> procs
8946                    : mProcessCrashTimes.getMap().entrySet()) {
8947                String pname = procs.getKey();
8948                SparseArray<Long> uids = procs.getValue();
8949                final int N = uids.size();
8950                for (int i=0; i<N; i++) {
8951                    int puid = uids.keyAt(i);
8952                    ProcessRecord r = mProcessNames.get(pname, puid);
8953                    if (dumpPackage != null && (r == null
8954                            || !dumpPackage.equals(r.info.packageName))) {
8955                        continue;
8956                    }
8957                    if (!printed) {
8958                        if (needSep) pw.println(" ");
8959                        needSep = true;
8960                        pw.println("  Time since processes crashed:");
8961                        printed = true;
8962                    }
8963                    pw.print("    Process "); pw.print(pname);
8964                            pw.print(" uid "); pw.print(puid);
8965                            pw.print(": last crashed ");
8966                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
8967                            pw.println(" ago");
8968                }
8969            }
8970        }
8971
8972        if (mBadProcesses.getMap().size() > 0) {
8973            boolean printed = false;
8974            for (Map.Entry<String, SparseArray<Long>> procs
8975                    : mBadProcesses.getMap().entrySet()) {
8976                String pname = procs.getKey();
8977                SparseArray<Long> uids = procs.getValue();
8978                final int N = uids.size();
8979                for (int i=0; i<N; i++) {
8980                    int puid = uids.keyAt(i);
8981                    ProcessRecord r = mProcessNames.get(pname, puid);
8982                    if (dumpPackage != null && (r == null
8983                            || !dumpPackage.equals(r.info.packageName))) {
8984                        continue;
8985                    }
8986                    if (!printed) {
8987                        if (needSep) pw.println(" ");
8988                        needSep = true;
8989                        pw.println("  Bad processes:");
8990                    }
8991                    pw.print("    Bad process "); pw.print(pname);
8992                            pw.print(" uid "); pw.print(puid);
8993                            pw.print(": crashed at time ");
8994                            pw.println(uids.valueAt(i));
8995                }
8996            }
8997        }
8998
8999        pw.println();
9000        pw.println("  mHomeProcess: " + mHomeProcess);
9001        pw.println("  mPreviousProcess: " + mPreviousProcess);
9002        if (dumpAll) {
9003            StringBuilder sb = new StringBuilder(128);
9004            sb.append("  mPreviousProcessVisibleTime: ");
9005            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9006            pw.println(sb);
9007        }
9008        if (mHeavyWeightProcess != null) {
9009            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9010        }
9011        pw.println("  mConfiguration: " + mConfiguration);
9012        if (dumpAll) {
9013            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9014            if (mCompatModePackages.getPackages().size() > 0) {
9015                boolean printed = false;
9016                for (Map.Entry<String, Integer> entry
9017                        : mCompatModePackages.getPackages().entrySet()) {
9018                    String pkg = entry.getKey();
9019                    int mode = entry.getValue();
9020                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9021                        continue;
9022                    }
9023                    if (!printed) {
9024                        pw.println("  mScreenCompatPackages:");
9025                        printed = true;
9026                    }
9027                    pw.print("    "); pw.print(pkg); pw.print(": ");
9028                            pw.print(mode); pw.println();
9029                }
9030            }
9031        }
9032        if (mSleeping || mWentToSleep || mLockScreenShown) {
9033            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9034                    + " mLockScreenShown " + mLockScreenShown);
9035        }
9036        if (mShuttingDown) {
9037            pw.println("  mShuttingDown=" + mShuttingDown);
9038        }
9039        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9040                || mOrigWaitForDebugger) {
9041            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9042                    + " mDebugTransient=" + mDebugTransient
9043                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9044        }
9045        if (mOpenGlTraceApp != null) {
9046            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9047        }
9048        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9049                || mProfileFd != null) {
9050            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9051            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9052            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9053                    + mAutoStopProfiler);
9054        }
9055        if (mAlwaysFinishActivities || mController != null) {
9056            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9057                    + " mController=" + mController);
9058        }
9059        if (dumpAll) {
9060            pw.println("  Total persistent processes: " + numPers);
9061            pw.println("  mStartRunning=" + mStartRunning
9062                    + " mProcessesReady=" + mProcessesReady
9063                    + " mSystemReady=" + mSystemReady);
9064            pw.println("  mBooting=" + mBooting
9065                    + " mBooted=" + mBooted
9066                    + " mFactoryTest=" + mFactoryTest);
9067            pw.print("  mLastPowerCheckRealtime=");
9068                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9069                    pw.println("");
9070            pw.print("  mLastPowerCheckUptime=");
9071                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9072                    pw.println("");
9073            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9074            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9075            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9076            pw.println("  mNumServiceProcs=" + mNumServiceProcs
9077                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9078        }
9079
9080        return true;
9081    }
9082
9083    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9084            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9085        if (mProcessesToGc.size() > 0) {
9086            boolean printed = false;
9087            long now = SystemClock.uptimeMillis();
9088            for (int i=0; i<mProcessesToGc.size(); i++) {
9089                ProcessRecord proc = mProcessesToGc.get(i);
9090                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9091                    continue;
9092                }
9093                if (!printed) {
9094                    if (needSep) pw.println(" ");
9095                    needSep = true;
9096                    pw.println("  Processes that are waiting to GC:");
9097                    printed = true;
9098                }
9099                pw.print("    Process "); pw.println(proc);
9100                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9101                        pw.print(", last gced=");
9102                        pw.print(now-proc.lastRequestedGc);
9103                        pw.print(" ms ago, last lowMem=");
9104                        pw.print(now-proc.lastLowMemory);
9105                        pw.println(" ms ago");
9106
9107            }
9108        }
9109        return needSep;
9110    }
9111
9112    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9113            int opti, boolean dumpAll) {
9114        boolean needSep = false;
9115
9116        if (mLruProcesses.size() > 0) {
9117            if (needSep) pw.println(" ");
9118            needSep = true;
9119            pw.println("  OOM levels:");
9120            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9121            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9122            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9123            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9124            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9125            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9126            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9127            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9128            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9129            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9130            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9131            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9132            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9133
9134            if (needSep) pw.println(" ");
9135            needSep = true;
9136            pw.println("  Process OOM control:");
9137            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9138                    "Proc", "PERS", true, null);
9139            needSep = true;
9140        }
9141
9142        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9143
9144        pw.println();
9145        pw.println("  mHomeProcess: " + mHomeProcess);
9146        pw.println("  mPreviousProcess: " + mPreviousProcess);
9147        if (mHeavyWeightProcess != null) {
9148            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9149        }
9150
9151        return true;
9152    }
9153
9154    /**
9155     * There are three ways to call this:
9156     *  - no provider specified: dump all the providers
9157     *  - a flattened component name that matched an existing provider was specified as the
9158     *    first arg: dump that one provider
9159     *  - the first arg isn't the flattened component name of an existing provider:
9160     *    dump all providers whose component contains the first arg as a substring
9161     */
9162    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9163            int opti, boolean dumpAll) {
9164        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9165    }
9166
9167    static class ItemMatcher {
9168        ArrayList<ComponentName> components;
9169        ArrayList<String> strings;
9170        ArrayList<Integer> objects;
9171        boolean all;
9172
9173        ItemMatcher() {
9174            all = true;
9175        }
9176
9177        void build(String name) {
9178            ComponentName componentName = ComponentName.unflattenFromString(name);
9179            if (componentName != null) {
9180                if (components == null) {
9181                    components = new ArrayList<ComponentName>();
9182                }
9183                components.add(componentName);
9184                all = false;
9185            } else {
9186                int objectId = 0;
9187                // Not a '/' separated full component name; maybe an object ID?
9188                try {
9189                    objectId = Integer.parseInt(name, 16);
9190                    if (objects == null) {
9191                        objects = new ArrayList<Integer>();
9192                    }
9193                    objects.add(objectId);
9194                    all = false;
9195                } catch (RuntimeException e) {
9196                    // Not an integer; just do string match.
9197                    if (strings == null) {
9198                        strings = new ArrayList<String>();
9199                    }
9200                    strings.add(name);
9201                    all = false;
9202                }
9203            }
9204        }
9205
9206        int build(String[] args, int opti) {
9207            for (; opti<args.length; opti++) {
9208                String name = args[opti];
9209                if ("--".equals(name)) {
9210                    return opti+1;
9211                }
9212                build(name);
9213            }
9214            return opti;
9215        }
9216
9217        boolean match(Object object, ComponentName comp) {
9218            if (all) {
9219                return true;
9220            }
9221            if (components != null) {
9222                for (int i=0; i<components.size(); i++) {
9223                    if (components.get(i).equals(comp)) {
9224                        return true;
9225                    }
9226                }
9227            }
9228            if (objects != null) {
9229                for (int i=0; i<objects.size(); i++) {
9230                    if (System.identityHashCode(object) == objects.get(i)) {
9231                        return true;
9232                    }
9233                }
9234            }
9235            if (strings != null) {
9236                String flat = comp.flattenToString();
9237                for (int i=0; i<strings.size(); i++) {
9238                    if (flat.contains(strings.get(i))) {
9239                        return true;
9240                    }
9241                }
9242            }
9243            return false;
9244        }
9245    }
9246
9247    /**
9248     * There are three things that cmd can be:
9249     *  - a flattened component name that matches an existing activity
9250     *  - the cmd arg isn't the flattened component name of an existing activity:
9251     *    dump all activity whose component contains the cmd as a substring
9252     *  - A hex number of the ActivityRecord object instance.
9253     */
9254    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9255            int opti, boolean dumpAll) {
9256        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9257
9258        if ("all".equals(name)) {
9259            synchronized (this) {
9260                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9261                    activities.add(r1);
9262                }
9263            }
9264        } else if ("top".equals(name)) {
9265            synchronized (this) {
9266                final int N = mMainStack.mHistory.size();
9267                if (N > 0) {
9268                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9269                }
9270            }
9271        } else {
9272            ItemMatcher matcher = new ItemMatcher();
9273            matcher.build(name);
9274
9275            synchronized (this) {
9276                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9277                    if (matcher.match(r1, r1.intent.getComponent())) {
9278                        activities.add(r1);
9279                    }
9280                }
9281            }
9282        }
9283
9284        if (activities.size() <= 0) {
9285            return false;
9286        }
9287
9288        String[] newArgs = new String[args.length - opti];
9289        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9290
9291        TaskRecord lastTask = null;
9292        boolean needSep = false;
9293        for (int i=activities.size()-1; i>=0; i--) {
9294            ActivityRecord r = (ActivityRecord)activities.get(i);
9295            if (needSep) {
9296                pw.println();
9297            }
9298            needSep = true;
9299            synchronized (this) {
9300                if (lastTask != r.task) {
9301                    lastTask = r.task;
9302                    pw.print("TASK "); pw.print(lastTask.affinity);
9303                            pw.print(" id="); pw.println(lastTask.taskId);
9304                    if (dumpAll) {
9305                        lastTask.dump(pw, "  ");
9306                    }
9307                }
9308            }
9309            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9310        }
9311        return true;
9312    }
9313
9314    /**
9315     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9316     * there is a thread associated with the activity.
9317     */
9318    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9319            final ActivityRecord r, String[] args, boolean dumpAll) {
9320        String innerPrefix = prefix + "  ";
9321        synchronized (this) {
9322            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9323                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9324                    pw.print(" pid=");
9325                    if (r.app != null) pw.println(r.app.pid);
9326                    else pw.println("(not running)");
9327            if (dumpAll) {
9328                r.dump(pw, innerPrefix);
9329            }
9330        }
9331        if (r.app != null && r.app.thread != null) {
9332            // flush anything that is already in the PrintWriter since the thread is going
9333            // to write to the file descriptor directly
9334            pw.flush();
9335            try {
9336                TransferPipe tp = new TransferPipe();
9337                try {
9338                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9339                            r.appToken, innerPrefix, args);
9340                    tp.go(fd);
9341                } finally {
9342                    tp.kill();
9343                }
9344            } catch (IOException e) {
9345                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9346            } catch (RemoteException e) {
9347                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9348            }
9349        }
9350    }
9351
9352    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9353            int opti, boolean dumpAll, String dumpPackage) {
9354        boolean needSep = false;
9355
9356        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9357        if (dumpAll) {
9358            if (mRegisteredReceivers.size() > 0) {
9359                boolean printed = false;
9360                Iterator it = mRegisteredReceivers.values().iterator();
9361                while (it.hasNext()) {
9362                    ReceiverList r = (ReceiverList)it.next();
9363                    if (dumpPackage != null && (r.app == null ||
9364                            !dumpPackage.equals(r.app.info.packageName))) {
9365                        continue;
9366                    }
9367                    if (!printed) {
9368                        pw.println("  Registered Receivers:");
9369                        needSep = true;
9370                        printed = true;
9371                    }
9372                    pw.print("  * "); pw.println(r);
9373                    r.dump(pw, "    ");
9374                }
9375            }
9376
9377            if (mReceiverResolver.dump(pw, needSep ?
9378                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9379                    "    ", dumpPackage, false)) {
9380                needSep = true;
9381            }
9382        }
9383
9384        for (BroadcastQueue q : mBroadcastQueues) {
9385            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9386        }
9387
9388        needSep = true;
9389
9390        if (mStickyBroadcasts != null && dumpPackage == null) {
9391            if (needSep) {
9392                pw.println();
9393            }
9394            needSep = true;
9395            pw.println("  Sticky broadcasts:");
9396            StringBuilder sb = new StringBuilder(128);
9397            for (Map.Entry<String, ArrayList<Intent>> ent
9398                    : mStickyBroadcasts.entrySet()) {
9399                pw.print("  * Sticky action "); pw.print(ent.getKey());
9400                if (dumpAll) {
9401                    pw.println(":");
9402                    ArrayList<Intent> intents = ent.getValue();
9403                    final int N = intents.size();
9404                    for (int i=0; i<N; i++) {
9405                        sb.setLength(0);
9406                        sb.append("    Intent: ");
9407                        intents.get(i).toShortString(sb, false, true, false, false);
9408                        pw.println(sb.toString());
9409                        Bundle bundle = intents.get(i).getExtras();
9410                        if (bundle != null) {
9411                            pw.print("      ");
9412                            pw.println(bundle.toString());
9413                        }
9414                    }
9415                } else {
9416                    pw.println("");
9417                }
9418            }
9419            needSep = true;
9420        }
9421
9422        if (dumpAll) {
9423            pw.println();
9424            for (BroadcastQueue queue : mBroadcastQueues) {
9425                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9426                        + queue.mBroadcastsScheduled);
9427            }
9428            pw.println("  mHandler:");
9429            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9430            needSep = true;
9431        }
9432
9433        return needSep;
9434    }
9435
9436    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9437            int opti, boolean dumpAll, String dumpPackage) {
9438        boolean needSep = true;
9439
9440        ItemMatcher matcher = new ItemMatcher();
9441        matcher.build(args, opti);
9442
9443        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9444
9445        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9446
9447        if (mLaunchingProviders.size() > 0) {
9448            boolean printed = false;
9449            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9450                ContentProviderRecord r = mLaunchingProviders.get(i);
9451                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9452                    continue;
9453                }
9454                if (!printed) {
9455                    if (needSep) pw.println(" ");
9456                    needSep = true;
9457                    pw.println("  Launching content providers:");
9458                    printed = true;
9459                }
9460                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9461                        pw.println(r);
9462            }
9463        }
9464
9465        if (mGrantedUriPermissions.size() > 0) {
9466            if (needSep) pw.println();
9467            needSep = true;
9468            pw.println("Granted Uri Permissions:");
9469            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9470                int uid = mGrantedUriPermissions.keyAt(i);
9471                HashMap<Uri, UriPermission> perms
9472                        = mGrantedUriPermissions.valueAt(i);
9473                pw.print("  * UID "); pw.print(uid);
9474                        pw.println(" holds:");
9475                for (UriPermission perm : perms.values()) {
9476                    pw.print("    "); pw.println(perm);
9477                    if (dumpAll) {
9478                        perm.dump(pw, "      ");
9479                    }
9480                }
9481            }
9482            needSep = true;
9483        }
9484
9485        return needSep;
9486    }
9487
9488    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9489            int opti, boolean dumpAll, String dumpPackage) {
9490        boolean needSep = false;
9491
9492        if (mIntentSenderRecords.size() > 0) {
9493            boolean printed = false;
9494            Iterator<WeakReference<PendingIntentRecord>> it
9495                    = mIntentSenderRecords.values().iterator();
9496            while (it.hasNext()) {
9497                WeakReference<PendingIntentRecord> ref = it.next();
9498                PendingIntentRecord rec = ref != null ? ref.get(): null;
9499                if (dumpPackage != null && (rec == null
9500                        || !dumpPackage.equals(rec.key.packageName))) {
9501                    continue;
9502                }
9503                if (!printed) {
9504                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9505                    printed = true;
9506                }
9507                needSep = true;
9508                if (rec != null) {
9509                    pw.print("  * "); pw.println(rec);
9510                    if (dumpAll) {
9511                        rec.dump(pw, "    ");
9512                    }
9513                } else {
9514                    pw.print("  * "); pw.println(ref);
9515                }
9516            }
9517        }
9518
9519        return needSep;
9520    }
9521
9522    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9523            String prefix, String label, boolean complete, boolean brief, boolean client,
9524            String dumpPackage) {
9525        TaskRecord lastTask = null;
9526        boolean needNL = false;
9527        final String innerPrefix = prefix + "      ";
9528        final String[] args = new String[0];
9529        for (int i=list.size()-1; i>=0; i--) {
9530            final ActivityRecord r = (ActivityRecord)list.get(i);
9531            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9532                continue;
9533            }
9534            final boolean full = !brief && (complete || !r.isInHistory());
9535            if (needNL) {
9536                pw.println(" ");
9537                needNL = false;
9538            }
9539            if (lastTask != r.task) {
9540                lastTask = r.task;
9541                pw.print(prefix);
9542                pw.print(full ? "* " : "  ");
9543                pw.println(lastTask);
9544                if (full) {
9545                    lastTask.dump(pw, prefix + "  ");
9546                } else if (complete) {
9547                    // Complete + brief == give a summary.  Isn't that obvious?!?
9548                    if (lastTask.intent != null) {
9549                        pw.print(prefix); pw.print("  ");
9550                                pw.println(lastTask.intent.toInsecureStringWithClip());
9551                    }
9552                }
9553            }
9554            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9555            pw.print(" #"); pw.print(i); pw.print(": ");
9556            pw.println(r);
9557            if (full) {
9558                r.dump(pw, innerPrefix);
9559            } else if (complete) {
9560                // Complete + brief == give a summary.  Isn't that obvious?!?
9561                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9562                if (r.app != null) {
9563                    pw.print(innerPrefix); pw.println(r.app);
9564                }
9565            }
9566            if (client && r.app != null && r.app.thread != null) {
9567                // flush anything that is already in the PrintWriter since the thread is going
9568                // to write to the file descriptor directly
9569                pw.flush();
9570                try {
9571                    TransferPipe tp = new TransferPipe();
9572                    try {
9573                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9574                                r.appToken, innerPrefix, args);
9575                        // Short timeout, since blocking here can
9576                        // deadlock with the application.
9577                        tp.go(fd, 2000);
9578                    } finally {
9579                        tp.kill();
9580                    }
9581                } catch (IOException e) {
9582                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9583                } catch (RemoteException e) {
9584                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9585                }
9586                needNL = true;
9587            }
9588        }
9589    }
9590
9591    private static String buildOomTag(String prefix, String space, int val, int base) {
9592        if (val == base) {
9593            if (space == null) return prefix;
9594            return prefix + "  ";
9595        }
9596        return prefix + "+" + Integer.toString(val-base);
9597    }
9598
9599    private static final int dumpProcessList(PrintWriter pw,
9600            ActivityManagerService service, List list,
9601            String prefix, String normalLabel, String persistentLabel,
9602            String dumpPackage) {
9603        int numPers = 0;
9604        final int N = list.size()-1;
9605        for (int i=N; i>=0; i--) {
9606            ProcessRecord r = (ProcessRecord)list.get(i);
9607            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9608                continue;
9609            }
9610            pw.println(String.format("%s%s #%2d: %s",
9611                    prefix, (r.persistent ? persistentLabel : normalLabel),
9612                    i, r.toString()));
9613            if (r.persistent) {
9614                numPers++;
9615            }
9616        }
9617        return numPers;
9618    }
9619
9620    private static final boolean dumpProcessOomList(PrintWriter pw,
9621            ActivityManagerService service, List<ProcessRecord> origList,
9622            String prefix, String normalLabel, String persistentLabel,
9623            boolean inclDetails, String dumpPackage) {
9624
9625        ArrayList<Pair<ProcessRecord, Integer>> list
9626                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9627        for (int i=0; i<origList.size(); i++) {
9628            ProcessRecord r = origList.get(i);
9629            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9630                continue;
9631            }
9632            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9633        }
9634
9635        if (list.size() <= 0) {
9636            return false;
9637        }
9638
9639        Comparator<Pair<ProcessRecord, Integer>> comparator
9640                = new Comparator<Pair<ProcessRecord, Integer>>() {
9641            @Override
9642            public int compare(Pair<ProcessRecord, Integer> object1,
9643                    Pair<ProcessRecord, Integer> object2) {
9644                if (object1.first.setAdj != object2.first.setAdj) {
9645                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9646                }
9647                if (object1.second.intValue() != object2.second.intValue()) {
9648                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9649                }
9650                return 0;
9651            }
9652        };
9653
9654        Collections.sort(list, comparator);
9655
9656        final long curRealtime = SystemClock.elapsedRealtime();
9657        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9658        final long curUptime = SystemClock.uptimeMillis();
9659        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9660
9661        for (int i=list.size()-1; i>=0; i--) {
9662            ProcessRecord r = list.get(i).first;
9663            String oomAdj;
9664            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9665                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9666            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9667                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9668            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9669                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9670            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9671                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9672            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9673                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9674            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9675                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9676            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9677                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9678            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9679                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9680            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9681                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9682            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9683                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9684            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9685                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9686            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9687                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9688            } else {
9689                oomAdj = Integer.toString(r.setAdj);
9690            }
9691            String schedGroup;
9692            switch (r.setSchedGroup) {
9693                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9694                    schedGroup = "B";
9695                    break;
9696                case Process.THREAD_GROUP_DEFAULT:
9697                    schedGroup = "F";
9698                    break;
9699                default:
9700                    schedGroup = Integer.toString(r.setSchedGroup);
9701                    break;
9702            }
9703            String foreground;
9704            if (r.foregroundActivities) {
9705                foreground = "A";
9706            } else if (r.foregroundServices) {
9707                foreground = "S";
9708            } else {
9709                foreground = " ";
9710            }
9711            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9712                    prefix, (r.persistent ? persistentLabel : normalLabel),
9713                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9714                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9715            if (r.adjSource != null || r.adjTarget != null) {
9716                pw.print(prefix);
9717                pw.print("    ");
9718                if (r.adjTarget instanceof ComponentName) {
9719                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9720                } else if (r.adjTarget != null) {
9721                    pw.print(r.adjTarget.toString());
9722                } else {
9723                    pw.print("{null}");
9724                }
9725                pw.print("<=");
9726                if (r.adjSource instanceof ProcessRecord) {
9727                    pw.print("Proc{");
9728                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9729                    pw.println("}");
9730                } else if (r.adjSource != null) {
9731                    pw.println(r.adjSource.toString());
9732                } else {
9733                    pw.println("{null}");
9734                }
9735            }
9736            if (inclDetails) {
9737                pw.print(prefix);
9738                pw.print("    ");
9739                pw.print("oom: max="); pw.print(r.maxAdj);
9740                pw.print(" hidden="); pw.print(r.hiddenAdj);
9741                pw.print(" curRaw="); pw.print(r.curRawAdj);
9742                pw.print(" setRaw="); pw.print(r.setRawAdj);
9743                pw.print(" cur="); pw.print(r.curAdj);
9744                pw.print(" set="); pw.println(r.setAdj);
9745                pw.print(prefix);
9746                pw.print("    ");
9747                pw.print("keeping="); pw.print(r.keeping);
9748                pw.print(" hidden="); pw.print(r.hidden);
9749                pw.print(" empty="); pw.print(r.empty);
9750                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9751
9752                if (!r.keeping) {
9753                    if (r.lastWakeTime != 0) {
9754                        long wtime;
9755                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9756                        synchronized (stats) {
9757                            wtime = stats.getProcessWakeTime(r.info.uid,
9758                                    r.pid, curRealtime);
9759                        }
9760                        long timeUsed = wtime - r.lastWakeTime;
9761                        pw.print(prefix);
9762                        pw.print("    ");
9763                        pw.print("keep awake over ");
9764                        TimeUtils.formatDuration(realtimeSince, pw);
9765                        pw.print(" used ");
9766                        TimeUtils.formatDuration(timeUsed, pw);
9767                        pw.print(" (");
9768                        pw.print((timeUsed*100)/realtimeSince);
9769                        pw.println("%)");
9770                    }
9771                    if (r.lastCpuTime != 0) {
9772                        long timeUsed = r.curCpuTime - r.lastCpuTime;
9773                        pw.print(prefix);
9774                        pw.print("    ");
9775                        pw.print("run cpu over ");
9776                        TimeUtils.formatDuration(uptimeSince, pw);
9777                        pw.print(" used ");
9778                        TimeUtils.formatDuration(timeUsed, pw);
9779                        pw.print(" (");
9780                        pw.print((timeUsed*100)/uptimeSince);
9781                        pw.println("%)");
9782                    }
9783                }
9784            }
9785        }
9786        return true;
9787    }
9788
9789    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
9790        ArrayList<ProcessRecord> procs;
9791        synchronized (this) {
9792            if (args != null && args.length > start
9793                    && args[start].charAt(0) != '-') {
9794                procs = new ArrayList<ProcessRecord>();
9795                int pid = -1;
9796                try {
9797                    pid = Integer.parseInt(args[start]);
9798                } catch (NumberFormatException e) {
9799
9800                }
9801                for (int i=mLruProcesses.size()-1; i>=0; i--) {
9802                    ProcessRecord proc = mLruProcesses.get(i);
9803                    if (proc.pid == pid) {
9804                        procs.add(proc);
9805                    } else if (proc.processName.equals(args[start])) {
9806                        procs.add(proc);
9807                    }
9808                }
9809                if (procs.size() <= 0) {
9810                    pw.println("No process found for: " + args[start]);
9811                    return null;
9812                }
9813            } else {
9814                procs = new ArrayList<ProcessRecord>(mLruProcesses);
9815            }
9816        }
9817        return procs;
9818    }
9819
9820    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9821            PrintWriter pw, String[] args) {
9822        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9823        if (procs == null) {
9824            return;
9825        }
9826
9827        long uptime = SystemClock.uptimeMillis();
9828        long realtime = SystemClock.elapsedRealtime();
9829        pw.println("Applications Graphics Acceleration Info:");
9830        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9831
9832        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9833            ProcessRecord r = procs.get(i);
9834            if (r.thread != null) {
9835                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9836                pw.flush();
9837                try {
9838                    TransferPipe tp = new TransferPipe();
9839                    try {
9840                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9841                        tp.go(fd);
9842                    } finally {
9843                        tp.kill();
9844                    }
9845                } catch (IOException e) {
9846                    pw.println("Failure while dumping the app: " + r);
9847                    pw.flush();
9848                } catch (RemoteException e) {
9849                    pw.println("Got a RemoteException while dumping the app " + r);
9850                    pw.flush();
9851                }
9852            }
9853        }
9854    }
9855
9856    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
9857        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9858        if (procs == null) {
9859            return;
9860        }
9861
9862        pw.println("Applications Database Info:");
9863
9864        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9865            ProcessRecord r = procs.get(i);
9866            if (r.thread != null) {
9867                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
9868                pw.flush();
9869                try {
9870                    TransferPipe tp = new TransferPipe();
9871                    try {
9872                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
9873                        tp.go(fd);
9874                    } finally {
9875                        tp.kill();
9876                    }
9877                } catch (IOException e) {
9878                    pw.println("Failure while dumping the app: " + r);
9879                    pw.flush();
9880                } catch (RemoteException e) {
9881                    pw.println("Got a RemoteException while dumping the app " + r);
9882                    pw.flush();
9883                }
9884            }
9885        }
9886    }
9887
9888    final static class MemItem {
9889        final String label;
9890        final String shortLabel;
9891        final long pss;
9892        final int id;
9893        ArrayList<MemItem> subitems;
9894
9895        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
9896            label = _label;
9897            shortLabel = _shortLabel;
9898            pss = _pss;
9899            id = _id;
9900        }
9901    }
9902
9903    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9904            boolean sort) {
9905        if (sort) {
9906            Collections.sort(items, new Comparator<MemItem>() {
9907                @Override
9908                public int compare(MemItem lhs, MemItem rhs) {
9909                    if (lhs.pss < rhs.pss) {
9910                        return 1;
9911                    } else if (lhs.pss > rhs.pss) {
9912                        return -1;
9913                    }
9914                    return 0;
9915                }
9916            });
9917        }
9918
9919        for (int i=0; i<items.size(); i++) {
9920            MemItem mi = items.get(i);
9921            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
9922            if (mi.subitems != null) {
9923                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
9924            }
9925        }
9926    }
9927
9928    // These are in KB.
9929    static final long[] DUMP_MEM_BUCKETS = new long[] {
9930        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9931        120*1024, 160*1024, 200*1024,
9932        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9933        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9934    };
9935
9936    static final void appendMemBucket(StringBuilder out, long memKB, String label,
9937            boolean stackLike) {
9938        int start = label.lastIndexOf('.');
9939        if (start >= 0) start++;
9940        else start = 0;
9941        int end = label.length();
9942        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
9943            if (DUMP_MEM_BUCKETS[i] >= memKB) {
9944                long bucket = DUMP_MEM_BUCKETS[i]/1024;
9945                out.append(bucket);
9946                out.append(stackLike ? "MB." : "MB ");
9947                out.append(label, start, end);
9948                return;
9949            }
9950        }
9951        out.append(memKB/1024);
9952        out.append(stackLike ? "MB." : "MB ");
9953        out.append(label, start, end);
9954    }
9955
9956    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
9957            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9958            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9959            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
9960            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
9961    };
9962    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
9963            "System", "Persistent", "Foreground",
9964            "Visible", "Perceptible", "Heavy Weight",
9965            "Backup", "A Services", "Home", "Previous",
9966            "B Services", "Background"
9967    };
9968
9969    final void dumpApplicationMemoryUsage(FileDescriptor fd,
9970            PrintWriter pw, String prefix, String[] args, boolean brief,
9971            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
9972        boolean dumpAll = false;
9973        boolean oomOnly = false;
9974
9975        int opti = 0;
9976        while (opti < args.length) {
9977            String opt = args[opti];
9978            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9979                break;
9980            }
9981            opti++;
9982            if ("-a".equals(opt)) {
9983                dumpAll = true;
9984            } else if ("--oom".equals(opt)) {
9985                oomOnly = true;
9986            } else if ("-h".equals(opt)) {
9987                pw.println("meminfo dump options: [-a] [--oom] [process]");
9988                pw.println("  -a: include all available information for each process.");
9989                pw.println("  --oom: only show processes organized by oom adj.");
9990                pw.println("If [process] is specified it can be the name or ");
9991                pw.println("pid of a specific process to dump.");
9992                return;
9993            } else {
9994                pw.println("Unknown argument: " + opt + "; use -h for help");
9995            }
9996        }
9997
9998        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
9999        if (procs == null) {
10000            return;
10001        }
10002
10003        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10004        long uptime = SystemClock.uptimeMillis();
10005        long realtime = SystemClock.elapsedRealtime();
10006
10007        if (procs.size() == 1 || isCheckinRequest) {
10008            dumpAll = true;
10009        }
10010
10011        if (isCheckinRequest) {
10012            // short checkin version
10013            pw.println(uptime + "," + realtime);
10014            pw.flush();
10015        } else {
10016            pw.println("Applications Memory Usage (kB):");
10017            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10018        }
10019
10020        String[] innerArgs = new String[args.length-opti];
10021        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10022
10023        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10024        long nativePss=0, dalvikPss=0, otherPss=0;
10025        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10026
10027        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10028        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10029                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10030
10031        long totalPss = 0;
10032
10033        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10034            ProcessRecord r = procs.get(i);
10035            if (r.thread != null) {
10036                if (!isCheckinRequest && dumpAll) {
10037                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10038                    pw.flush();
10039                }
10040                Debug.MemoryInfo mi = null;
10041                if (dumpAll) {
10042                    try {
10043                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10044                    } catch (RemoteException e) {
10045                        if (!isCheckinRequest) {
10046                            pw.println("Got RemoteException!");
10047                            pw.flush();
10048                        }
10049                    }
10050                } else {
10051                    mi = new Debug.MemoryInfo();
10052                    Debug.getMemoryInfo(r.pid, mi);
10053                }
10054
10055                if (!isCheckinRequest && mi != null) {
10056                    long myTotalPss = mi.getTotalPss();
10057                    totalPss += myTotalPss;
10058                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10059                            r.processName, myTotalPss, 0);
10060                    procMems.add(pssItem);
10061
10062                    nativePss += mi.nativePss;
10063                    dalvikPss += mi.dalvikPss;
10064                    otherPss += mi.otherPss;
10065                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10066                        long mem = mi.getOtherPss(j);
10067                        miscPss[j] += mem;
10068                        otherPss -= mem;
10069                    }
10070
10071                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10072                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10073                                || oomIndex == (oomPss.length-1)) {
10074                            oomPss[oomIndex] += myTotalPss;
10075                            if (oomProcs[oomIndex] == null) {
10076                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10077                            }
10078                            oomProcs[oomIndex].add(pssItem);
10079                            break;
10080                        }
10081                    }
10082                }
10083            }
10084        }
10085
10086        if (!isCheckinRequest && procs.size() > 1) {
10087            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10088
10089            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10090            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10091            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10092            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10093                String label = Debug.MemoryInfo.getOtherLabel(j);
10094                catMems.add(new MemItem(label, label, miscPss[j], j));
10095            }
10096
10097            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10098            for (int j=0; j<oomPss.length; j++) {
10099                if (oomPss[j] != 0) {
10100                    String label = DUMP_MEM_OOM_LABEL[j];
10101                    MemItem item = new MemItem(label, label, oomPss[j],
10102                            DUMP_MEM_OOM_ADJ[j]);
10103                    item.subitems = oomProcs[j];
10104                    oomMems.add(item);
10105                }
10106            }
10107
10108            if (outTag != null || outStack != null) {
10109                if (outTag != null) {
10110                    appendMemBucket(outTag, totalPss, "total", false);
10111                }
10112                if (outStack != null) {
10113                    appendMemBucket(outStack, totalPss, "total", true);
10114                }
10115                boolean firstLine = true;
10116                for (int i=0; i<oomMems.size(); i++) {
10117                    MemItem miCat = oomMems.get(i);
10118                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10119                        continue;
10120                    }
10121                    if (miCat.id < ProcessList.SERVICE_ADJ
10122                            || miCat.id == ProcessList.HOME_APP_ADJ
10123                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10124                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10125                            outTag.append(" / ");
10126                        }
10127                        if (outStack != null) {
10128                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10129                                if (firstLine) {
10130                                    outStack.append(":");
10131                                    firstLine = false;
10132                                }
10133                                outStack.append("\n\t at ");
10134                            } else {
10135                                outStack.append("$");
10136                            }
10137                        }
10138                        for (int j=0; j<miCat.subitems.size(); j++) {
10139                            MemItem mi = miCat.subitems.get(j);
10140                            if (j > 0) {
10141                                if (outTag != null) {
10142                                    outTag.append(" ");
10143                                }
10144                                if (outStack != null) {
10145                                    outStack.append("$");
10146                                }
10147                            }
10148                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10149                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10150                            }
10151                            if (outStack != null) {
10152                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10153                            }
10154                        }
10155                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10156                            outStack.append("(");
10157                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10158                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10159                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10160                                    outStack.append(":");
10161                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10162                                }
10163                            }
10164                            outStack.append(")");
10165                        }
10166                    }
10167                }
10168            }
10169
10170            if (!brief && !oomOnly) {
10171                pw.println();
10172                pw.println("Total PSS by process:");
10173                dumpMemItems(pw, "  ", procMems, true);
10174                pw.println();
10175            }
10176            pw.println("Total PSS by OOM adjustment:");
10177            dumpMemItems(pw, "  ", oomMems, false);
10178            if (!oomOnly) {
10179                PrintWriter out = categoryPw != null ? categoryPw : pw;
10180                out.println();
10181                out.println("Total PSS by category:");
10182                dumpMemItems(out, "  ", catMems, true);
10183            }
10184            pw.println();
10185            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10186            final int[] SINGLE_LONG_FORMAT = new int[] {
10187                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10188            };
10189            long[] longOut = new long[1];
10190            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10191                    SINGLE_LONG_FORMAT, null, longOut, null);
10192            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10193            longOut[0] = 0;
10194            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10195                    SINGLE_LONG_FORMAT, null, longOut, null);
10196            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10197            longOut[0] = 0;
10198            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10199                    SINGLE_LONG_FORMAT, null, longOut, null);
10200            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10201            longOut[0] = 0;
10202            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10203                    SINGLE_LONG_FORMAT, null, longOut, null);
10204            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10205            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10206                    pw.print(shared); pw.println(" kB");
10207            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10208                    pw.print(voltile); pw.println(" kB volatile");
10209        }
10210    }
10211
10212    /**
10213     * Searches array of arguments for the specified string
10214     * @param args array of argument strings
10215     * @param value value to search for
10216     * @return true if the value is contained in the array
10217     */
10218    private static boolean scanArgs(String[] args, String value) {
10219        if (args != null) {
10220            for (String arg : args) {
10221                if (value.equals(arg)) {
10222                    return true;
10223                }
10224            }
10225        }
10226        return false;
10227    }
10228
10229    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10230            ContentProviderRecord cpr, boolean always) {
10231        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10232
10233        if (!inLaunching || always) {
10234            synchronized (cpr) {
10235                cpr.launchingApp = null;
10236                cpr.notifyAll();
10237            }
10238            mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid));
10239            String names[] = cpr.info.authority.split(";");
10240            for (int j = 0; j < names.length; j++) {
10241                mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid));
10242            }
10243        }
10244
10245        for (int i=0; i<cpr.connections.size(); i++) {
10246            ContentProviderConnection conn = cpr.connections.get(i);
10247            if (conn.waiting) {
10248                // If this connection is waiting for the provider, then we don't
10249                // need to mess with its process unless we are always removing
10250                // or for some reason the provider is not currently launching.
10251                if (inLaunching && !always) {
10252                    continue;
10253                }
10254            }
10255            ProcessRecord capp = conn.client;
10256            conn.dead = true;
10257            if (conn.stableCount > 0) {
10258                if (!capp.persistent && capp.thread != null
10259                        && capp.pid != 0
10260                        && capp.pid != MY_PID) {
10261                    Slog.i(TAG, "Kill " + capp.processName
10262                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10263                            + " in dying process " + (proc != null ? proc.processName : "??"));
10264                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10265                            capp.processName, capp.setAdj, "dying provider "
10266                                    + cpr.name.toShortString());
10267                    Process.killProcessQuiet(capp.pid);
10268                }
10269            } else if (capp.thread != null && conn.provider.provider != null) {
10270                try {
10271                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10272                } catch (RemoteException e) {
10273                }
10274                // In the protocol here, we don't expect the client to correctly
10275                // clean up this connection, we'll just remove it.
10276                cpr.connections.remove(i);
10277                conn.client.conProviders.remove(conn);
10278            }
10279        }
10280
10281        if (inLaunching && always) {
10282            mLaunchingProviders.remove(cpr);
10283        }
10284        return inLaunching;
10285    }
10286
10287    /**
10288     * Main code for cleaning up a process when it has gone away.  This is
10289     * called both as a result of the process dying, or directly when stopping
10290     * a process when running in single process mode.
10291     */
10292    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10293            boolean restarting, boolean allowRestart, int index) {
10294        if (index >= 0) {
10295            mLruProcesses.remove(index);
10296        }
10297
10298        mProcessesToGc.remove(app);
10299
10300        // Dismiss any open dialogs.
10301        if (app.crashDialog != null) {
10302            app.crashDialog.dismiss();
10303            app.crashDialog = null;
10304        }
10305        if (app.anrDialog != null) {
10306            app.anrDialog.dismiss();
10307            app.anrDialog = null;
10308        }
10309        if (app.waitDialog != null) {
10310            app.waitDialog.dismiss();
10311            app.waitDialog = null;
10312        }
10313
10314        app.crashing = false;
10315        app.notResponding = false;
10316
10317        app.resetPackageList();
10318        app.unlinkDeathRecipient();
10319        app.thread = null;
10320        app.forcingToForeground = null;
10321        app.foregroundServices = false;
10322        app.foregroundActivities = false;
10323        app.hasShownUi = false;
10324        app.hasAboveClient = false;
10325
10326        mServices.killServicesLocked(app, allowRestart);
10327
10328        boolean restart = false;
10329
10330        // Remove published content providers.
10331        if (!app.pubProviders.isEmpty()) {
10332            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10333            while (it.hasNext()) {
10334                ContentProviderRecord cpr = it.next();
10335
10336                final boolean always = app.bad || !allowRestart;
10337                if (removeDyingProviderLocked(app, cpr, always) || always) {
10338                    // We left the provider in the launching list, need to
10339                    // restart it.
10340                    restart = true;
10341                }
10342
10343                cpr.provider = null;
10344                cpr.proc = null;
10345            }
10346            app.pubProviders.clear();
10347        }
10348
10349        // Take care of any launching providers waiting for this process.
10350        if (checkAppInLaunchingProvidersLocked(app, false)) {
10351            restart = true;
10352        }
10353
10354        // Unregister from connected content providers.
10355        if (!app.conProviders.isEmpty()) {
10356            for (int i=0; i<app.conProviders.size(); i++) {
10357                ContentProviderConnection conn = app.conProviders.get(i);
10358                conn.provider.connections.remove(conn);
10359            }
10360            app.conProviders.clear();
10361        }
10362
10363        // At this point there may be remaining entries in mLaunchingProviders
10364        // where we were the only one waiting, so they are no longer of use.
10365        // Look for these and clean up if found.
10366        // XXX Commented out for now.  Trying to figure out a way to reproduce
10367        // the actual situation to identify what is actually going on.
10368        if (false) {
10369            for (int i=0; i<mLaunchingProviders.size(); i++) {
10370                ContentProviderRecord cpr = (ContentProviderRecord)
10371                        mLaunchingProviders.get(i);
10372                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10373                    synchronized (cpr) {
10374                        cpr.launchingApp = null;
10375                        cpr.notifyAll();
10376                    }
10377                }
10378            }
10379        }
10380
10381        skipCurrentReceiverLocked(app);
10382
10383        // Unregister any receivers.
10384        if (app.receivers.size() > 0) {
10385            Iterator<ReceiverList> it = app.receivers.iterator();
10386            while (it.hasNext()) {
10387                removeReceiverLocked(it.next());
10388            }
10389            app.receivers.clear();
10390        }
10391
10392        // If the app is undergoing backup, tell the backup manager about it
10393        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10394            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10395            try {
10396                IBackupManager bm = IBackupManager.Stub.asInterface(
10397                        ServiceManager.getService(Context.BACKUP_SERVICE));
10398                bm.agentDisconnected(app.info.packageName);
10399            } catch (RemoteException e) {
10400                // can't happen; backup manager is local
10401            }
10402        }
10403
10404        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10405            ProcessChangeItem item = mPendingProcessChanges.get(i);
10406            if (item.pid == app.pid) {
10407                mPendingProcessChanges.remove(i);
10408                mAvailProcessChanges.add(item);
10409            }
10410        }
10411        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10412
10413        // If the caller is restarting this app, then leave it in its
10414        // current lists and let the caller take care of it.
10415        if (restarting) {
10416            return;
10417        }
10418
10419        if (!app.persistent || app.isolated) {
10420            if (DEBUG_PROCESSES) Slog.v(TAG,
10421                    "Removing non-persistent process during cleanup: " + app);
10422            mProcessNames.remove(app.processName, app.uid);
10423            mIsolatedProcesses.remove(app.uid);
10424            if (mHeavyWeightProcess == app) {
10425                mHeavyWeightProcess = null;
10426                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10427            }
10428        } else if (!app.removed) {
10429            // This app is persistent, so we need to keep its record around.
10430            // If it is not already on the pending app list, add it there
10431            // and start a new process for it.
10432            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10433                mPersistentStartingProcesses.add(app);
10434                restart = true;
10435            }
10436        }
10437        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10438                "Clean-up removing on hold: " + app);
10439        mProcessesOnHold.remove(app);
10440
10441        if (app == mHomeProcess) {
10442            mHomeProcess = null;
10443        }
10444        if (app == mPreviousProcess) {
10445            mPreviousProcess = null;
10446        }
10447
10448        if (restart && !app.isolated) {
10449            // We have components that still need to be running in the
10450            // process, so re-launch it.
10451            mProcessNames.put(app.processName, app.uid, app);
10452            startProcessLocked(app, "restart", app.processName);
10453        } else if (app.pid > 0 && app.pid != MY_PID) {
10454            // Goodbye!
10455            synchronized (mPidsSelfLocked) {
10456                mPidsSelfLocked.remove(app.pid);
10457                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10458            }
10459            app.setPid(0);
10460        }
10461    }
10462
10463    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10464        // Look through the content providers we are waiting to have launched,
10465        // and if any run in this process then either schedule a restart of
10466        // the process or kill the client waiting for it if this process has
10467        // gone bad.
10468        int NL = mLaunchingProviders.size();
10469        boolean restart = false;
10470        for (int i=0; i<NL; i++) {
10471            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10472            if (cpr.launchingApp == app) {
10473                if (!alwaysBad && !app.bad) {
10474                    restart = true;
10475                } else {
10476                    removeDyingProviderLocked(app, cpr, true);
10477                    NL = mLaunchingProviders.size();
10478                }
10479            }
10480        }
10481        return restart;
10482    }
10483
10484    // =========================================================
10485    // SERVICES
10486    // =========================================================
10487
10488    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10489            int flags) {
10490        enforceNotIsolatedCaller("getServices");
10491        synchronized (this) {
10492            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10493        }
10494    }
10495
10496    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10497        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10498        synchronized (this) {
10499            return mServices.getRunningServiceControlPanelLocked(name);
10500        }
10501    }
10502
10503    public ComponentName startService(IApplicationThread caller, Intent service,
10504            String resolvedType) {
10505        enforceNotIsolatedCaller("startService");
10506        // Refuse possible leaked file descriptors
10507        if (service != null && service.hasFileDescriptors() == true) {
10508            throw new IllegalArgumentException("File descriptors passed in Intent");
10509        }
10510
10511        if (DEBUG_SERVICE)
10512            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10513        synchronized(this) {
10514            final int callingPid = Binder.getCallingPid();
10515            final int callingUid = Binder.getCallingUid();
10516            final long origId = Binder.clearCallingIdentity();
10517            ComponentName res = mServices.startServiceLocked(caller, service,
10518                    resolvedType, callingPid, callingUid);
10519            Binder.restoreCallingIdentity(origId);
10520            return res;
10521        }
10522    }
10523
10524    ComponentName startServiceInPackage(int uid,
10525            Intent service, String resolvedType) {
10526        synchronized(this) {
10527            if (DEBUG_SERVICE)
10528                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10529            final long origId = Binder.clearCallingIdentity();
10530            ComponentName res = mServices.startServiceLocked(null, service,
10531                    resolvedType, -1, uid);
10532            Binder.restoreCallingIdentity(origId);
10533            return res;
10534        }
10535    }
10536
10537    public int stopService(IApplicationThread caller, Intent service,
10538            String resolvedType) {
10539        enforceNotIsolatedCaller("stopService");
10540        // Refuse possible leaked file descriptors
10541        if (service != null && service.hasFileDescriptors() == true) {
10542            throw new IllegalArgumentException("File descriptors passed in Intent");
10543        }
10544
10545        synchronized(this) {
10546            return mServices.stopServiceLocked(caller, service, resolvedType);
10547        }
10548    }
10549
10550    public IBinder peekService(Intent service, String resolvedType) {
10551        enforceNotIsolatedCaller("peekService");
10552        // Refuse possible leaked file descriptors
10553        if (service != null && service.hasFileDescriptors() == true) {
10554            throw new IllegalArgumentException("File descriptors passed in Intent");
10555        }
10556        synchronized(this) {
10557            return mServices.peekServiceLocked(service, resolvedType);
10558        }
10559    }
10560
10561    public boolean stopServiceToken(ComponentName className, IBinder token,
10562            int startId) {
10563        synchronized(this) {
10564            return mServices.stopServiceTokenLocked(className, token, startId);
10565        }
10566    }
10567
10568    public void setServiceForeground(ComponentName className, IBinder token,
10569            int id, Notification notification, boolean removeNotification) {
10570        synchronized(this) {
10571            mServices.setServiceForegroundLocked(className, token, id, notification,
10572                    removeNotification);
10573        }
10574    }
10575
10576    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10577            String className, int flags) {
10578        boolean result = false;
10579        if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10580            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10581                if (ActivityManager.checkUidPermission(
10582                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10583                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10584                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10585                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10586                            + " requests FLAG_SINGLE_USER, but app does not hold "
10587                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10588                    Slog.w(TAG, msg);
10589                    throw new SecurityException(msg);
10590                }
10591                result = true;
10592            }
10593        } else if (componentProcessName == aInfo.packageName) {
10594            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10595        } else if ("system".equals(componentProcessName)) {
10596            result = true;
10597        }
10598        if (DEBUG_MU) {
10599            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10600                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10601        }
10602        return result;
10603    }
10604
10605    public int bindService(IApplicationThread caller, IBinder token,
10606            Intent service, String resolvedType,
10607            IServiceConnection connection, int flags, int userId) {
10608        enforceNotIsolatedCaller("bindService");
10609        // Refuse possible leaked file descriptors
10610        if (service != null && service.hasFileDescriptors() == true) {
10611            throw new IllegalArgumentException("File descriptors passed in Intent");
10612        }
10613
10614        checkValidCaller(Binder.getCallingUid(), userId);
10615
10616        synchronized(this) {
10617            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10618                    connection, flags, userId);
10619        }
10620    }
10621
10622    public boolean unbindService(IServiceConnection connection) {
10623        synchronized (this) {
10624            return mServices.unbindServiceLocked(connection);
10625        }
10626    }
10627
10628    public void publishService(IBinder token, Intent intent, IBinder service) {
10629        // Refuse possible leaked file descriptors
10630        if (intent != null && intent.hasFileDescriptors() == true) {
10631            throw new IllegalArgumentException("File descriptors passed in Intent");
10632        }
10633
10634        synchronized(this) {
10635            if (!(token instanceof ServiceRecord)) {
10636                throw new IllegalArgumentException("Invalid service token");
10637            }
10638            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
10639        }
10640    }
10641
10642    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10643        // Refuse possible leaked file descriptors
10644        if (intent != null && intent.hasFileDescriptors() == true) {
10645            throw new IllegalArgumentException("File descriptors passed in Intent");
10646        }
10647
10648        synchronized(this) {
10649            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
10650        }
10651    }
10652
10653    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10654        synchronized(this) {
10655            if (!(token instanceof ServiceRecord)) {
10656                throw new IllegalArgumentException("Invalid service token");
10657            }
10658            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
10659        }
10660    }
10661
10662    // =========================================================
10663    // BACKUP AND RESTORE
10664    // =========================================================
10665
10666    // Cause the target app to be launched if necessary and its backup agent
10667    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10668    // activity manager to announce its creation.
10669    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10670        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10671        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10672
10673        synchronized(this) {
10674            // !!! TODO: currently no check here that we're already bound
10675            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10676            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10677            synchronized (stats) {
10678                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10679            }
10680
10681            // Backup agent is now in use, its package can't be stopped.
10682            try {
10683                AppGlobals.getPackageManager().setPackageStoppedState(
10684                        app.packageName, false, UserId.getUserId(app.uid));
10685            } catch (RemoteException e) {
10686            } catch (IllegalArgumentException e) {
10687                Slog.w(TAG, "Failed trying to unstop package "
10688                        + app.packageName + ": " + e);
10689            }
10690
10691            BackupRecord r = new BackupRecord(ss, app, backupMode);
10692            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10693                    ? new ComponentName(app.packageName, app.backupAgentName)
10694                    : new ComponentName("android", "FullBackupAgent");
10695            // startProcessLocked() returns existing proc's record if it's already running
10696            ProcessRecord proc = startProcessLocked(app.processName, app,
10697                    false, 0, "backup", hostingName, false, false);
10698            if (proc == null) {
10699                Slog.e(TAG, "Unable to start backup agent process " + r);
10700                return false;
10701            }
10702
10703            r.app = proc;
10704            mBackupTarget = r;
10705            mBackupAppName = app.packageName;
10706
10707            // Try not to kill the process during backup
10708            updateOomAdjLocked(proc);
10709
10710            // If the process is already attached, schedule the creation of the backup agent now.
10711            // If it is not yet live, this will be done when it attaches to the framework.
10712            if (proc.thread != null) {
10713                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
10714                try {
10715                    proc.thread.scheduleCreateBackupAgent(app,
10716                            compatibilityInfoForPackageLocked(app), backupMode);
10717                } catch (RemoteException e) {
10718                    // Will time out on the backup manager side
10719                }
10720            } else {
10721                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
10722            }
10723            // Invariants: at this point, the target app process exists and the application
10724            // is either already running or in the process of coming up.  mBackupTarget and
10725            // mBackupAppName describe the app, so that when it binds back to the AM we
10726            // know that it's scheduled for a backup-agent operation.
10727        }
10728
10729        return true;
10730    }
10731
10732    // A backup agent has just come up
10733    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10734        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
10735                + " = " + agent);
10736
10737        synchronized(this) {
10738            if (!agentPackageName.equals(mBackupAppName)) {
10739                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10740                return;
10741            }
10742        }
10743
10744        long oldIdent = Binder.clearCallingIdentity();
10745        try {
10746            IBackupManager bm = IBackupManager.Stub.asInterface(
10747                    ServiceManager.getService(Context.BACKUP_SERVICE));
10748            bm.agentConnected(agentPackageName, agent);
10749        } catch (RemoteException e) {
10750            // can't happen; the backup manager service is local
10751        } catch (Exception e) {
10752            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10753            e.printStackTrace();
10754        } finally {
10755            Binder.restoreCallingIdentity(oldIdent);
10756        }
10757    }
10758
10759    // done with this agent
10760    public void unbindBackupAgent(ApplicationInfo appInfo) {
10761        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
10762        if (appInfo == null) {
10763            Slog.w(TAG, "unbind backup agent for null app");
10764            return;
10765        }
10766
10767        synchronized(this) {
10768            if (mBackupAppName == null) {
10769                Slog.w(TAG, "Unbinding backup agent with no active backup");
10770                return;
10771            }
10772
10773            if (!mBackupAppName.equals(appInfo.packageName)) {
10774                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
10775                return;
10776            }
10777
10778            ProcessRecord proc = mBackupTarget.app;
10779            mBackupTarget = null;
10780            mBackupAppName = null;
10781
10782            // Not backing this app up any more; reset its OOM adjustment
10783            updateOomAdjLocked(proc);
10784
10785            // If the app crashed during backup, 'thread' will be null here
10786            if (proc.thread != null) {
10787                try {
10788                    proc.thread.scheduleDestroyBackupAgent(appInfo,
10789                            compatibilityInfoForPackageLocked(appInfo));
10790                } catch (Exception e) {
10791                    Slog.e(TAG, "Exception when unbinding backup agent:");
10792                    e.printStackTrace();
10793                }
10794            }
10795        }
10796    }
10797    // =========================================================
10798    // BROADCASTS
10799    // =========================================================
10800
10801    private final List getStickiesLocked(String action, IntentFilter filter,
10802            List cur) {
10803        final ContentResolver resolver = mContext.getContentResolver();
10804        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10805        if (list == null) {
10806            return cur;
10807        }
10808        int N = list.size();
10809        for (int i=0; i<N; i++) {
10810            Intent intent = list.get(i);
10811            if (filter.match(resolver, intent, true, TAG) >= 0) {
10812                if (cur == null) {
10813                    cur = new ArrayList<Intent>();
10814                }
10815                cur.add(intent);
10816            }
10817        }
10818        return cur;
10819    }
10820
10821    boolean isPendingBroadcastProcessLocked(int pid) {
10822        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
10823                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
10824    }
10825
10826    void skipPendingBroadcastLocked(int pid) {
10827            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
10828            for (BroadcastQueue queue : mBroadcastQueues) {
10829                queue.skipPendingBroadcastLocked(pid);
10830            }
10831    }
10832
10833    // The app just attached; send any pending broadcasts that it should receive
10834    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
10835        boolean didSomething = false;
10836        for (BroadcastQueue queue : mBroadcastQueues) {
10837            didSomething |= queue.sendPendingBroadcastsLocked(app);
10838        }
10839        return didSomething;
10840    }
10841
10842    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
10843            IIntentReceiver receiver, IntentFilter filter, String permission) {
10844        enforceNotIsolatedCaller("registerReceiver");
10845        int callingUid;
10846        synchronized(this) {
10847            ProcessRecord callerApp = null;
10848            if (caller != null) {
10849                callerApp = getRecordForAppLocked(caller);
10850                if (callerApp == null) {
10851                    throw new SecurityException(
10852                            "Unable to find app for caller " + caller
10853                            + " (pid=" + Binder.getCallingPid()
10854                            + ") when registering receiver " + receiver);
10855                }
10856                if (callerApp.info.uid != Process.SYSTEM_UID &&
10857                        !callerApp.pkgList.contains(callerPackage)) {
10858                    throw new SecurityException("Given caller package " + callerPackage
10859                            + " is not running in process " + callerApp);
10860                }
10861                callingUid = callerApp.info.uid;
10862            } else {
10863                callerPackage = null;
10864                callingUid = Binder.getCallingUid();
10865            }
10866
10867            List allSticky = null;
10868
10869            // Look for any matching sticky broadcasts...
10870            Iterator actions = filter.actionsIterator();
10871            if (actions != null) {
10872                while (actions.hasNext()) {
10873                    String action = (String)actions.next();
10874                    allSticky = getStickiesLocked(action, filter, allSticky);
10875                }
10876            } else {
10877                allSticky = getStickiesLocked(null, filter, allSticky);
10878            }
10879
10880            // The first sticky in the list is returned directly back to
10881            // the client.
10882            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10883
10884            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
10885                    + ": " + sticky);
10886
10887            if (receiver == null) {
10888                return sticky;
10889            }
10890
10891            ReceiverList rl
10892                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10893            if (rl == null) {
10894                rl = new ReceiverList(this, callerApp,
10895                        Binder.getCallingPid(),
10896                        Binder.getCallingUid(), receiver);
10897                if (rl.app != null) {
10898                    rl.app.receivers.add(rl);
10899                } else {
10900                    try {
10901                        receiver.asBinder().linkToDeath(rl, 0);
10902                    } catch (RemoteException e) {
10903                        return sticky;
10904                    }
10905                    rl.linkedToDeath = true;
10906                }
10907                mRegisteredReceivers.put(receiver.asBinder(), rl);
10908            }
10909            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
10910                    permission, callingUid);
10911            rl.add(bf);
10912            if (!bf.debugCheck()) {
10913                Slog.w(TAG, "==> For Dynamic broadast");
10914            }
10915            mReceiverResolver.addFilter(bf);
10916
10917            // Enqueue broadcasts for all existing stickies that match
10918            // this filter.
10919            if (allSticky != null) {
10920                ArrayList receivers = new ArrayList();
10921                receivers.add(bf);
10922
10923                int N = allSticky.size();
10924                for (int i=0; i<N; i++) {
10925                    Intent intent = (Intent)allSticky.get(i);
10926                    BroadcastQueue queue = broadcastQueueForIntent(intent);
10927                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
10928                            null, -1, -1, null, receivers, null, 0, null, null,
10929                            false, true, true, false);
10930                    queue.enqueueParallelBroadcastLocked(r);
10931                    queue.scheduleBroadcastsLocked();
10932                }
10933            }
10934
10935            return sticky;
10936        }
10937    }
10938
10939    public void unregisterReceiver(IIntentReceiver receiver) {
10940        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
10941
10942        final long origId = Binder.clearCallingIdentity();
10943        try {
10944            boolean doTrim = false;
10945
10946            synchronized(this) {
10947                ReceiverList rl
10948                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10949                if (rl != null) {
10950                    if (rl.curBroadcast != null) {
10951                        BroadcastRecord r = rl.curBroadcast;
10952                        final boolean doNext = finishReceiverLocked(
10953                                receiver.asBinder(), r.resultCode, r.resultData,
10954                                r.resultExtras, r.resultAbort, true);
10955                        if (doNext) {
10956                            doTrim = true;
10957                            r.queue.processNextBroadcast(false);
10958                        }
10959                    }
10960
10961                    if (rl.app != null) {
10962                        rl.app.receivers.remove(rl);
10963                    }
10964                    removeReceiverLocked(rl);
10965                    if (rl.linkedToDeath) {
10966                        rl.linkedToDeath = false;
10967                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
10968                    }
10969                }
10970            }
10971
10972            // If we actually concluded any broadcasts, we might now be able
10973            // to trim the recipients' apps from our working set
10974            if (doTrim) {
10975                trimApplications();
10976                return;
10977            }
10978
10979        } finally {
10980            Binder.restoreCallingIdentity(origId);
10981        }
10982    }
10983
10984    void removeReceiverLocked(ReceiverList rl) {
10985        mRegisteredReceivers.remove(rl.receiver.asBinder());
10986        int N = rl.size();
10987        for (int i=0; i<N; i++) {
10988            mReceiverResolver.removeFilter(rl.get(i));
10989        }
10990    }
10991
10992    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
10993        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10994            ProcessRecord r = mLruProcesses.get(i);
10995            if (r.thread != null) {
10996                try {
10997                    r.thread.dispatchPackageBroadcast(cmd, packages);
10998                } catch (RemoteException ex) {
10999                }
11000            }
11001        }
11002    }
11003
11004    private final int broadcastIntentLocked(ProcessRecord callerApp,
11005            String callerPackage, Intent intent, String resolvedType,
11006            IIntentReceiver resultTo, int resultCode, String resultData,
11007            Bundle map, String requiredPermission,
11008            boolean ordered, boolean sticky, int callingPid, int callingUid,
11009            int userId) {
11010        intent = new Intent(intent);
11011
11012        // By default broadcasts do not go to stopped apps.
11013        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11014
11015        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11016            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11017            + " ordered=" + ordered + " userid=" + userId);
11018        if ((resultTo != null) && !ordered) {
11019            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11020        }
11021
11022        boolean onlySendToCaller = false;
11023
11024        // If the caller is trying to send this broadcast to a different
11025        // user, verify that is allowed.
11026        if (UserId.getUserId(callingUid) != userId) {
11027            if (checkComponentPermission(
11028                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
11029                    callingPid, callingUid, -1, true)
11030                    != PackageManager.PERMISSION_GRANTED) {
11031                if (checkComponentPermission(
11032                        android.Manifest.permission.INTERACT_ACROSS_USERS,
11033                        callingPid, callingUid, -1, true)
11034                        == PackageManager.PERMISSION_GRANTED) {
11035                    onlySendToCaller = true;
11036                } else {
11037                    String msg = "Permission Denial: " + intent.getAction()
11038                            + " broadcast from " + callerPackage
11039                            + " asks to send as user " + userId
11040                            + " but is calling from user " + UserId.getUserId(callingUid)
11041                            + "; this requires "
11042                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
11043                    Slog.w(TAG, msg);
11044                    throw new SecurityException(msg);
11045                }
11046            }
11047        }
11048
11049        // Handle special intents: if this broadcast is from the package
11050        // manager about a package being removed, we need to remove all of
11051        // its activities from the history stack.
11052        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11053                intent.getAction());
11054        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11055                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11056                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11057                || uidRemoved) {
11058            if (checkComponentPermission(
11059                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11060                    callingPid, callingUid, -1, true)
11061                    == PackageManager.PERMISSION_GRANTED) {
11062                if (uidRemoved) {
11063                    final Bundle intentExtras = intent.getExtras();
11064                    final int uid = intentExtras != null
11065                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11066                    if (uid >= 0) {
11067                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11068                        synchronized (bs) {
11069                            bs.removeUidStatsLocked(uid);
11070                        }
11071                    }
11072                } else {
11073                    // If resources are unvailble just force stop all
11074                    // those packages and flush the attribute cache as well.
11075                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11076                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11077                        if (list != null && (list.length > 0)) {
11078                            for (String pkg : list) {
11079                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11080                            }
11081                            sendPackageBroadcastLocked(
11082                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
11083                        }
11084                    } else {
11085                        Uri data = intent.getData();
11086                        String ssp;
11087                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11088                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11089                                forceStopPackageLocked(ssp,
11090                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11091                                        false, userId);
11092                            }
11093                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11094                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11095                                        new String[] {ssp});
11096                            }
11097                        }
11098                    }
11099                }
11100            } else {
11101                String msg = "Permission Denial: " + intent.getAction()
11102                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11103                        + ", uid=" + callingUid + ")"
11104                        + " requires "
11105                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11106                Slog.w(TAG, msg);
11107                throw new SecurityException(msg);
11108            }
11109
11110        // Special case for adding a package: by default turn on compatibility
11111        // mode.
11112        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11113            Uri data = intent.getData();
11114            String ssp;
11115            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11116                mCompatModePackages.handlePackageAddedLocked(ssp,
11117                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11118            }
11119        }
11120
11121        /*
11122         * If this is the time zone changed action, queue up a message that will reset the timezone
11123         * of all currently running processes. This message will get queued up before the broadcast
11124         * happens.
11125         */
11126        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11127            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11128        }
11129
11130        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11131            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11132        }
11133
11134        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11135            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11136            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11137        }
11138
11139        /*
11140         * Prevent non-system code (defined here to be non-persistent
11141         * processes) from sending protected broadcasts.
11142         */
11143        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11144            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11145            callingUid == 0) {
11146            // Always okay.
11147        } else if (callerApp == null || !callerApp.persistent) {
11148            try {
11149                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11150                        intent.getAction())) {
11151                    String msg = "Permission Denial: not allowed to send broadcast "
11152                            + intent.getAction() + " from pid="
11153                            + callingPid + ", uid=" + callingUid;
11154                    Slog.w(TAG, msg);
11155                    throw new SecurityException(msg);
11156                }
11157            } catch (RemoteException e) {
11158                Slog.w(TAG, "Remote exception", e);
11159                return ActivityManager.BROADCAST_SUCCESS;
11160            }
11161        }
11162
11163        // Add to the sticky list if requested.
11164        if (sticky) {
11165            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11166                    callingPid, callingUid)
11167                    != PackageManager.PERMISSION_GRANTED) {
11168                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11169                        + callingPid + ", uid=" + callingUid
11170                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11171                Slog.w(TAG, msg);
11172                throw new SecurityException(msg);
11173            }
11174            if (requiredPermission != null) {
11175                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11176                        + " and enforce permission " + requiredPermission);
11177                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11178            }
11179            if (intent.getComponent() != null) {
11180                throw new SecurityException(
11181                        "Sticky broadcasts can't target a specific component");
11182            }
11183            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11184            if (list == null) {
11185                list = new ArrayList<Intent>();
11186                mStickyBroadcasts.put(intent.getAction(), list);
11187            }
11188            int N = list.size();
11189            int i;
11190            for (i=0; i<N; i++) {
11191                if (intent.filterEquals(list.get(i))) {
11192                    // This sticky already exists, replace it.
11193                    list.set(i, new Intent(intent));
11194                    break;
11195                }
11196            }
11197            if (i >= N) {
11198                list.add(new Intent(intent));
11199            }
11200        }
11201
11202        // Figure out who all will receive this broadcast.
11203        List receivers = null;
11204        List<BroadcastFilter> registeredReceivers = null;
11205        try {
11206            // Need to resolve the intent to interested receivers...
11207            if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11208                     == 0) {
11209                receivers = AppGlobals.getPackageManager().queryIntentReceivers(
11210                        intent, resolvedType, STOCK_PM_FLAGS, userId);
11211            }
11212            if (intent.getComponent() == null) {
11213                registeredReceivers = mReceiverResolver.queryIntent(intent,
11214                        resolvedType, false, userId);
11215            }
11216        } catch (RemoteException ex) {
11217            // pm is in same process, this will never happen.
11218        }
11219
11220        final boolean replacePending =
11221                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11222
11223        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11224                + " replacePending=" + replacePending);
11225
11226        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11227        if (!ordered && NR > 0) {
11228            // If we are not serializing this broadcast, then send the
11229            // registered receivers separately so they don't wait for the
11230            // components to be launched.
11231            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11232            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11233                    callerPackage, callingPid, callingUid, requiredPermission,
11234                    registeredReceivers, resultTo, resultCode, resultData, map,
11235                    ordered, sticky, false, onlySendToCaller);
11236            if (DEBUG_BROADCAST) Slog.v(
11237                    TAG, "Enqueueing parallel broadcast " + r);
11238            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11239            if (!replaced) {
11240                queue.enqueueParallelBroadcastLocked(r);
11241                queue.scheduleBroadcastsLocked();
11242            }
11243            registeredReceivers = null;
11244            NR = 0;
11245        }
11246
11247        // Merge into one list.
11248        int ir = 0;
11249        if (receivers != null) {
11250            // A special case for PACKAGE_ADDED: do not allow the package
11251            // being added to see this broadcast.  This prevents them from
11252            // using this as a back door to get run as soon as they are
11253            // installed.  Maybe in the future we want to have a special install
11254            // broadcast or such for apps, but we'd like to deliberately make
11255            // this decision.
11256            String skipPackages[] = null;
11257            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11258                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11259                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11260                Uri data = intent.getData();
11261                if (data != null) {
11262                    String pkgName = data.getSchemeSpecificPart();
11263                    if (pkgName != null) {
11264                        skipPackages = new String[] { pkgName };
11265                    }
11266                }
11267            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11268                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11269            }
11270            if (skipPackages != null && (skipPackages.length > 0)) {
11271                for (String skipPackage : skipPackages) {
11272                    if (skipPackage != null) {
11273                        int NT = receivers.size();
11274                        for (int it=0; it<NT; it++) {
11275                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11276                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11277                                receivers.remove(it);
11278                                it--;
11279                                NT--;
11280                            }
11281                        }
11282                    }
11283                }
11284            }
11285
11286            int NT = receivers != null ? receivers.size() : 0;
11287            int it = 0;
11288            ResolveInfo curt = null;
11289            BroadcastFilter curr = null;
11290            while (it < NT && ir < NR) {
11291                if (curt == null) {
11292                    curt = (ResolveInfo)receivers.get(it);
11293                }
11294                if (curr == null) {
11295                    curr = registeredReceivers.get(ir);
11296                }
11297                if (curr.getPriority() >= curt.priority) {
11298                    // Insert this broadcast record into the final list.
11299                    receivers.add(it, curr);
11300                    ir++;
11301                    curr = null;
11302                    it++;
11303                    NT++;
11304                } else {
11305                    // Skip to the next ResolveInfo in the final list.
11306                    it++;
11307                    curt = null;
11308                }
11309            }
11310        }
11311        while (ir < NR) {
11312            if (receivers == null) {
11313                receivers = new ArrayList();
11314            }
11315            receivers.add(registeredReceivers.get(ir));
11316            ir++;
11317        }
11318
11319        if ((receivers != null && receivers.size() > 0)
11320                || resultTo != null) {
11321            BroadcastQueue queue = broadcastQueueForIntent(intent);
11322            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11323                    callerPackage, callingPid, callingUid, requiredPermission,
11324                    receivers, resultTo, resultCode, resultData, map, ordered,
11325                    sticky, false, onlySendToCaller);
11326            if (DEBUG_BROADCAST) Slog.v(
11327                    TAG, "Enqueueing ordered broadcast " + r
11328                    + ": prev had " + queue.mOrderedBroadcasts.size());
11329            if (DEBUG_BROADCAST) {
11330                int seq = r.intent.getIntExtra("seq", -1);
11331                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11332            }
11333            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11334            if (!replaced) {
11335                queue.enqueueOrderedBroadcastLocked(r);
11336                queue.scheduleBroadcastsLocked();
11337            }
11338        }
11339
11340        return ActivityManager.BROADCAST_SUCCESS;
11341    }
11342
11343    final Intent verifyBroadcastLocked(Intent intent) {
11344        // Refuse possible leaked file descriptors
11345        if (intent != null && intent.hasFileDescriptors() == true) {
11346            throw new IllegalArgumentException("File descriptors passed in Intent");
11347        }
11348
11349        int flags = intent.getFlags();
11350
11351        if (!mProcessesReady) {
11352            // if the caller really truly claims to know what they're doing, go
11353            // ahead and allow the broadcast without launching any receivers
11354            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11355                intent = new Intent(intent);
11356                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11357            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11358                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11359                        + " before boot completion");
11360                throw new IllegalStateException("Cannot broadcast before boot completed");
11361            }
11362        }
11363
11364        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11365            throw new IllegalArgumentException(
11366                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11367        }
11368
11369        return intent;
11370    }
11371
11372    public final int broadcastIntent(IApplicationThread caller,
11373            Intent intent, String resolvedType, IIntentReceiver resultTo,
11374            int resultCode, String resultData, Bundle map,
11375            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11376        enforceNotIsolatedCaller("broadcastIntent");
11377        synchronized(this) {
11378            intent = verifyBroadcastLocked(intent);
11379
11380            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11381            final int callingPid = Binder.getCallingPid();
11382            final int callingUid = Binder.getCallingUid();
11383            final long origId = Binder.clearCallingIdentity();
11384            int res = broadcastIntentLocked(callerApp,
11385                    callerApp != null ? callerApp.info.packageName : null,
11386                    intent, resolvedType, resultTo,
11387                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11388                    callingPid, callingUid, userId);
11389            Binder.restoreCallingIdentity(origId);
11390            return res;
11391        }
11392    }
11393
11394    int broadcastIntentInPackage(String packageName, int uid,
11395            Intent intent, String resolvedType, IIntentReceiver resultTo,
11396            int resultCode, String resultData, Bundle map,
11397            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11398        synchronized(this) {
11399            intent = verifyBroadcastLocked(intent);
11400
11401            final long origId = Binder.clearCallingIdentity();
11402            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11403                    resultTo, resultCode, resultData, map, requiredPermission,
11404                    serialized, sticky, -1, uid, userId);
11405            Binder.restoreCallingIdentity(origId);
11406            return res;
11407        }
11408    }
11409
11410    // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
11411    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11412        // Refuse possible leaked file descriptors
11413        if (intent != null && intent.hasFileDescriptors() == true) {
11414            throw new IllegalArgumentException("File descriptors passed in Intent");
11415        }
11416
11417        synchronized(this) {
11418            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11419                    != PackageManager.PERMISSION_GRANTED) {
11420                String msg = "Permission Denial: unbroadcastIntent() from pid="
11421                        + Binder.getCallingPid()
11422                        + ", uid=" + Binder.getCallingUid()
11423                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11424                Slog.w(TAG, msg);
11425                throw new SecurityException(msg);
11426            }
11427            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11428            if (list != null) {
11429                int N = list.size();
11430                int i;
11431                for (i=0; i<N; i++) {
11432                    if (intent.filterEquals(list.get(i))) {
11433                        list.remove(i);
11434                        break;
11435                    }
11436                }
11437            }
11438        }
11439    }
11440
11441    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11442            String resultData, Bundle resultExtras, boolean resultAbort,
11443            boolean explicit) {
11444        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11445        if (r == null) {
11446            Slog.w(TAG, "finishReceiver called but not found on queue");
11447            return false;
11448        }
11449
11450        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11451                explicit);
11452    }
11453
11454    public void finishReceiver(IBinder who, int resultCode, String resultData,
11455            Bundle resultExtras, boolean resultAbort) {
11456        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11457
11458        // Refuse possible leaked file descriptors
11459        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11460            throw new IllegalArgumentException("File descriptors passed in Bundle");
11461        }
11462
11463        final long origId = Binder.clearCallingIdentity();
11464        try {
11465            boolean doNext = false;
11466            BroadcastRecord r = null;
11467
11468            synchronized(this) {
11469                r = broadcastRecordForReceiverLocked(who);
11470                if (r != null) {
11471                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11472                        resultData, resultExtras, resultAbort, true);
11473                }
11474            }
11475
11476            if (doNext) {
11477                r.queue.processNextBroadcast(false);
11478            }
11479            trimApplications();
11480        } finally {
11481            Binder.restoreCallingIdentity(origId);
11482        }
11483    }
11484
11485    // =========================================================
11486    // INSTRUMENTATION
11487    // =========================================================
11488
11489    public boolean startInstrumentation(ComponentName className,
11490            String profileFile, int flags, Bundle arguments,
11491            IInstrumentationWatcher watcher) {
11492        enforceNotIsolatedCaller("startInstrumentation");
11493        // Refuse possible leaked file descriptors
11494        if (arguments != null && arguments.hasFileDescriptors()) {
11495            throw new IllegalArgumentException("File descriptors passed in Bundle");
11496        }
11497
11498        synchronized(this) {
11499            InstrumentationInfo ii = null;
11500            ApplicationInfo ai = null;
11501            try {
11502                ii = mContext.getPackageManager().getInstrumentationInfo(
11503                    className, STOCK_PM_FLAGS);
11504                ai = mContext.getPackageManager().getApplicationInfo(
11505                        ii.targetPackage, STOCK_PM_FLAGS);
11506            } catch (PackageManager.NameNotFoundException e) {
11507            }
11508            if (ii == null) {
11509                reportStartInstrumentationFailure(watcher, className,
11510                        "Unable to find instrumentation info for: " + className);
11511                return false;
11512            }
11513            if (ai == null) {
11514                reportStartInstrumentationFailure(watcher, className,
11515                        "Unable to find instrumentation target package: " + ii.targetPackage);
11516                return false;
11517            }
11518
11519            int match = mContext.getPackageManager().checkSignatures(
11520                    ii.targetPackage, ii.packageName);
11521            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11522                String msg = "Permission Denial: starting instrumentation "
11523                        + className + " from pid="
11524                        + Binder.getCallingPid()
11525                        + ", uid=" + Binder.getCallingPid()
11526                        + " not allowed because package " + ii.packageName
11527                        + " does not have a signature matching the target "
11528                        + ii.targetPackage;
11529                reportStartInstrumentationFailure(watcher, className, msg);
11530                throw new SecurityException(msg);
11531            }
11532
11533            int userId = UserId.getCallingUserId();
11534            final long origId = Binder.clearCallingIdentity();
11535            // Instrumentation can kill and relaunch even persistent processes
11536            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
11537            ProcessRecord app = addAppLocked(ai, false);
11538            app.instrumentationClass = className;
11539            app.instrumentationInfo = ai;
11540            app.instrumentationProfileFile = profileFile;
11541            app.instrumentationArguments = arguments;
11542            app.instrumentationWatcher = watcher;
11543            app.instrumentationResultClass = className;
11544            Binder.restoreCallingIdentity(origId);
11545        }
11546
11547        return true;
11548    }
11549
11550    /**
11551     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11552     * error to the logs, but if somebody is watching, send the report there too.  This enables
11553     * the "am" command to report errors with more information.
11554     *
11555     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11556     * @param cn The component name of the instrumentation.
11557     * @param report The error report.
11558     */
11559    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11560            ComponentName cn, String report) {
11561        Slog.w(TAG, report);
11562        try {
11563            if (watcher != null) {
11564                Bundle results = new Bundle();
11565                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11566                results.putString("Error", report);
11567                watcher.instrumentationStatus(cn, -1, results);
11568            }
11569        } catch (RemoteException e) {
11570            Slog.w(TAG, e);
11571        }
11572    }
11573
11574    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11575        if (app.instrumentationWatcher != null) {
11576            try {
11577                // NOTE:  IInstrumentationWatcher *must* be oneway here
11578                app.instrumentationWatcher.instrumentationFinished(
11579                    app.instrumentationClass,
11580                    resultCode,
11581                    results);
11582            } catch (RemoteException e) {
11583            }
11584        }
11585        app.instrumentationWatcher = null;
11586        app.instrumentationClass = null;
11587        app.instrumentationInfo = null;
11588        app.instrumentationProfileFile = null;
11589        app.instrumentationArguments = null;
11590
11591        forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId);
11592    }
11593
11594    public void finishInstrumentation(IApplicationThread target,
11595            int resultCode, Bundle results) {
11596        int userId = UserId.getCallingUserId();
11597        // Refuse possible leaked file descriptors
11598        if (results != null && results.hasFileDescriptors()) {
11599            throw new IllegalArgumentException("File descriptors passed in Intent");
11600        }
11601
11602        synchronized(this) {
11603            ProcessRecord app = getRecordForAppLocked(target);
11604            if (app == null) {
11605                Slog.w(TAG, "finishInstrumentation: no app for " + target);
11606                return;
11607            }
11608            final long origId = Binder.clearCallingIdentity();
11609            finishInstrumentationLocked(app, resultCode, results);
11610            Binder.restoreCallingIdentity(origId);
11611        }
11612    }
11613
11614    // =========================================================
11615    // CONFIGURATION
11616    // =========================================================
11617
11618    public ConfigurationInfo getDeviceConfigurationInfo() {
11619        ConfigurationInfo config = new ConfigurationInfo();
11620        synchronized (this) {
11621            config.reqTouchScreen = mConfiguration.touchscreen;
11622            config.reqKeyboardType = mConfiguration.keyboard;
11623            config.reqNavigation = mConfiguration.navigation;
11624            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11625                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
11626                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11627            }
11628            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11629                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
11630                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11631            }
11632            config.reqGlEsVersion = GL_ES_VERSION;
11633        }
11634        return config;
11635    }
11636
11637    public Configuration getConfiguration() {
11638        Configuration ci;
11639        synchronized(this) {
11640            ci = new Configuration(mConfiguration);
11641        }
11642        return ci;
11643    }
11644
11645    public void updatePersistentConfiguration(Configuration values) {
11646        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11647                "updateConfiguration()");
11648        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
11649                "updateConfiguration()");
11650        if (values == null) {
11651            throw new NullPointerException("Configuration must not be null");
11652        }
11653
11654        synchronized(this) {
11655            final long origId = Binder.clearCallingIdentity();
11656            updateConfigurationLocked(values, null, true, false);
11657            Binder.restoreCallingIdentity(origId);
11658        }
11659    }
11660
11661    public void updateConfiguration(Configuration values) {
11662        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11663                "updateConfiguration()");
11664
11665        synchronized(this) {
11666            if (values == null && mWindowManager != null) {
11667                // sentinel: fetch the current configuration from the window manager
11668                values = mWindowManager.computeNewConfiguration();
11669            }
11670
11671            if (mWindowManager != null) {
11672                mProcessList.applyDisplaySize(mWindowManager);
11673            }
11674
11675            final long origId = Binder.clearCallingIdentity();
11676            if (values != null) {
11677                Settings.System.clearConfiguration(values);
11678            }
11679            updateConfigurationLocked(values, null, false, false);
11680            Binder.restoreCallingIdentity(origId);
11681        }
11682    }
11683
11684    /**
11685     * Do either or both things: (1) change the current configuration, and (2)
11686     * make sure the given activity is running with the (now) current
11687     * configuration.  Returns true if the activity has been left running, or
11688     * false if <var>starting</var> is being destroyed to match the new
11689     * configuration.
11690     * @param persistent TODO
11691     */
11692    boolean updateConfigurationLocked(Configuration values,
11693            ActivityRecord starting, boolean persistent, boolean initLocale) {
11694        // do nothing if we are headless
11695        if (mHeadless) return true;
11696
11697        int changes = 0;
11698
11699        boolean kept = true;
11700
11701        if (values != null) {
11702            Configuration newConfig = new Configuration(mConfiguration);
11703            changes = newConfig.updateFrom(values);
11704            if (changes != 0) {
11705                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
11706                    Slog.i(TAG, "Updating configuration to: " + values);
11707                }
11708
11709                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
11710
11711                if (values.locale != null && !initLocale) {
11712                    saveLocaleLocked(values.locale,
11713                                     !values.locale.equals(mConfiguration.locale),
11714                                     values.userSetLocale);
11715                }
11716
11717                mConfigurationSeq++;
11718                if (mConfigurationSeq <= 0) {
11719                    mConfigurationSeq = 1;
11720                }
11721                newConfig.seq = mConfigurationSeq;
11722                mConfiguration = newConfig;
11723                Slog.i(TAG, "Config changed: " + newConfig);
11724
11725                final Configuration configCopy = new Configuration(mConfiguration);
11726
11727                // TODO: If our config changes, should we auto dismiss any currently
11728                // showing dialogs?
11729                mShowDialogs = shouldShowDialogs(newConfig);
11730
11731                AttributeCache ac = AttributeCache.instance();
11732                if (ac != null) {
11733                    ac.updateConfiguration(configCopy);
11734                }
11735
11736                // Make sure all resources in our process are updated
11737                // right now, so that anyone who is going to retrieve
11738                // resource values after we return will be sure to get
11739                // the new ones.  This is especially important during
11740                // boot, where the first config change needs to guarantee
11741                // all resources have that config before following boot
11742                // code is executed.
11743                mSystemThread.applyConfigurationToResources(configCopy);
11744
11745                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
11746                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11747                    msg.obj = new Configuration(configCopy);
11748                    mHandler.sendMessage(msg);
11749                }
11750
11751                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11752                    ProcessRecord app = mLruProcesses.get(i);
11753                    try {
11754                        if (app.thread != null) {
11755                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
11756                                    + app.processName + " new config " + mConfiguration);
11757                            app.thread.scheduleConfigurationChanged(configCopy);
11758                        }
11759                    } catch (Exception e) {
11760                    }
11761                }
11762                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
11763                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11764                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
11765                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11766                        null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11767                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
11768                    broadcastIntentLocked(null, null,
11769                            new Intent(Intent.ACTION_LOCALE_CHANGED),
11770                            null, null, 0, null, null,
11771                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11772                }
11773            }
11774        }
11775
11776        if (changes != 0 && starting == null) {
11777            // If the configuration changed, and the caller is not already
11778            // in the process of starting an activity, then find the top
11779            // activity to check if its configuration needs to change.
11780            starting = mMainStack.topRunningActivityLocked(null);
11781        }
11782
11783        if (starting != null) {
11784            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
11785            // And we need to make sure at this point that all other activities
11786            // are made visible with the correct configuration.
11787            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
11788        }
11789
11790        if (values != null && mWindowManager != null) {
11791            mWindowManager.setNewConfiguration(mConfiguration);
11792        }
11793
11794        return kept;
11795    }
11796
11797    /**
11798     * Decide based on the configuration whether we should shouw the ANR,
11799     * crash, etc dialogs.  The idea is that if there is no affordnace to
11800     * press the on-screen buttons, we shouldn't show the dialog.
11801     *
11802     * A thought: SystemUI might also want to get told about this, the Power
11803     * dialog / global actions also might want different behaviors.
11804     */
11805    private static final boolean shouldShowDialogs(Configuration config) {
11806        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
11807                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
11808    }
11809
11810    /**
11811     * Save the locale.  You must be inside a synchronized (this) block.
11812     */
11813    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
11814        if(isDiff) {
11815            SystemProperties.set("user.language", l.getLanguage());
11816            SystemProperties.set("user.region", l.getCountry());
11817        }
11818
11819        if(isPersist) {
11820            SystemProperties.set("persist.sys.language", l.getLanguage());
11821            SystemProperties.set("persist.sys.country", l.getCountry());
11822            SystemProperties.set("persist.sys.localevar", l.getVariant());
11823        }
11824    }
11825
11826    @Override
11827    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
11828        ActivityRecord srec = ActivityRecord.forToken(token);
11829        return srec != null && srec.task.affinity != null &&
11830                srec.task.affinity.equals(destAffinity);
11831    }
11832
11833    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
11834            Intent resultData) {
11835        ComponentName dest = destIntent.getComponent();
11836
11837        synchronized (this) {
11838            ActivityRecord srec = ActivityRecord.forToken(token);
11839            if (srec == null) {
11840                return false;
11841            }
11842            ArrayList<ActivityRecord> history = srec.stack.mHistory;
11843            final int start = history.indexOf(srec);
11844            if (start < 0) {
11845                // Current activity is not in history stack; do nothing.
11846                return false;
11847            }
11848            int finishTo = start - 1;
11849            ActivityRecord parent = null;
11850            boolean foundParentInTask = false;
11851            if (dest != null) {
11852                TaskRecord tr = srec.task;
11853                for (int i = start - 1; i >= 0; i--) {
11854                    ActivityRecord r = history.get(i);
11855                    if (tr != r.task) {
11856                        // Couldn't find parent in the same task; stop at the one above this.
11857                        // (Root of current task; in-app "home" behavior)
11858                        // Always at least finish the current activity.
11859                        finishTo = Math.min(start - 1, i + 1);
11860                        parent = history.get(finishTo);
11861                        break;
11862                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
11863                            r.info.name.equals(dest.getClassName())) {
11864                        finishTo = i;
11865                        parent = r;
11866                        foundParentInTask = true;
11867                        break;
11868                    }
11869                }
11870            }
11871
11872            if (mController != null) {
11873                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
11874                if (next != null) {
11875                    // ask watcher if this is allowed
11876                    boolean resumeOK = true;
11877                    try {
11878                        resumeOK = mController.activityResuming(next.packageName);
11879                    } catch (RemoteException e) {
11880                        mController = null;
11881                    }
11882
11883                    if (!resumeOK) {
11884                        return false;
11885                    }
11886                }
11887            }
11888            final long origId = Binder.clearCallingIdentity();
11889            for (int i = start; i > finishTo; i--) {
11890                ActivityRecord r = history.get(i);
11891                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
11892                        "navigate-up");
11893                // Only return the supplied result for the first activity finished
11894                resultCode = Activity.RESULT_CANCELED;
11895                resultData = null;
11896            }
11897
11898            if (parent != null && foundParentInTask) {
11899                final int parentLaunchMode = parent.info.launchMode;
11900                final int destIntentFlags = destIntent.getFlags();
11901                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
11902                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
11903                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
11904                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
11905                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
11906                } else {
11907                    try {
11908                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
11909                                destIntent.getComponent(), 0, UserId.getCallingUserId());
11910                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
11911                                null, aInfo, parent.appToken, null,
11912                                0, -1, parent.launchedFromUid, 0, null, true, null);
11913                        foundParentInTask = res == ActivityManager.START_SUCCESS;
11914                    } catch (RemoteException e) {
11915                        foundParentInTask = false;
11916                    }
11917                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
11918                            resultData, "navigate-up");
11919                }
11920            }
11921            Binder.restoreCallingIdentity(origId);
11922            return foundParentInTask;
11923        }
11924    }
11925
11926    public int getLaunchedFromUid(IBinder activityToken) {
11927        ActivityRecord srec = ActivityRecord.forToken(activityToken);
11928        if (srec == null) {
11929            return -1;
11930        }
11931        return srec.launchedFromUid;
11932    }
11933
11934    // =========================================================
11935    // LIFETIME MANAGEMENT
11936    // =========================================================
11937
11938    // Returns which broadcast queue the app is the current [or imminent] receiver
11939    // on, or 'null' if the app is not an active broadcast recipient.
11940    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
11941        BroadcastRecord r = app.curReceiver;
11942        if (r != null) {
11943            return r.queue;
11944        }
11945
11946        // It's not the current receiver, but it might be starting up to become one
11947        synchronized (this) {
11948            for (BroadcastQueue queue : mBroadcastQueues) {
11949                r = queue.mPendingBroadcast;
11950                if (r != null && r.curApp == app) {
11951                    // found it; report which queue it's in
11952                    return queue;
11953                }
11954            }
11955        }
11956
11957        return null;
11958    }
11959
11960    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
11961            ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
11962        if (mAdjSeq == app.adjSeq) {
11963            // This adjustment has already been computed.  If we are calling
11964            // from the top, we may have already computed our adjustment with
11965            // an earlier hidden adjustment that isn't really for us... if
11966            // so, use the new hidden adjustment.
11967            if (!recursed && app.hidden) {
11968                app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
11969            }
11970            return app.curRawAdj;
11971        }
11972
11973        if (app.thread == null) {
11974            app.adjSeq = mAdjSeq;
11975            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
11976            return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
11977        }
11978
11979        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
11980        app.adjSource = null;
11981        app.adjTarget = null;
11982        app.empty = false;
11983        app.hidden = false;
11984
11985        final int activitiesSize = app.activities.size();
11986
11987        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
11988            // The max adjustment doesn't allow this app to be anything
11989            // below foreground, so it is not worth doing work for it.
11990            app.adjType = "fixed";
11991            app.adjSeq = mAdjSeq;
11992            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
11993            app.foregroundActivities = false;
11994            app.keeping = true;
11995            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
11996            // System process can do UI, and when they do we want to have
11997            // them trim their memory after the user leaves the UI.  To
11998            // facilitate this, here we need to determine whether or not it
11999            // is currently showing UI.
12000            app.systemNoUi = true;
12001            if (app == TOP_APP) {
12002                app.systemNoUi = false;
12003            } else if (activitiesSize > 0) {
12004                for (int j = 0; j < activitiesSize; j++) {
12005                    final ActivityRecord r = app.activities.get(j);
12006                    if (r.visible) {
12007                        app.systemNoUi = false;
12008                        break;
12009                    }
12010                }
12011            }
12012            return (app.curAdj=app.maxAdj);
12013        }
12014
12015        app.keeping = false;
12016        app.systemNoUi = false;
12017
12018        // Determine the importance of the process, starting with most
12019        // important to least, and assign an appropriate OOM adjustment.
12020        int adj;
12021        int schedGroup;
12022        boolean foregroundActivities = false;
12023        boolean interesting = false;
12024        BroadcastQueue queue;
12025        if (app == TOP_APP) {
12026            // The last app on the list is the foreground app.
12027            adj = ProcessList.FOREGROUND_APP_ADJ;
12028            schedGroup = Process.THREAD_GROUP_DEFAULT;
12029            app.adjType = "top-activity";
12030            foregroundActivities = true;
12031            interesting = true;
12032        } else if (app.instrumentationClass != null) {
12033            // Don't want to kill running instrumentation.
12034            adj = ProcessList.FOREGROUND_APP_ADJ;
12035            schedGroup = Process.THREAD_GROUP_DEFAULT;
12036            app.adjType = "instrumentation";
12037            interesting = true;
12038        } else if ((queue = isReceivingBroadcast(app)) != null) {
12039            // An app that is currently receiving a broadcast also
12040            // counts as being in the foreground for OOM killer purposes.
12041            // It's placed in a sched group based on the nature of the
12042            // broadcast as reflected by which queue it's active in.
12043            adj = ProcessList.FOREGROUND_APP_ADJ;
12044            schedGroup = (queue == mFgBroadcastQueue)
12045                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12046            app.adjType = "broadcast";
12047        } else if (app.executingServices.size() > 0) {
12048            // An app that is currently executing a service callback also
12049            // counts as being in the foreground.
12050            adj = ProcessList.FOREGROUND_APP_ADJ;
12051            schedGroup = Process.THREAD_GROUP_DEFAULT;
12052            app.adjType = "exec-service";
12053        } else if (activitiesSize > 0) {
12054            // This app is in the background with paused activities.
12055            // We inspect activities to potentially upgrade adjustment further below.
12056            adj = hiddenAdj;
12057            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12058            app.hidden = true;
12059            app.adjType = "bg-activities";
12060        } else {
12061            // A very not-needed process.  If this is lower in the lru list,
12062            // we will push it in to the empty bucket.
12063            adj = hiddenAdj;
12064            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12065            app.hidden = true;
12066            app.empty = true;
12067            app.adjType = "bg-empty";
12068        }
12069
12070        boolean hasStoppingActivities = false;
12071
12072        // Examine all activities if not already foreground.
12073        if (!foregroundActivities && activitiesSize > 0) {
12074            for (int j = 0; j < activitiesSize; j++) {
12075                final ActivityRecord r = app.activities.get(j);
12076                if (r.visible) {
12077                    // App has a visible activity; only upgrade adjustment.
12078                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12079                        adj = ProcessList.VISIBLE_APP_ADJ;
12080                        app.adjType = "visible";
12081                    }
12082                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12083                    app.hidden = false;
12084                    foregroundActivities = true;
12085                    break;
12086                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12087                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12088                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12089                        app.adjType = "pausing";
12090                    }
12091                    app.hidden = false;
12092                    foregroundActivities = true;
12093                } else if (r.state == ActivityState.STOPPING) {
12094                    // We will apply the actual adjustment later, because
12095                    // we want to allow this process to immediately go through
12096                    // any memory trimming that is in effect.
12097                    app.hidden = false;
12098                    foregroundActivities = true;
12099                    hasStoppingActivities = true;
12100                }
12101            }
12102        }
12103
12104        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12105            if (app.foregroundServices) {
12106                // The user is aware of this app, so make it visible.
12107                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12108                app.hidden = false;
12109                app.adjType = "foreground-service";
12110                schedGroup = Process.THREAD_GROUP_DEFAULT;
12111            } else if (app.forcingToForeground != null) {
12112                // The user is aware of this app, so make it visible.
12113                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12114                app.hidden = false;
12115                app.adjType = "force-foreground";
12116                app.adjSource = app.forcingToForeground;
12117                schedGroup = Process.THREAD_GROUP_DEFAULT;
12118            }
12119        }
12120
12121        if (app.foregroundServices) {
12122            interesting = true;
12123        }
12124
12125        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12126            // We don't want to kill the current heavy-weight process.
12127            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12128            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12129            app.hidden = false;
12130            app.adjType = "heavy";
12131        }
12132
12133        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12134            // This process is hosting what we currently consider to be the
12135            // home app, so we don't want to let it go into the background.
12136            adj = ProcessList.HOME_APP_ADJ;
12137            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12138            app.hidden = false;
12139            app.adjType = "home";
12140        }
12141
12142        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12143                && app.activities.size() > 0) {
12144            // This was the previous process that showed UI to the user.
12145            // We want to try to keep it around more aggressively, to give
12146            // a good experience around switching between two apps.
12147            adj = ProcessList.PREVIOUS_APP_ADJ;
12148            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12149            app.hidden = false;
12150            app.adjType = "previous";
12151        }
12152
12153        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12154                + " reason=" + app.adjType);
12155
12156        // By default, we use the computed adjustment.  It may be changed if
12157        // there are applications dependent on our services or providers, but
12158        // this gives us a baseline and makes sure we don't get into an
12159        // infinite recursion.
12160        app.adjSeq = mAdjSeq;
12161        app.curRawAdj = app.nonStoppingAdj = adj;
12162
12163        if (mBackupTarget != null && app == mBackupTarget.app) {
12164            // If possible we want to avoid killing apps while they're being backed up
12165            if (adj > ProcessList.BACKUP_APP_ADJ) {
12166                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12167                adj = ProcessList.BACKUP_APP_ADJ;
12168                app.adjType = "backup";
12169                app.hidden = false;
12170            }
12171        }
12172
12173        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12174                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12175            final long now = SystemClock.uptimeMillis();
12176            // This process is more important if the top activity is
12177            // bound to the service.
12178            Iterator<ServiceRecord> jt = app.services.iterator();
12179            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12180                ServiceRecord s = jt.next();
12181                if (s.startRequested) {
12182                    if (app.hasShownUi && app != mHomeProcess) {
12183                        // If this process has shown some UI, let it immediately
12184                        // go to the LRU list because it may be pretty heavy with
12185                        // UI stuff.  We'll tag it with a label just to help
12186                        // debug and understand what is going on.
12187                        if (adj > ProcessList.SERVICE_ADJ) {
12188                            app.adjType = "started-bg-ui-services";
12189                        }
12190                    } else {
12191                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12192                            // This service has seen some activity within
12193                            // recent memory, so we will keep its process ahead
12194                            // of the background processes.
12195                            if (adj > ProcessList.SERVICE_ADJ) {
12196                                adj = ProcessList.SERVICE_ADJ;
12197                                app.adjType = "started-services";
12198                                app.hidden = false;
12199                            }
12200                        }
12201                        // If we have let the service slide into the background
12202                        // state, still have some text describing what it is doing
12203                        // even though the service no longer has an impact.
12204                        if (adj > ProcessList.SERVICE_ADJ) {
12205                            app.adjType = "started-bg-services";
12206                        }
12207                    }
12208                    // Don't kill this process because it is doing work; it
12209                    // has said it is doing work.
12210                    app.keeping = true;
12211                }
12212                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12213                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12214                    Iterator<ArrayList<ConnectionRecord>> kt
12215                            = s.connections.values().iterator();
12216                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12217                        ArrayList<ConnectionRecord> clist = kt.next();
12218                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12219                            // XXX should compute this based on the max of
12220                            // all connected clients.
12221                            ConnectionRecord cr = clist.get(i);
12222                            if (cr.binding.client == app) {
12223                                // Binding to ourself is not interesting.
12224                                continue;
12225                            }
12226                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12227                                ProcessRecord client = cr.binding.client;
12228                                int clientAdj = adj;
12229                                int myHiddenAdj = hiddenAdj;
12230                                if (myHiddenAdj > client.hiddenAdj) {
12231                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12232                                        myHiddenAdj = client.hiddenAdj;
12233                                    } else {
12234                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12235                                    }
12236                                }
12237                                clientAdj = computeOomAdjLocked(
12238                                    client, myHiddenAdj, TOP_APP, true, doingAll);
12239                                String adjType = null;
12240                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12241                                    // Not doing bind OOM management, so treat
12242                                    // this guy more like a started service.
12243                                    if (app.hasShownUi && app != mHomeProcess) {
12244                                        // If this process has shown some UI, let it immediately
12245                                        // go to the LRU list because it may be pretty heavy with
12246                                        // UI stuff.  We'll tag it with a label just to help
12247                                        // debug and understand what is going on.
12248                                        if (adj > clientAdj) {
12249                                            adjType = "bound-bg-ui-services";
12250                                        }
12251                                        app.hidden = false;
12252                                        clientAdj = adj;
12253                                    } else {
12254                                        if (now >= (s.lastActivity
12255                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12256                                            // This service has not seen activity within
12257                                            // recent memory, so allow it to drop to the
12258                                            // LRU list if there is no other reason to keep
12259                                            // it around.  We'll also tag it with a label just
12260                                            // to help debug and undertand what is going on.
12261                                            if (adj > clientAdj) {
12262                                                adjType = "bound-bg-services";
12263                                            }
12264                                            clientAdj = adj;
12265                                        }
12266                                    }
12267                                }
12268                                if (adj > clientAdj) {
12269                                    // If this process has recently shown UI, and
12270                                    // the process that is binding to it is less
12271                                    // important than being visible, then we don't
12272                                    // care about the binding as much as we care
12273                                    // about letting this process get into the LRU
12274                                    // list to be killed and restarted if needed for
12275                                    // memory.
12276                                    if (app.hasShownUi && app != mHomeProcess
12277                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12278                                        adjType = "bound-bg-ui-services";
12279                                    } else {
12280                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12281                                                |Context.BIND_IMPORTANT)) != 0) {
12282                                            adj = clientAdj;
12283                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12284                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12285                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12286                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12287                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12288                                            adj = clientAdj;
12289                                        } else {
12290                                            app.pendingUiClean = true;
12291                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12292                                                adj = ProcessList.VISIBLE_APP_ADJ;
12293                                            }
12294                                        }
12295                                        if (!client.hidden) {
12296                                            app.hidden = false;
12297                                        }
12298                                        if (client.keeping) {
12299                                            app.keeping = true;
12300                                        }
12301                                        adjType = "service";
12302                                    }
12303                                }
12304                                if (adjType != null) {
12305                                    app.adjType = adjType;
12306                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12307                                            .REASON_SERVICE_IN_USE;
12308                                    app.adjSource = cr.binding.client;
12309                                    app.adjSourceOom = clientAdj;
12310                                    app.adjTarget = s.name;
12311                                }
12312                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12313                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12314                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12315                                    }
12316                                }
12317                            }
12318                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12319                                ActivityRecord a = cr.activity;
12320                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12321                                        (a.visible || a.state == ActivityState.RESUMED
12322                                         || a.state == ActivityState.PAUSING)) {
12323                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12324                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12325                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12326                                    }
12327                                    app.hidden = false;
12328                                    app.adjType = "service";
12329                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12330                                            .REASON_SERVICE_IN_USE;
12331                                    app.adjSource = a;
12332                                    app.adjSourceOom = adj;
12333                                    app.adjTarget = s.name;
12334                                }
12335                            }
12336                        }
12337                    }
12338                }
12339            }
12340
12341            // Finally, if this process has active services running in it, we
12342            // would like to avoid killing it unless it would prevent the current
12343            // application from running.  By default we put the process in
12344            // with the rest of the background processes; as we scan through
12345            // its services we may bump it up from there.
12346            if (adj > hiddenAdj) {
12347                adj = hiddenAdj;
12348                app.hidden = false;
12349                app.adjType = "bg-services";
12350            }
12351        }
12352
12353        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12354                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12355            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12356            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12357                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12358                ContentProviderRecord cpr = jt.next();
12359                for (int i = cpr.connections.size()-1;
12360                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12361                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12362                        i--) {
12363                    ContentProviderConnection conn = cpr.connections.get(i);
12364                    ProcessRecord client = conn.client;
12365                    if (client == app) {
12366                        // Being our own client is not interesting.
12367                        continue;
12368                    }
12369                    int myHiddenAdj = hiddenAdj;
12370                    if (myHiddenAdj > client.hiddenAdj) {
12371                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12372                            myHiddenAdj = client.hiddenAdj;
12373                        } else {
12374                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12375                        }
12376                    }
12377                    int clientAdj = computeOomAdjLocked(
12378                        client, myHiddenAdj, TOP_APP, true, doingAll);
12379                    if (adj > clientAdj) {
12380                        if (app.hasShownUi && app != mHomeProcess
12381                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12382                            app.adjType = "bg-ui-provider";
12383                        } else {
12384                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12385                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12386                            app.adjType = "provider";
12387                        }
12388                        if (!client.hidden) {
12389                            app.hidden = false;
12390                        }
12391                        if (client.keeping) {
12392                            app.keeping = true;
12393                        }
12394                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12395                                .REASON_PROVIDER_IN_USE;
12396                        app.adjSource = client;
12397                        app.adjSourceOom = clientAdj;
12398                        app.adjTarget = cpr.name;
12399                    }
12400                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12401                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12402                    }
12403                }
12404                // If the provider has external (non-framework) process
12405                // dependencies, ensure that its adjustment is at least
12406                // FOREGROUND_APP_ADJ.
12407                if (cpr.hasExternalProcessHandles()) {
12408                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12409                        adj = ProcessList.FOREGROUND_APP_ADJ;
12410                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12411                        app.hidden = false;
12412                        app.keeping = true;
12413                        app.adjType = "provider";
12414                        app.adjTarget = cpr.name;
12415                    }
12416                }
12417            }
12418        }
12419
12420        if (adj == ProcessList.SERVICE_ADJ) {
12421            if (doingAll) {
12422                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12423                mNewNumServiceProcs++;
12424            }
12425            if (app.serviceb) {
12426                adj = ProcessList.SERVICE_B_ADJ;
12427            }
12428        } else {
12429            app.serviceb = false;
12430        }
12431
12432        app.nonStoppingAdj = adj;
12433
12434        if (hasStoppingActivities) {
12435            // Only upgrade adjustment.
12436            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12437                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12438                app.adjType = "stopping";
12439            }
12440        }
12441
12442        app.curRawAdj = adj;
12443
12444        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12445        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12446        if (adj > app.maxAdj) {
12447            adj = app.maxAdj;
12448            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12449                schedGroup = Process.THREAD_GROUP_DEFAULT;
12450            }
12451        }
12452        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12453            app.keeping = true;
12454        }
12455
12456        if (app.hasAboveClient) {
12457            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12458            // then we need to drop its adjustment to be lower than the service's
12459            // in order to honor the request.  We want to drop it by one adjustment
12460            // level...  but there is special meaning applied to various levels so
12461            // we will skip some of them.
12462            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12463                // System process will not get dropped, ever
12464            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12465                adj = ProcessList.VISIBLE_APP_ADJ;
12466            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12467                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12468            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12469                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12470            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12471                adj++;
12472            }
12473        }
12474
12475        int importance = app.memImportance;
12476        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12477            app.curAdj = adj;
12478            app.curSchedGroup = schedGroup;
12479            if (!interesting) {
12480                // For this reporting, if there is not something explicitly
12481                // interesting in this process then we will push it to the
12482                // background importance.
12483                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12484            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12485                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12486            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12487                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12488            } else if (adj >= ProcessList.HOME_APP_ADJ) {
12489                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12490            } else if (adj >= ProcessList.SERVICE_ADJ) {
12491                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12492            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12493                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12494            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12495                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12496            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12497                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12498            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12499                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12500            } else {
12501                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12502            }
12503        }
12504
12505        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12506        if (foregroundActivities != app.foregroundActivities) {
12507            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12508        }
12509        if (changes != 0) {
12510            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12511            app.memImportance = importance;
12512            app.foregroundActivities = foregroundActivities;
12513            int i = mPendingProcessChanges.size()-1;
12514            ProcessChangeItem item = null;
12515            while (i >= 0) {
12516                item = mPendingProcessChanges.get(i);
12517                if (item.pid == app.pid) {
12518                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12519                    break;
12520                }
12521                i--;
12522            }
12523            if (i < 0) {
12524                // No existing item in pending changes; need a new one.
12525                final int NA = mAvailProcessChanges.size();
12526                if (NA > 0) {
12527                    item = mAvailProcessChanges.remove(NA-1);
12528                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12529                } else {
12530                    item = new ProcessChangeItem();
12531                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
12532                }
12533                item.changes = 0;
12534                item.pid = app.pid;
12535                item.uid = app.info.uid;
12536                if (mPendingProcessChanges.size() == 0) {
12537                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
12538                            "*** Enqueueing dispatch processes changed!");
12539                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
12540                }
12541                mPendingProcessChanges.add(item);
12542            }
12543            item.changes |= changes;
12544            item.importance = importance;
12545            item.foregroundActivities = foregroundActivities;
12546            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
12547                    + Integer.toHexString(System.identityHashCode(item))
12548                    + " " + app.toShortString() + ": changes=" + item.changes
12549                    + " importance=" + item.importance
12550                    + " foreground=" + item.foregroundActivities
12551                    + " type=" + app.adjType + " source=" + app.adjSource
12552                    + " target=" + app.adjTarget);
12553        }
12554
12555        return app.curRawAdj;
12556    }
12557
12558    /**
12559     * Ask a given process to GC right now.
12560     */
12561    final void performAppGcLocked(ProcessRecord app) {
12562        try {
12563            app.lastRequestedGc = SystemClock.uptimeMillis();
12564            if (app.thread != null) {
12565                if (app.reportLowMemory) {
12566                    app.reportLowMemory = false;
12567                    app.thread.scheduleLowMemory();
12568                } else {
12569                    app.thread.processInBackground();
12570                }
12571            }
12572        } catch (Exception e) {
12573            // whatever.
12574        }
12575    }
12576
12577    /**
12578     * Returns true if things are idle enough to perform GCs.
12579     */
12580    private final boolean canGcNowLocked() {
12581        boolean processingBroadcasts = false;
12582        for (BroadcastQueue q : mBroadcastQueues) {
12583            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
12584                processingBroadcasts = true;
12585            }
12586        }
12587        return !processingBroadcasts
12588                && (mSleeping || (mMainStack.mResumedActivity != null &&
12589                        mMainStack.mResumedActivity.idle));
12590    }
12591
12592    /**
12593     * Perform GCs on all processes that are waiting for it, but only
12594     * if things are idle.
12595     */
12596    final void performAppGcsLocked() {
12597        final int N = mProcessesToGc.size();
12598        if (N <= 0) {
12599            return;
12600        }
12601        if (canGcNowLocked()) {
12602            while (mProcessesToGc.size() > 0) {
12603                ProcessRecord proc = mProcessesToGc.remove(0);
12604                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
12605                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12606                            <= SystemClock.uptimeMillis()) {
12607                        // To avoid spamming the system, we will GC processes one
12608                        // at a time, waiting a few seconds between each.
12609                        performAppGcLocked(proc);
12610                        scheduleAppGcsLocked();
12611                        return;
12612                    } else {
12613                        // It hasn't been long enough since we last GCed this
12614                        // process...  put it in the list to wait for its time.
12615                        addProcessToGcListLocked(proc);
12616                        break;
12617                    }
12618                }
12619            }
12620
12621            scheduleAppGcsLocked();
12622        }
12623    }
12624
12625    /**
12626     * If all looks good, perform GCs on all processes waiting for them.
12627     */
12628    final void performAppGcsIfAppropriateLocked() {
12629        if (canGcNowLocked()) {
12630            performAppGcsLocked();
12631            return;
12632        }
12633        // Still not idle, wait some more.
12634        scheduleAppGcsLocked();
12635    }
12636
12637    /**
12638     * Schedule the execution of all pending app GCs.
12639     */
12640    final void scheduleAppGcsLocked() {
12641        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
12642
12643        if (mProcessesToGc.size() > 0) {
12644            // Schedule a GC for the time to the next process.
12645            ProcessRecord proc = mProcessesToGc.get(0);
12646            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12647
12648            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
12649            long now = SystemClock.uptimeMillis();
12650            if (when < (now+GC_TIMEOUT)) {
12651                when = now + GC_TIMEOUT;
12652            }
12653            mHandler.sendMessageAtTime(msg, when);
12654        }
12655    }
12656
12657    /**
12658     * Add a process to the array of processes waiting to be GCed.  Keeps the
12659     * list in sorted order by the last GC time.  The process can't already be
12660     * on the list.
12661     */
12662    final void addProcessToGcListLocked(ProcessRecord proc) {
12663        boolean added = false;
12664        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12665            if (mProcessesToGc.get(i).lastRequestedGc <
12666                    proc.lastRequestedGc) {
12667                added = true;
12668                mProcessesToGc.add(i+1, proc);
12669                break;
12670            }
12671        }
12672        if (!added) {
12673            mProcessesToGc.add(0, proc);
12674        }
12675    }
12676
12677    /**
12678     * Set up to ask a process to GC itself.  This will either do it
12679     * immediately, or put it on the list of processes to gc the next
12680     * time things are idle.
12681     */
12682    final void scheduleAppGcLocked(ProcessRecord app) {
12683        long now = SystemClock.uptimeMillis();
12684        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
12685            return;
12686        }
12687        if (!mProcessesToGc.contains(app)) {
12688            addProcessToGcListLocked(app);
12689            scheduleAppGcsLocked();
12690        }
12691    }
12692
12693    final void checkExcessivePowerUsageLocked(boolean doKills) {
12694        updateCpuStatsNow();
12695
12696        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12697        boolean doWakeKills = doKills;
12698        boolean doCpuKills = doKills;
12699        if (mLastPowerCheckRealtime == 0) {
12700            doWakeKills = false;
12701        }
12702        if (mLastPowerCheckUptime == 0) {
12703            doCpuKills = false;
12704        }
12705        if (stats.isScreenOn()) {
12706            doWakeKills = false;
12707        }
12708        final long curRealtime = SystemClock.elapsedRealtime();
12709        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12710        final long curUptime = SystemClock.uptimeMillis();
12711        final long uptimeSince = curUptime - mLastPowerCheckUptime;
12712        mLastPowerCheckRealtime = curRealtime;
12713        mLastPowerCheckUptime = curUptime;
12714        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12715            doWakeKills = false;
12716        }
12717        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12718            doCpuKills = false;
12719        }
12720        int i = mLruProcesses.size();
12721        while (i > 0) {
12722            i--;
12723            ProcessRecord app = mLruProcesses.get(i);
12724            if (!app.keeping) {
12725                long wtime;
12726                synchronized (stats) {
12727                    wtime = stats.getProcessWakeTime(app.info.uid,
12728                            app.pid, curRealtime);
12729                }
12730                long wtimeUsed = wtime - app.lastWakeTime;
12731                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12732                if (DEBUG_POWER) {
12733                    StringBuilder sb = new StringBuilder(128);
12734                    sb.append("Wake for ");
12735                    app.toShortString(sb);
12736                    sb.append(": over ");
12737                    TimeUtils.formatDuration(realtimeSince, sb);
12738                    sb.append(" used ");
12739                    TimeUtils.formatDuration(wtimeUsed, sb);
12740                    sb.append(" (");
12741                    sb.append((wtimeUsed*100)/realtimeSince);
12742                    sb.append("%)");
12743                    Slog.i(TAG, sb.toString());
12744                    sb.setLength(0);
12745                    sb.append("CPU for ");
12746                    app.toShortString(sb);
12747                    sb.append(": over ");
12748                    TimeUtils.formatDuration(uptimeSince, sb);
12749                    sb.append(" used ");
12750                    TimeUtils.formatDuration(cputimeUsed, sb);
12751                    sb.append(" (");
12752                    sb.append((cputimeUsed*100)/uptimeSince);
12753                    sb.append("%)");
12754                    Slog.i(TAG, sb.toString());
12755                }
12756                // If a process has held a wake lock for more
12757                // than 50% of the time during this period,
12758                // that sounds bad.  Kill!
12759                if (doWakeKills && realtimeSince > 0
12760                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
12761                    synchronized (stats) {
12762                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12763                                realtimeSince, wtimeUsed);
12764                    }
12765                    Slog.w(TAG, "Excessive wake lock in " + app.processName
12766                            + " (pid " + app.pid + "): held " + wtimeUsed
12767                            + " during " + realtimeSince);
12768                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12769                            app.processName, app.setAdj, "excessive wake lock");
12770                    Process.killProcessQuiet(app.pid);
12771                } else if (doCpuKills && uptimeSince > 0
12772                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
12773                    synchronized (stats) {
12774                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12775                                uptimeSince, cputimeUsed);
12776                    }
12777                    Slog.w(TAG, "Excessive CPU in " + app.processName
12778                            + " (pid " + app.pid + "): used " + cputimeUsed
12779                            + " during " + uptimeSince);
12780                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12781                            app.processName, app.setAdj, "excessive cpu");
12782                    Process.killProcessQuiet(app.pid);
12783                } else {
12784                    app.lastWakeTime = wtime;
12785                    app.lastCpuTime = app.curCpuTime;
12786                }
12787            }
12788        }
12789    }
12790
12791    private final boolean updateOomAdjLocked(
12792            ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
12793        app.hiddenAdj = hiddenAdj;
12794
12795        if (app.thread == null) {
12796            return false;
12797        }
12798
12799        final boolean wasKeeping = app.keeping;
12800
12801        boolean success = true;
12802
12803        computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
12804
12805        if (app.curRawAdj != app.setRawAdj) {
12806            if (wasKeeping && !app.keeping) {
12807                // This app is no longer something we want to keep.  Note
12808                // its current wake lock time to later know to kill it if
12809                // it is not behaving well.
12810                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12811                synchronized (stats) {
12812                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12813                            app.pid, SystemClock.elapsedRealtime());
12814                }
12815                app.lastCpuTime = app.curCpuTime;
12816            }
12817
12818            app.setRawAdj = app.curRawAdj;
12819        }
12820
12821        if (app.curAdj != app.setAdj) {
12822            if (Process.setOomAdj(app.pid, app.curAdj)) {
12823                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
12824                    TAG, "Set " + app.pid + " " + app.processName +
12825                    " adj " + app.curAdj + ": " + app.adjType);
12826                app.setAdj = app.curAdj;
12827            } else {
12828                success = false;
12829                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
12830            }
12831        }
12832        if (app.setSchedGroup != app.curSchedGroup) {
12833            app.setSchedGroup = app.curSchedGroup;
12834            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
12835                    "Setting process group of " + app.processName
12836                    + " to " + app.curSchedGroup);
12837            if (app.waitingToKill != null &&
12838                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
12839                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
12840                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12841                        app.processName, app.setAdj, app.waitingToKill);
12842                app.killedBackground = true;
12843                Process.killProcessQuiet(app.pid);
12844                success = false;
12845            } else {
12846                if (true) {
12847                    long oldId = Binder.clearCallingIdentity();
12848                    try {
12849                        Process.setProcessGroup(app.pid, app.curSchedGroup);
12850                    } catch (Exception e) {
12851                        Slog.w(TAG, "Failed setting process group of " + app.pid
12852                                + " to " + app.curSchedGroup);
12853                        e.printStackTrace();
12854                    } finally {
12855                        Binder.restoreCallingIdentity(oldId);
12856                    }
12857                } else {
12858                    if (app.thread != null) {
12859                        try {
12860                            app.thread.setSchedulingGroup(app.curSchedGroup);
12861                        } catch (RemoteException e) {
12862                        }
12863                    }
12864                }
12865            }
12866        }
12867        return success;
12868    }
12869
12870    private final ActivityRecord resumedAppLocked() {
12871        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
12872        if (resumedActivity == null || resumedActivity.app == null) {
12873            resumedActivity = mMainStack.mPausingActivity;
12874            if (resumedActivity == null || resumedActivity.app == null) {
12875                resumedActivity = mMainStack.topRunningActivityLocked(null);
12876            }
12877        }
12878        return resumedActivity;
12879    }
12880
12881    final boolean updateOomAdjLocked(ProcessRecord app) {
12882        final ActivityRecord TOP_ACT = resumedAppLocked();
12883        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12884        int curAdj = app.curAdj;
12885        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12886            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12887
12888        mAdjSeq++;
12889
12890        boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
12891        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12892            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12893        if (nowHidden != wasHidden) {
12894            // Changed to/from hidden state, so apps after it in the LRU
12895            // list may also be changed.
12896            updateOomAdjLocked();
12897        }
12898        return success;
12899    }
12900
12901    final void updateOomAdjLocked() {
12902        final ActivityRecord TOP_ACT = resumedAppLocked();
12903        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12904
12905        if (false) {
12906            RuntimeException e = new RuntimeException();
12907            e.fillInStackTrace();
12908            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
12909        }
12910
12911        mAdjSeq++;
12912        mNewNumServiceProcs = 0;
12913
12914        // Let's determine how many processes we have running vs.
12915        // how many slots we have for background processes; we may want
12916        // to put multiple processes in a slot of there are enough of
12917        // them.
12918        int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
12919        int factor = (mLruProcesses.size()-4)/numSlots;
12920        if (factor < 1) factor = 1;
12921        int step = 0;
12922        int numHidden = 0;
12923        int numTrimming = 0;
12924
12925        // First update the OOM adjustment for each of the
12926        // application processes based on their current state.
12927        int i = mLruProcesses.size();
12928        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
12929        while (i > 0) {
12930            i--;
12931            ProcessRecord app = mLruProcesses.get(i);
12932            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
12933            updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
12934            if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
12935                && app.curAdj == curHiddenAdj) {
12936                step++;
12937                if (step >= factor) {
12938                    step = 0;
12939                    curHiddenAdj++;
12940                }
12941            }
12942            if (!app.killedBackground) {
12943                if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12944                    numHidden++;
12945                    if (numHidden > mProcessLimit) {
12946                        Slog.i(TAG, "No longer want " + app.processName
12947                                + " (pid " + app.pid + "): hidden #" + numHidden);
12948                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12949                                app.processName, app.setAdj, "too many background");
12950                        app.killedBackground = true;
12951                        Process.killProcessQuiet(app.pid);
12952                    }
12953                }
12954                if (!app.killedBackground && app.isolated && app.services.size() <= 0) {
12955                    // If this is an isolated process, and there are no
12956                    // services running in it, then the process is no longer
12957                    // needed.  We agressively kill these because we can by
12958                    // definition not re-use the same process again, and it is
12959                    // good to avoid having whatever code was running in them
12960                    // left sitting around after no longer needed.
12961                    Slog.i(TAG, "Isolated process " + app.processName
12962                            + " (pid " + app.pid + ") no longer needed");
12963                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12964                            app.processName, app.setAdj, "isolated not needed");
12965                    app.killedBackground = true;
12966                    Process.killProcessQuiet(app.pid);
12967                }
12968                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
12969                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
12970                        && !app.killedBackground) {
12971                    numTrimming++;
12972                }
12973            }
12974        }
12975
12976        mNumServiceProcs = mNewNumServiceProcs;
12977
12978        // Now determine the memory trimming level of background processes.
12979        // Unfortunately we need to start at the back of the list to do this
12980        // properly.  We only do this if the number of background apps we
12981        // are managing to keep around is less than half the maximum we desire;
12982        // if we are keeping a good number around, we'll let them use whatever
12983        // memory they want.
12984        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
12985            final int N = mLruProcesses.size();
12986            factor = numTrimming/3;
12987            int minFactor = 2;
12988            if (mHomeProcess != null) minFactor++;
12989            if (mPreviousProcess != null) minFactor++;
12990            if (factor < minFactor) factor = minFactor;
12991            step = 0;
12992            int fgTrimLevel;
12993            if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) {
12994                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
12995            } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) {
12996                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
12997            } else {
12998                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
12999            }
13000            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13001            for (i=0; i<N; i++) {
13002                ProcessRecord app = mLruProcesses.get(i);
13003                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13004                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13005                        && !app.killedBackground) {
13006                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13007                        try {
13008                            app.thread.scheduleTrimMemory(curLevel);
13009                        } catch (RemoteException e) {
13010                        }
13011                        if (false) {
13012                            // For now we won't do this; our memory trimming seems
13013                            // to be good enough at this point that destroying
13014                            // activities causes more harm than good.
13015                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13016                                    && app != mHomeProcess && app != mPreviousProcess) {
13017                                // Need to do this on its own message because the stack may not
13018                                // be in a consistent state at this point.
13019                                // For these apps we will also finish their activities
13020                                // to help them free memory.
13021                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13022                            }
13023                        }
13024                    }
13025                    app.trimMemoryLevel = curLevel;
13026                    step++;
13027                    if (step >= factor) {
13028                        step = 0;
13029                        switch (curLevel) {
13030                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13031                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13032                                break;
13033                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13034                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13035                                break;
13036                        }
13037                    }
13038                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13039                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13040                            && app.thread != null) {
13041                        try {
13042                            app.thread.scheduleTrimMemory(
13043                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13044                        } catch (RemoteException e) {
13045                        }
13046                    }
13047                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13048                } else {
13049                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13050                            && app.pendingUiClean) {
13051                        // If this application is now in the background and it
13052                        // had done UI, then give it the special trim level to
13053                        // have it free UI resources.
13054                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13055                        if (app.trimMemoryLevel < level && app.thread != null) {
13056                            try {
13057                                app.thread.scheduleTrimMemory(level);
13058                            } catch (RemoteException e) {
13059                            }
13060                        }
13061                        app.pendingUiClean = false;
13062                    }
13063                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13064                        try {
13065                            app.thread.scheduleTrimMemory(fgTrimLevel);
13066                        } catch (RemoteException e) {
13067                        }
13068                    }
13069                    app.trimMemoryLevel = fgTrimLevel;
13070                }
13071            }
13072        } else {
13073            final int N = mLruProcesses.size();
13074            for (i=0; i<N; i++) {
13075                ProcessRecord app = mLruProcesses.get(i);
13076                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13077                        && app.pendingUiClean) {
13078                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13079                            && app.thread != null) {
13080                        try {
13081                            app.thread.scheduleTrimMemory(
13082                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13083                        } catch (RemoteException e) {
13084                        }
13085                    }
13086                    app.pendingUiClean = false;
13087                }
13088                app.trimMemoryLevel = 0;
13089            }
13090        }
13091
13092        if (mAlwaysFinishActivities) {
13093            // Need to do this on its own message because the stack may not
13094            // be in a consistent state at this point.
13095            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13096        }
13097    }
13098
13099    final void trimApplications() {
13100        synchronized (this) {
13101            int i;
13102
13103            // First remove any unused application processes whose package
13104            // has been removed.
13105            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13106                final ProcessRecord app = mRemovedProcesses.get(i);
13107                if (app.activities.size() == 0
13108                        && app.curReceiver == null && app.services.size() == 0) {
13109                    Slog.i(
13110                        TAG, "Exiting empty application process "
13111                        + app.processName + " ("
13112                        + (app.thread != null ? app.thread.asBinder() : null)
13113                        + ")\n");
13114                    if (app.pid > 0 && app.pid != MY_PID) {
13115                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13116                                app.processName, app.setAdj, "empty");
13117                        Process.killProcessQuiet(app.pid);
13118                    } else {
13119                        try {
13120                            app.thread.scheduleExit();
13121                        } catch (Exception e) {
13122                            // Ignore exceptions.
13123                        }
13124                    }
13125                    cleanUpApplicationRecordLocked(app, false, true, -1);
13126                    mRemovedProcesses.remove(i);
13127
13128                    if (app.persistent) {
13129                        if (app.persistent) {
13130                            addAppLocked(app.info, false);
13131                        }
13132                    }
13133                }
13134            }
13135
13136            // Now update the oom adj for all processes.
13137            updateOomAdjLocked();
13138        }
13139    }
13140
13141    /** This method sends the specified signal to each of the persistent apps */
13142    public void signalPersistentProcesses(int sig) throws RemoteException {
13143        if (sig != Process.SIGNAL_USR1) {
13144            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13145        }
13146
13147        synchronized (this) {
13148            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13149                    != PackageManager.PERMISSION_GRANTED) {
13150                throw new SecurityException("Requires permission "
13151                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13152            }
13153
13154            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13155                ProcessRecord r = mLruProcesses.get(i);
13156                if (r.thread != null && r.persistent) {
13157                    Process.sendSignal(r.pid, sig);
13158                }
13159            }
13160        }
13161    }
13162
13163    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13164        if (proc == null || proc == mProfileProc) {
13165            proc = mProfileProc;
13166            path = mProfileFile;
13167            profileType = mProfileType;
13168            clearProfilerLocked();
13169        }
13170        if (proc == null) {
13171            return;
13172        }
13173        try {
13174            proc.thread.profilerControl(false, path, null, profileType);
13175        } catch (RemoteException e) {
13176            throw new IllegalStateException("Process disappeared");
13177        }
13178    }
13179
13180    private void clearProfilerLocked() {
13181        if (mProfileFd != null) {
13182            try {
13183                mProfileFd.close();
13184            } catch (IOException e) {
13185            }
13186        }
13187        mProfileApp = null;
13188        mProfileProc = null;
13189        mProfileFile = null;
13190        mProfileType = 0;
13191        mAutoStopProfiler = false;
13192    }
13193
13194    public boolean profileControl(String process, boolean start,
13195            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13196
13197        try {
13198            synchronized (this) {
13199                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13200                // its own permission.
13201                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13202                        != PackageManager.PERMISSION_GRANTED) {
13203                    throw new SecurityException("Requires permission "
13204                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13205                }
13206
13207                if (start && fd == null) {
13208                    throw new IllegalArgumentException("null fd");
13209                }
13210
13211                ProcessRecord proc = null;
13212                if (process != null) {
13213                    try {
13214                        int pid = Integer.parseInt(process);
13215                        synchronized (mPidsSelfLocked) {
13216                            proc = mPidsSelfLocked.get(pid);
13217                        }
13218                    } catch (NumberFormatException e) {
13219                    }
13220
13221                    if (proc == null) {
13222                        HashMap<String, SparseArray<ProcessRecord>> all
13223                                = mProcessNames.getMap();
13224                        SparseArray<ProcessRecord> procs = all.get(process);
13225                        if (procs != null && procs.size() > 0) {
13226                            proc = procs.valueAt(0);
13227                        }
13228                    }
13229                }
13230
13231                if (start && (proc == null || proc.thread == null)) {
13232                    throw new IllegalArgumentException("Unknown process: " + process);
13233                }
13234
13235                if (start) {
13236                    stopProfilerLocked(null, null, 0);
13237                    setProfileApp(proc.info, proc.processName, path, fd, false);
13238                    mProfileProc = proc;
13239                    mProfileType = profileType;
13240                    try {
13241                        fd = fd.dup();
13242                    } catch (IOException e) {
13243                        fd = null;
13244                    }
13245                    proc.thread.profilerControl(start, path, fd, profileType);
13246                    fd = null;
13247                    mProfileFd = null;
13248                } else {
13249                    stopProfilerLocked(proc, path, profileType);
13250                    if (fd != null) {
13251                        try {
13252                            fd.close();
13253                        } catch (IOException e) {
13254                        }
13255                    }
13256                }
13257
13258                return true;
13259            }
13260        } catch (RemoteException e) {
13261            throw new IllegalStateException("Process disappeared");
13262        } finally {
13263            if (fd != null) {
13264                try {
13265                    fd.close();
13266                } catch (IOException e) {
13267                }
13268            }
13269        }
13270    }
13271
13272    public boolean dumpHeap(String process, boolean managed,
13273            String path, ParcelFileDescriptor fd) throws RemoteException {
13274
13275        try {
13276            synchronized (this) {
13277                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13278                // its own permission (same as profileControl).
13279                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13280                        != PackageManager.PERMISSION_GRANTED) {
13281                    throw new SecurityException("Requires permission "
13282                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13283                }
13284
13285                if (fd == null) {
13286                    throw new IllegalArgumentException("null fd");
13287                }
13288
13289                ProcessRecord proc = null;
13290                try {
13291                    int pid = Integer.parseInt(process);
13292                    synchronized (mPidsSelfLocked) {
13293                        proc = mPidsSelfLocked.get(pid);
13294                    }
13295                } catch (NumberFormatException e) {
13296                }
13297
13298                if (proc == null) {
13299                    HashMap<String, SparseArray<ProcessRecord>> all
13300                            = mProcessNames.getMap();
13301                    SparseArray<ProcessRecord> procs = all.get(process);
13302                    if (procs != null && procs.size() > 0) {
13303                        proc = procs.valueAt(0);
13304                    }
13305                }
13306
13307                if (proc == null || proc.thread == null) {
13308                    throw new IllegalArgumentException("Unknown process: " + process);
13309                }
13310
13311                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13312                if (!isDebuggable) {
13313                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13314                        throw new SecurityException("Process not debuggable: " + proc);
13315                    }
13316                }
13317
13318                proc.thread.dumpHeap(managed, path, fd);
13319                fd = null;
13320                return true;
13321            }
13322        } catch (RemoteException e) {
13323            throw new IllegalStateException("Process disappeared");
13324        } finally {
13325            if (fd != null) {
13326                try {
13327                    fd.close();
13328                } catch (IOException e) {
13329                }
13330            }
13331        }
13332    }
13333
13334    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13335    public void monitor() {
13336        synchronized (this) { }
13337    }
13338
13339    void onCoreSettingsChange(Bundle settings) {
13340        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13341            ProcessRecord processRecord = mLruProcesses.get(i);
13342            try {
13343                if (processRecord.thread != null) {
13344                    processRecord.thread.setCoreSettings(settings);
13345                }
13346            } catch (RemoteException re) {
13347                /* ignore */
13348            }
13349        }
13350    }
13351
13352    // Multi-user methods
13353
13354    private int mCurrentUserId;
13355    private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
13356
13357    public boolean switchUser(int userId) {
13358        final int callingUid = Binder.getCallingUid();
13359        if (callingUid != 0 && callingUid != Process.myUid()) {
13360            Slog.e(TAG, "Trying to switch user from unauthorized app");
13361            return false;
13362        }
13363        if (mCurrentUserId == userId)
13364            return true;
13365
13366        synchronized (this) {
13367            // Check if user is already logged in, otherwise check if user exists first before
13368            // adding to the list of logged in users.
13369            if (mLoggedInUsers.indexOfKey(userId) < 0) {
13370                if (!userExists(userId)) {
13371                    return false;
13372                }
13373                mLoggedInUsers.append(userId, userId);
13374            }
13375
13376            mCurrentUserId = userId;
13377            boolean haveActivities = mMainStack.switchUser(userId);
13378            if (!haveActivities) {
13379                startHomeActivityLocked(userId);
13380            }
13381
13382        }
13383
13384        // Inform of user switch
13385        Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13386        addedIntent.putExtra(Intent.EXTRA_USERID, userId);
13387        mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS);
13388
13389        return true;
13390    }
13391
13392    @Override
13393    public UserInfo getCurrentUser() throws RemoteException {
13394        final int callingUid = Binder.getCallingUid();
13395        if (callingUid != 0 && callingUid != Process.myUid()) {
13396            Slog.e(TAG, "Trying to get user from unauthorized app");
13397            return null;
13398        }
13399        return AppGlobals.getPackageManager().getUser(mCurrentUserId);
13400    }
13401
13402    private void onUserRemoved(Intent intent) {
13403        int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1);
13404        if (extraUserId < 1) return;
13405
13406        // Kill all the processes for the user
13407        ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>();
13408        synchronized (this) {
13409            HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap();
13410            for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
13411                SparseArray<ProcessRecord> uids = uidMap.getValue();
13412                for (int i = 0; i < uids.size(); i++) {
13413                    if (UserId.getUserId(uids.keyAt(i)) == extraUserId) {
13414                        pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
13415                    }
13416                }
13417            }
13418
13419            for (Pair<String,Integer> pkgAndUid : pkgAndUids) {
13420                forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second,
13421                        false, false, true, true, extraUserId);
13422            }
13423        }
13424    }
13425
13426    private boolean userExists(int userId) {
13427        try {
13428            UserInfo user = AppGlobals.getPackageManager().getUser(userId);
13429            return user != null;
13430        } catch (RemoteException re) {
13431            // Won't happen, in same process
13432        }
13433
13434        return false;
13435    }
13436
13437    private void checkValidCaller(int uid, int userId) {
13438        if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
13439
13440        throw new SecurityException("Caller uid=" + uid
13441                + " is not privileged to communicate with user=" + userId);
13442    }
13443
13444    private int applyUserId(int uid, int userId) {
13445        return UserId.getUid(userId, uid);
13446    }
13447
13448    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
13449        if (info == null) return null;
13450        ApplicationInfo newInfo = new ApplicationInfo(info);
13451        newInfo.uid = applyUserId(info.uid, userId);
13452        newInfo.dataDir = USER_DATA_DIR + userId + "/"
13453                + info.packageName;
13454        return newInfo;
13455    }
13456
13457    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
13458        if (aInfo == null
13459                || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) {
13460            return aInfo;
13461        }
13462
13463        ActivityInfo info = new ActivityInfo(aInfo);
13464        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
13465        return info;
13466    }
13467}
13468