ActivityManagerService.java revision 80a4af2bbc6af42ae605e454bf89558e564f5244
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20
21import com.android.internal.R;
22import com.android.internal.os.BatteryStatsImpl;
23import com.android.internal.os.ProcessStats;
24import com.android.server.AttributeCache;
25import com.android.server.IntentResolver;
26import com.android.server.ProcessMap;
27import com.android.server.SystemServer;
28import com.android.server.Watchdog;
29import com.android.server.am.ActivityStack.ActivityState;
30import com.android.server.wm.WindowManagerService;
31
32import dalvik.system.Zygote;
33
34import android.app.Activity;
35import android.app.ActivityManager;
36import android.app.ActivityManagerNative;
37import android.app.ActivityOptions;
38import android.app.ActivityThread;
39import android.app.AlertDialog;
40import android.app.AppGlobals;
41import android.app.ApplicationErrorReport;
42import android.app.Dialog;
43import android.app.IActivityController;
44import android.app.IApplicationThread;
45import android.app.IInstrumentationWatcher;
46import android.app.INotificationManager;
47import android.app.IProcessObserver;
48import android.app.IServiceConnection;
49import android.app.IStopUserCallback;
50import android.app.IThumbnailReceiver;
51import android.app.Instrumentation;
52import android.app.Notification;
53import android.app.NotificationManager;
54import android.app.PendingIntent;
55import android.app.backup.IBackupManager;
56import android.content.ActivityNotFoundException;
57import android.content.BroadcastReceiver;
58import android.content.ClipData;
59import android.content.ComponentCallbacks2;
60import android.content.ComponentName;
61import android.content.ContentProvider;
62import android.content.ContentResolver;
63import android.content.Context;
64import android.content.DialogInterface;
65import android.content.IContentProvider;
66import android.content.IIntentReceiver;
67import android.content.IIntentSender;
68import android.content.Intent;
69import android.content.IntentFilter;
70import android.content.IntentSender;
71import android.content.pm.ActivityInfo;
72import android.content.pm.ApplicationInfo;
73import android.content.pm.ConfigurationInfo;
74import android.content.pm.IPackageDataObserver;
75import android.content.pm.IPackageManager;
76import android.content.pm.InstrumentationInfo;
77import android.content.pm.PackageInfo;
78import android.content.pm.PackageManager;
79import android.content.pm.UserInfo;
80import android.content.pm.PackageManager.NameNotFoundException;
81import android.content.pm.PathPermission;
82import android.content.pm.ProviderInfo;
83import android.content.pm.ResolveInfo;
84import android.content.pm.ServiceInfo;
85import android.content.res.CompatibilityInfo;
86import android.content.res.Configuration;
87import android.graphics.Bitmap;
88import android.net.Proxy;
89import android.net.ProxyProperties;
90import android.net.Uri;
91import android.os.Binder;
92import android.os.Build;
93import android.os.Bundle;
94import android.os.Debug;
95import android.os.DropBoxManager;
96import android.os.Environment;
97import android.os.FileObserver;
98import android.os.FileUtils;
99import android.os.Handler;
100import android.os.IBinder;
101import android.os.IPermissionController;
102import android.os.Looper;
103import android.os.Message;
104import android.os.Parcel;
105import android.os.ParcelFileDescriptor;
106import android.os.Process;
107import android.os.RemoteCallbackList;
108import android.os.RemoteException;
109import android.os.SELinux;
110import android.os.ServiceManager;
111import android.os.StrictMode;
112import android.os.SystemClock;
113import android.os.SystemProperties;
114import android.os.UserHandle;
115import android.os.UserManager;
116import android.provider.Settings;
117import android.text.format.Time;
118import android.util.EventLog;
119import android.util.Log;
120import android.util.Pair;
121import android.util.PrintWriterPrinter;
122import android.util.Slog;
123import android.util.SparseArray;
124import android.util.SparseIntArray;
125import android.util.TimeUtils;
126import android.view.Gravity;
127import android.view.LayoutInflater;
128import android.view.View;
129import android.view.WindowManager;
130import android.view.WindowManagerPolicy;
131
132import java.io.BufferedInputStream;
133import java.io.BufferedOutputStream;
134import java.io.BufferedReader;
135import java.io.DataInputStream;
136import java.io.DataOutputStream;
137import java.io.File;
138import java.io.FileDescriptor;
139import java.io.FileInputStream;
140import java.io.FileNotFoundException;
141import java.io.FileOutputStream;
142import java.io.IOException;
143import java.io.InputStreamReader;
144import java.io.PrintWriter;
145import java.io.StringWriter;
146import java.lang.ref.WeakReference;
147import java.util.ArrayList;
148import java.util.Collections;
149import java.util.Comparator;
150import java.util.HashMap;
151import java.util.HashSet;
152import java.util.Iterator;
153import java.util.List;
154import java.util.Locale;
155import java.util.Map;
156import java.util.Map.Entry;
157import java.util.Set;
158import java.util.concurrent.atomic.AtomicBoolean;
159import java.util.concurrent.atomic.AtomicLong;
160
161public final class ActivityManagerService extends ActivityManagerNative
162        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
163    private static final String USER_DATA_DIR = "/data/user/";
164    static final String TAG = "ActivityManager";
165    static final String TAG_MU = "ActivityManagerServiceMU";
166    static final boolean DEBUG = false;
167    static final boolean localLOGV = DEBUG;
168    static final boolean DEBUG_SWITCH = localLOGV || false;
169    static final boolean DEBUG_TASKS = localLOGV || false;
170    static final boolean DEBUG_PAUSE = localLOGV || false;
171    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
172    static final boolean DEBUG_TRANSITION = localLOGV || false;
173    static final boolean DEBUG_BROADCAST = localLOGV || false;
174    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
175    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
176    static final boolean DEBUG_SERVICE = localLOGV || false;
177    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
178    static final boolean DEBUG_VISBILITY = localLOGV || false;
179    static final boolean DEBUG_PROCESSES = localLOGV || false;
180    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
181    static final boolean DEBUG_PROVIDER = localLOGV || false;
182    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
183    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
184    static final boolean DEBUG_RESULTS = localLOGV || false;
185    static final boolean DEBUG_BACKUP = localLOGV || false;
186    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
187    static final boolean DEBUG_POWER = localLOGV || false;
188    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
189    static final boolean DEBUG_MU = localLOGV || false;
190    static final boolean VALIDATE_TOKENS = false;
191    static final boolean SHOW_ACTIVITY_START_TIME = true;
192
193    // Control over CPU and battery monitoring.
194    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
195    static final boolean MONITOR_CPU_USAGE = true;
196    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
197    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
198    static final boolean MONITOR_THREAD_CPU_USAGE = false;
199
200    // The flags that are set for all calls we make to the package manager.
201    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
202
203    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
204
205    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
206
207    // Maximum number of recent tasks that we can remember.
208    static final int MAX_RECENT_TASKS = 20;
209
210    // Amount of time after a call to stopAppSwitches() during which we will
211    // prevent further untrusted switches from happening.
212    static final long APP_SWITCH_DELAY_TIME = 5*1000;
213
214    // How long we wait for a launched process to attach to the activity manager
215    // before we decide it's never going to come up for real.
216    static final int PROC_START_TIMEOUT = 10*1000;
217
218    // How long we wait for a launched process to attach to the activity manager
219    // before we decide it's never going to come up for real, when the process was
220    // started with a wrapper for instrumentation (such as Valgrind) because it
221    // could take much longer than usual.
222    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
223
224    // How long to wait after going idle before forcing apps to GC.
225    static final int GC_TIMEOUT = 5*1000;
226
227    // The minimum amount of time between successive GC requests for a process.
228    static final int GC_MIN_INTERVAL = 60*1000;
229
230    // The rate at which we check for apps using excessive power -- 15 mins.
231    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
232
233    // The minimum sample duration we will allow before deciding we have
234    // enough data on wake locks to start killing things.
235    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
236
237    // The minimum sample duration we will allow before deciding we have
238    // enough data on CPU usage to start killing things.
239    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
240
241    // How long we allow a receiver to run before giving up on it.
242    static final int BROADCAST_FG_TIMEOUT = 10*1000;
243    static final int BROADCAST_BG_TIMEOUT = 60*1000;
244
245    // How long we wait until we timeout on key dispatching.
246    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
247
248    // How long we wait until we timeout on key dispatching during instrumentation.
249    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
250
251    static final int MY_PID = Process.myPid();
252
253    static final String[] EMPTY_STRING_ARRAY = new String[0];
254
255    public ActivityStack mMainStack;
256
257    private final boolean mHeadless;
258
259    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
260    // default actuion automatically.  Important for devices without direct input
261    // devices.
262    private boolean mShowDialogs = true;
263
264    /**
265     * Description of a request to start a new activity, which has been held
266     * due to app switches being disabled.
267     */
268    static class PendingActivityLaunch {
269        ActivityRecord r;
270        ActivityRecord sourceRecord;
271        int startFlags;
272    }
273
274    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
275            = new ArrayList<PendingActivityLaunch>();
276
277
278    BroadcastQueue mFgBroadcastQueue;
279    BroadcastQueue mBgBroadcastQueue;
280    // Convenient for easy iteration over the queues. Foreground is first
281    // so that dispatch of foreground broadcasts gets precedence.
282    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
283
284    BroadcastQueue broadcastQueueForIntent(Intent intent) {
285        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
286        if (DEBUG_BACKGROUND_BROADCAST) {
287            Slog.i(TAG, "Broadcast intent " + intent + " on "
288                    + (isFg ? "foreground" : "background")
289                    + " queue");
290        }
291        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
292    }
293
294    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
295        for (BroadcastQueue queue : mBroadcastQueues) {
296            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
297            if (r != null) {
298                return r;
299            }
300        }
301        return null;
302    }
303
304    /**
305     * Activity we have told the window manager to have key focus.
306     */
307    ActivityRecord mFocusedActivity = null;
308    /**
309     * List of intents that were used to start the most recent tasks.
310     */
311    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
312
313    /**
314     * Process management.
315     */
316    final ProcessList mProcessList = new ProcessList();
317
318    /**
319     * All of the applications we currently have running organized by name.
320     * The keys are strings of the application package name (as
321     * returned by the package manager), and the keys are ApplicationRecord
322     * objects.
323     */
324    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
325
326    /**
327     * The currently running isolated processes.
328     */
329    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
330
331    /**
332     * Counter for assigning isolated process uids, to avoid frequently reusing the
333     * same ones.
334     */
335    int mNextIsolatedProcessUid = 0;
336
337    /**
338     * The currently running heavy-weight process, if any.
339     */
340    ProcessRecord mHeavyWeightProcess = null;
341
342    /**
343     * The last time that various processes have crashed.
344     */
345    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
346
347    /**
348     * Set of applications that we consider to be bad, and will reject
349     * incoming broadcasts from (which the user has no control over).
350     * Processes are added to this set when they have crashed twice within
351     * a minimum amount of time; they are removed from it when they are
352     * later restarted (hopefully due to some user action).  The value is the
353     * time it was added to the list.
354     */
355    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
356
357    /**
358     * All of the processes we currently have running organized by pid.
359     * The keys are the pid running the application.
360     *
361     * <p>NOTE: This object is protected by its own lock, NOT the global
362     * activity manager lock!
363     */
364    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
365
366    /**
367     * All of the processes that have been forced to be foreground.  The key
368     * is the pid of the caller who requested it (we hold a death
369     * link on it).
370     */
371    abstract class ForegroundToken implements IBinder.DeathRecipient {
372        int pid;
373        IBinder token;
374    }
375    final SparseArray<ForegroundToken> mForegroundProcesses
376            = new SparseArray<ForegroundToken>();
377
378    /**
379     * List of records for processes that someone had tried to start before the
380     * system was ready.  We don't start them at that point, but ensure they
381     * are started by the time booting is complete.
382     */
383    final ArrayList<ProcessRecord> mProcessesOnHold
384            = new ArrayList<ProcessRecord>();
385
386    /**
387     * List of persistent applications that are in the process
388     * of being started.
389     */
390    final ArrayList<ProcessRecord> mPersistentStartingProcesses
391            = new ArrayList<ProcessRecord>();
392
393    /**
394     * Processes that are being forcibly torn down.
395     */
396    final ArrayList<ProcessRecord> mRemovedProcesses
397            = new ArrayList<ProcessRecord>();
398
399    /**
400     * List of running applications, sorted by recent usage.
401     * The first entry in the list is the least recently used.
402     * It contains ApplicationRecord objects.  This list does NOT include
403     * any persistent application records (since we never want to exit them).
404     */
405    final ArrayList<ProcessRecord> mLruProcesses
406            = new ArrayList<ProcessRecord>();
407
408    /**
409     * List of processes that should gc as soon as things are idle.
410     */
411    final ArrayList<ProcessRecord> mProcessesToGc
412            = new ArrayList<ProcessRecord>();
413
414    /**
415     * This is the process holding what we currently consider to be
416     * the "home" activity.
417     */
418    ProcessRecord mHomeProcess;
419
420    /**
421     * This is the process holding the activity the user last visited that
422     * is in a different process from the one they are currently in.
423     */
424    ProcessRecord mPreviousProcess;
425
426    /**
427     * The time at which the previous process was last visible.
428     */
429    long mPreviousProcessVisibleTime;
430
431    /**
432     * Which uses have been started, so are allowed to run code.
433     */
434    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
435
436    /**
437     * Packages that the user has asked to have run in screen size
438     * compatibility mode instead of filling the screen.
439     */
440    final CompatModePackages mCompatModePackages;
441
442    /**
443     * Set of PendingResultRecord objects that are currently active.
444     */
445    final HashSet mPendingResultRecords = new HashSet();
446
447    /**
448     * Set of IntentSenderRecord objects that are currently active.
449     */
450    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
451            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
452
453    /**
454     * Fingerprints (hashCode()) of stack traces that we've
455     * already logged DropBox entries for.  Guarded by itself.  If
456     * something (rogue user app) forces this over
457     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
458     */
459    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
460    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
461
462    /**
463     * Strict Mode background batched logging state.
464     *
465     * The string buffer is guarded by itself, and its lock is also
466     * used to determine if another batched write is already
467     * in-flight.
468     */
469    private final StringBuilder mStrictModeBuffer = new StringBuilder();
470
471    /**
472     * Keeps track of all IIntentReceivers that have been registered for
473     * broadcasts.  Hash keys are the receiver IBinder, hash value is
474     * a ReceiverList.
475     */
476    final HashMap mRegisteredReceivers = new HashMap();
477
478    /**
479     * Resolver for broadcast intents to registered receivers.
480     * Holds BroadcastFilter (subclass of IntentFilter).
481     */
482    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
483            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
484        @Override
485        protected boolean allowFilterResult(
486                BroadcastFilter filter, List<BroadcastFilter> dest) {
487            IBinder target = filter.receiverList.receiver.asBinder();
488            for (int i=dest.size()-1; i>=0; i--) {
489                if (dest.get(i).receiverList.receiver.asBinder() == target) {
490                    return false;
491                }
492            }
493            return true;
494        }
495
496        @Override
497        protected BroadcastFilter[] newArray(int size) {
498            return new BroadcastFilter[size];
499        }
500
501        @Override
502        protected String packageForFilter(BroadcastFilter filter) {
503            return filter.packageName;
504        }
505    };
506
507    /**
508     * State of all active sticky broadcasts.  Keys are the action of the
509     * sticky Intent, values are an ArrayList of all broadcasted intents with
510     * that action (which should usually be one).
511     */
512    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
513            new HashMap<String, ArrayList<Intent>>();
514
515    final ActiveServices mServices;
516
517    /**
518     * Backup/restore process management
519     */
520    String mBackupAppName = null;
521    BackupRecord mBackupTarget = null;
522
523    /**
524     * List of PendingThumbnailsRecord objects of clients who are still
525     * waiting to receive all of the thumbnails for a task.
526     */
527    final ArrayList mPendingThumbnails = new ArrayList();
528
529    /**
530     * List of HistoryRecord objects that have been finished and must
531     * still report back to a pending thumbnail receiver.
532     */
533    final ArrayList mCancelledThumbnails = new ArrayList();
534
535    final ProviderMap mProviderMap = new ProviderMap();
536
537    /**
538     * List of content providers who have clients waiting for them.  The
539     * application is currently being launched and the provider will be
540     * removed from this list once it is published.
541     */
542    final ArrayList<ContentProviderRecord> mLaunchingProviders
543            = new ArrayList<ContentProviderRecord>();
544
545    /**
546     * Global set of specific Uri permissions that have been granted.
547     */
548    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
549            = new SparseArray<HashMap<Uri, UriPermission>>();
550
551    CoreSettingsObserver mCoreSettingsObserver;
552
553    /**
554     * Thread-local storage used to carry caller permissions over through
555     * indirect content-provider access.
556     * @see #ActivityManagerService.openContentUri()
557     */
558    private class Identity {
559        public int pid;
560        public int uid;
561
562        Identity(int _pid, int _uid) {
563            pid = _pid;
564            uid = _uid;
565        }
566    }
567
568    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
569
570    /**
571     * All information we have collected about the runtime performance of
572     * any user id that can impact battery performance.
573     */
574    final BatteryStatsService mBatteryStatsService;
575
576    /**
577     * information about component usage
578     */
579    final UsageStatsService mUsageStatsService;
580
581    /**
582     * Current configuration information.  HistoryRecord objects are given
583     * a reference to this object to indicate which configuration they are
584     * currently running in, so this object must be kept immutable.
585     */
586    Configuration mConfiguration = new Configuration();
587
588    /**
589     * Current sequencing integer of the configuration, for skipping old
590     * configurations.
591     */
592    int mConfigurationSeq = 0;
593
594    /**
595     * Hardware-reported OpenGLES version.
596     */
597    final int GL_ES_VERSION;
598
599    /**
600     * List of initialization arguments to pass to all processes when binding applications to them.
601     * For example, references to the commonly used services.
602     */
603    HashMap<String, IBinder> mAppBindArgs;
604
605    /**
606     * Temporary to avoid allocations.  Protected by main lock.
607     */
608    final StringBuilder mStringBuilder = new StringBuilder(256);
609
610    /**
611     * Used to control how we initialize the service.
612     */
613    boolean mStartRunning = false;
614    ComponentName mTopComponent;
615    String mTopAction;
616    String mTopData;
617    boolean mProcessesReady = false;
618    boolean mSystemReady = false;
619    boolean mBooting = false;
620    boolean mWaitingUpdate = false;
621    boolean mDidUpdate = false;
622    boolean mOnBattery = false;
623    boolean mLaunchWarningShown = false;
624
625    Context mContext;
626
627    int mFactoryTest;
628
629    boolean mCheckedForSetup;
630
631    /**
632     * The time at which we will allow normal application switches again,
633     * after a call to {@link #stopAppSwitches()}.
634     */
635    long mAppSwitchesAllowedTime;
636
637    /**
638     * This is set to true after the first switch after mAppSwitchesAllowedTime
639     * is set; any switches after that will clear the time.
640     */
641    boolean mDidAppSwitch;
642
643    /**
644     * Last time (in realtime) at which we checked for power usage.
645     */
646    long mLastPowerCheckRealtime;
647
648    /**
649     * Last time (in uptime) at which we checked for power usage.
650     */
651    long mLastPowerCheckUptime;
652
653    /**
654     * Set while we are wanting to sleep, to prevent any
655     * activities from being started/resumed.
656     */
657    boolean mSleeping = false;
658
659    /**
660     * State of external calls telling us if the device is asleep.
661     */
662    boolean mWentToSleep = false;
663
664    /**
665     * State of external call telling us if the lock screen is shown.
666     */
667    boolean mLockScreenShown = false;
668
669    /**
670     * Set if we are shutting down the system, similar to sleeping.
671     */
672    boolean mShuttingDown = false;
673
674    /**
675     * Task identifier that activities are currently being started
676     * in.  Incremented each time a new task is created.
677     * todo: Replace this with a TokenSpace class that generates non-repeating
678     * integers that won't wrap.
679     */
680    int mCurTask = 1;
681
682    /**
683     * Current sequence id for oom_adj computation traversal.
684     */
685    int mAdjSeq = 0;
686
687    /**
688     * Current sequence id for process LRU updating.
689     */
690    int mLruSeq = 0;
691
692    /**
693     * Keep track of the non-hidden/empty process we last found, to help
694     * determine how to distribute hidden/empty processes next time.
695     */
696    int mNumNonHiddenProcs = 0;
697
698    /**
699     * Keep track of the number of hidden procs, to balance oom adj
700     * distribution between those and empty procs.
701     */
702    int mNumHiddenProcs = 0;
703
704    /**
705     * Keep track of the number of service processes we last found, to
706     * determine on the next iteration which should be B services.
707     */
708    int mNumServiceProcs = 0;
709    int mNewNumServiceProcs = 0;
710
711    /**
712     * System monitoring: number of processes that died since the last
713     * N procs were started.
714     */
715    int[] mProcDeaths = new int[20];
716
717    /**
718     * This is set if we had to do a delayed dexopt of an app before launching
719     * it, to increasing the ANR timeouts in that case.
720     */
721    boolean mDidDexOpt;
722
723    String mDebugApp = null;
724    boolean mWaitForDebugger = false;
725    boolean mDebugTransient = false;
726    String mOrigDebugApp = null;
727    boolean mOrigWaitForDebugger = false;
728    boolean mAlwaysFinishActivities = false;
729    IActivityController mController = null;
730    String mProfileApp = null;
731    ProcessRecord mProfileProc = null;
732    String mProfileFile;
733    ParcelFileDescriptor mProfileFd;
734    int mProfileType = 0;
735    boolean mAutoStopProfiler = false;
736    String mOpenGlTraceApp = null;
737
738    static class ProcessChangeItem {
739        static final int CHANGE_ACTIVITIES = 1<<0;
740        static final int CHANGE_IMPORTANCE= 1<<1;
741        int changes;
742        int uid;
743        int pid;
744        int importance;
745        boolean foregroundActivities;
746    }
747
748    final RemoteCallbackList<IProcessObserver> mProcessObservers
749            = new RemoteCallbackList<IProcessObserver>();
750    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
751
752    final ArrayList<ProcessChangeItem> mPendingProcessChanges
753            = new ArrayList<ProcessChangeItem>();
754    final ArrayList<ProcessChangeItem> mAvailProcessChanges
755            = new ArrayList<ProcessChangeItem>();
756
757    /**
758     * Callback of last caller to {@link #requestPss}.
759     */
760    Runnable mRequestPssCallback;
761
762    /**
763     * Remaining processes for which we are waiting results from the last
764     * call to {@link #requestPss}.
765     */
766    final ArrayList<ProcessRecord> mRequestPssList
767            = new ArrayList<ProcessRecord>();
768
769    /**
770     * Runtime statistics collection thread.  This object's lock is used to
771     * protect all related state.
772     */
773    final Thread mProcessStatsThread;
774
775    /**
776     * Used to collect process stats when showing not responding dialog.
777     * Protected by mProcessStatsThread.
778     */
779    final ProcessStats mProcessStats = new ProcessStats(
780            MONITOR_THREAD_CPU_USAGE);
781    final AtomicLong mLastCpuTime = new AtomicLong(0);
782    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
783
784    long mLastWriteTime = 0;
785
786    /**
787     * Set to true after the system has finished booting.
788     */
789    boolean mBooted = false;
790
791    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
792    int mProcessLimitOverride = -1;
793
794    WindowManagerService mWindowManager;
795
796    static ActivityManagerService mSelf;
797    static ActivityThread mSystemThread;
798
799    private int mCurrentUserId;
800    private UserManager mUserManager;
801
802    private final class AppDeathRecipient implements IBinder.DeathRecipient {
803        final ProcessRecord mApp;
804        final int mPid;
805        final IApplicationThread mAppThread;
806
807        AppDeathRecipient(ProcessRecord app, int pid,
808                IApplicationThread thread) {
809            if (localLOGV) Slog.v(
810                TAG, "New death recipient " + this
811                + " for thread " + thread.asBinder());
812            mApp = app;
813            mPid = pid;
814            mAppThread = thread;
815        }
816
817        public void binderDied() {
818            if (localLOGV) Slog.v(
819                TAG, "Death received in " + this
820                + " for thread " + mAppThread.asBinder());
821            synchronized(ActivityManagerService.this) {
822                appDiedLocked(mApp, mPid, mAppThread);
823            }
824        }
825    }
826
827    static final int SHOW_ERROR_MSG = 1;
828    static final int SHOW_NOT_RESPONDING_MSG = 2;
829    static final int SHOW_FACTORY_ERROR_MSG = 3;
830    static final int UPDATE_CONFIGURATION_MSG = 4;
831    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
832    static final int WAIT_FOR_DEBUGGER_MSG = 6;
833    static final int SERVICE_TIMEOUT_MSG = 12;
834    static final int UPDATE_TIME_ZONE = 13;
835    static final int SHOW_UID_ERROR_MSG = 14;
836    static final int IM_FEELING_LUCKY_MSG = 15;
837    static final int PROC_START_TIMEOUT_MSG = 20;
838    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
839    static final int KILL_APPLICATION_MSG = 22;
840    static final int FINALIZE_PENDING_INTENT_MSG = 23;
841    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
842    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
843    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
844    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
845    static final int CLEAR_DNS_CACHE = 28;
846    static final int UPDATE_HTTP_PROXY = 29;
847    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
848    static final int DISPATCH_PROCESSES_CHANGED = 31;
849    static final int DISPATCH_PROCESS_DIED = 32;
850    static final int REPORT_MEM_USAGE = 33;
851
852    static final int FIRST_ACTIVITY_STACK_MSG = 100;
853    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
854    static final int FIRST_COMPAT_MODE_MSG = 300;
855
856    AlertDialog mUidAlert;
857    CompatModeDialog mCompatModeDialog;
858    long mLastMemUsageReportTime = 0;
859
860    final Handler mHandler = new Handler() {
861        //public Handler() {
862        //    if (localLOGV) Slog.v(TAG, "Handler started!");
863        //}
864
865        public void handleMessage(Message msg) {
866            switch (msg.what) {
867            case SHOW_ERROR_MSG: {
868                HashMap data = (HashMap) msg.obj;
869                synchronized (ActivityManagerService.this) {
870                    ProcessRecord proc = (ProcessRecord)data.get("app");
871                    if (proc != null && proc.crashDialog != null) {
872                        Slog.e(TAG, "App already has crash dialog: " + proc);
873                        return;
874                    }
875                    AppErrorResult res = (AppErrorResult) data.get("result");
876                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
877                        Dialog d = new AppErrorDialog(mContext, res, proc);
878                        d.show();
879                        proc.crashDialog = d;
880                    } else {
881                        // The device is asleep, so just pretend that the user
882                        // saw a crash dialog and hit "force quit".
883                        res.set(0);
884                    }
885                }
886
887                ensureBootCompleted();
888            } break;
889            case SHOW_NOT_RESPONDING_MSG: {
890                synchronized (ActivityManagerService.this) {
891                    HashMap data = (HashMap) msg.obj;
892                    ProcessRecord proc = (ProcessRecord)data.get("app");
893                    if (proc != null && proc.anrDialog != null) {
894                        Slog.e(TAG, "App already has anr dialog: " + proc);
895                        return;
896                    }
897
898                    Intent intent = new Intent("android.intent.action.ANR");
899                    if (!mProcessesReady) {
900                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
901                                | Intent.FLAG_RECEIVER_FOREGROUND);
902                    }
903                    broadcastIntentLocked(null, null, intent,
904                            null, null, 0, null, null, null,
905                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
906
907                    if (mShowDialogs) {
908                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
909                                mContext, proc, (ActivityRecord)data.get("activity"));
910                        d.show();
911                        proc.anrDialog = d;
912                    } else {
913                        // Just kill the app if there is no dialog to be shown.
914                        killAppAtUsersRequest(proc, null);
915                    }
916                }
917
918                ensureBootCompleted();
919            } break;
920            case SHOW_STRICT_MODE_VIOLATION_MSG: {
921                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
922                synchronized (ActivityManagerService.this) {
923                    ProcessRecord proc = (ProcessRecord) data.get("app");
924                    if (proc == null) {
925                        Slog.e(TAG, "App not found when showing strict mode dialog.");
926                        break;
927                    }
928                    if (proc.crashDialog != null) {
929                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
930                        return;
931                    }
932                    AppErrorResult res = (AppErrorResult) data.get("result");
933                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
934                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
935                        d.show();
936                        proc.crashDialog = d;
937                    } else {
938                        // The device is asleep, so just pretend that the user
939                        // saw a crash dialog and hit "force quit".
940                        res.set(0);
941                    }
942                }
943                ensureBootCompleted();
944            } break;
945            case SHOW_FACTORY_ERROR_MSG: {
946                Dialog d = new FactoryErrorDialog(
947                    mContext, msg.getData().getCharSequence("msg"));
948                d.show();
949                ensureBootCompleted();
950            } break;
951            case UPDATE_CONFIGURATION_MSG: {
952                final ContentResolver resolver = mContext.getContentResolver();
953                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
954            } break;
955            case GC_BACKGROUND_PROCESSES_MSG: {
956                synchronized (ActivityManagerService.this) {
957                    performAppGcsIfAppropriateLocked();
958                }
959            } break;
960            case WAIT_FOR_DEBUGGER_MSG: {
961                synchronized (ActivityManagerService.this) {
962                    ProcessRecord app = (ProcessRecord)msg.obj;
963                    if (msg.arg1 != 0) {
964                        if (!app.waitedForDebugger) {
965                            Dialog d = new AppWaitingForDebuggerDialog(
966                                    ActivityManagerService.this,
967                                    mContext, app);
968                            app.waitDialog = d;
969                            app.waitedForDebugger = true;
970                            d.show();
971                        }
972                    } else {
973                        if (app.waitDialog != null) {
974                            app.waitDialog.dismiss();
975                            app.waitDialog = null;
976                        }
977                    }
978                }
979            } break;
980            case SERVICE_TIMEOUT_MSG: {
981                if (mDidDexOpt) {
982                    mDidDexOpt = false;
983                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
984                    nmsg.obj = msg.obj;
985                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
986                    return;
987                }
988                mServices.serviceTimeout((ProcessRecord)msg.obj);
989            } break;
990            case UPDATE_TIME_ZONE: {
991                synchronized (ActivityManagerService.this) {
992                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
993                        ProcessRecord r = mLruProcesses.get(i);
994                        if (r.thread != null) {
995                            try {
996                                r.thread.updateTimeZone();
997                            } catch (RemoteException ex) {
998                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
999                            }
1000                        }
1001                    }
1002                }
1003            } break;
1004            case CLEAR_DNS_CACHE: {
1005                synchronized (ActivityManagerService.this) {
1006                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1007                        ProcessRecord r = mLruProcesses.get(i);
1008                        if (r.thread != null) {
1009                            try {
1010                                r.thread.clearDnsCache();
1011                            } catch (RemoteException ex) {
1012                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1013                            }
1014                        }
1015                    }
1016                }
1017            } break;
1018            case UPDATE_HTTP_PROXY: {
1019                ProxyProperties proxy = (ProxyProperties)msg.obj;
1020                String host = "";
1021                String port = "";
1022                String exclList = "";
1023                if (proxy != null) {
1024                    host = proxy.getHost();
1025                    port = Integer.toString(proxy.getPort());
1026                    exclList = proxy.getExclusionList();
1027                }
1028                synchronized (ActivityManagerService.this) {
1029                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1030                        ProcessRecord r = mLruProcesses.get(i);
1031                        if (r.thread != null) {
1032                            try {
1033                                r.thread.setHttpProxy(host, port, exclList);
1034                            } catch (RemoteException ex) {
1035                                Slog.w(TAG, "Failed to update http proxy for: " +
1036                                        r.info.processName);
1037                            }
1038                        }
1039                    }
1040                }
1041            } break;
1042            case SHOW_UID_ERROR_MSG: {
1043                String title = "System UIDs Inconsistent";
1044                String text = "UIDs on the system are inconsistent, you need to wipe your"
1045                        + " data partition or your device will be unstable.";
1046                Log.e(TAG, title + ": " + text);
1047                if (mShowDialogs) {
1048                    // XXX This is a temporary dialog, no need to localize.
1049                    AlertDialog d = new BaseErrorDialog(mContext);
1050                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1051                    d.setCancelable(false);
1052                    d.setTitle(title);
1053                    d.setMessage(text);
1054                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1055                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1056                    mUidAlert = d;
1057                    d.show();
1058                }
1059            } break;
1060            case IM_FEELING_LUCKY_MSG: {
1061                if (mUidAlert != null) {
1062                    mUidAlert.dismiss();
1063                    mUidAlert = null;
1064                }
1065            } break;
1066            case PROC_START_TIMEOUT_MSG: {
1067                if (mDidDexOpt) {
1068                    mDidDexOpt = false;
1069                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1070                    nmsg.obj = msg.obj;
1071                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1072                    return;
1073                }
1074                ProcessRecord app = (ProcessRecord)msg.obj;
1075                synchronized (ActivityManagerService.this) {
1076                    processStartTimedOutLocked(app);
1077                }
1078            } break;
1079            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1080                synchronized (ActivityManagerService.this) {
1081                    doPendingActivityLaunchesLocked(true);
1082                }
1083            } break;
1084            case KILL_APPLICATION_MSG: {
1085                synchronized (ActivityManagerService.this) {
1086                    int uid = msg.arg1;
1087                    boolean restart = (msg.arg2 == 1);
1088                    String pkg = (String) msg.obj;
1089                    forceStopPackageLocked(pkg, uid, restart, false, true, false,
1090                            UserHandle.getUserId(uid));
1091                }
1092            } break;
1093            case FINALIZE_PENDING_INTENT_MSG: {
1094                ((PendingIntentRecord)msg.obj).completeFinalize();
1095            } break;
1096            case POST_HEAVY_NOTIFICATION_MSG: {
1097                INotificationManager inm = NotificationManager.getService();
1098                if (inm == null) {
1099                    return;
1100                }
1101
1102                ActivityRecord root = (ActivityRecord)msg.obj;
1103                ProcessRecord process = root.app;
1104                if (process == null) {
1105                    return;
1106                }
1107
1108                try {
1109                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1110                    String text = mContext.getString(R.string.heavy_weight_notification,
1111                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1112                    Notification notification = new Notification();
1113                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1114                    notification.when = 0;
1115                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1116                    notification.tickerText = text;
1117                    notification.defaults = 0; // please be quiet
1118                    notification.sound = null;
1119                    notification.vibrate = null;
1120                    notification.setLatestEventInfo(context, text,
1121                            mContext.getText(R.string.heavy_weight_notification_detail),
1122                            PendingIntent.getActivity(mContext, 0, root.intent,
1123                                    PendingIntent.FLAG_CANCEL_CURRENT));
1124
1125                    try {
1126                        int[] outId = new int[1];
1127                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
1128                                notification, outId);
1129                    } catch (RuntimeException e) {
1130                        Slog.w(ActivityManagerService.TAG,
1131                                "Error showing notification for heavy-weight app", e);
1132                    } catch (RemoteException e) {
1133                    }
1134                } catch (NameNotFoundException e) {
1135                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1136                }
1137            } break;
1138            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1139                INotificationManager inm = NotificationManager.getService();
1140                if (inm == null) {
1141                    return;
1142                }
1143                try {
1144                    inm.cancelNotification("android",
1145                            R.string.heavy_weight_notification);
1146                } catch (RuntimeException e) {
1147                    Slog.w(ActivityManagerService.TAG,
1148                            "Error canceling notification for service", e);
1149                } catch (RemoteException e) {
1150                }
1151            } break;
1152            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1153                synchronized (ActivityManagerService.this) {
1154                    checkExcessivePowerUsageLocked(true);
1155                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1156                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1157                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1158                }
1159            } break;
1160            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1161                synchronized (ActivityManagerService.this) {
1162                    ActivityRecord ar = (ActivityRecord)msg.obj;
1163                    if (mCompatModeDialog != null) {
1164                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1165                                ar.info.applicationInfo.packageName)) {
1166                            return;
1167                        }
1168                        mCompatModeDialog.dismiss();
1169                        mCompatModeDialog = null;
1170                    }
1171                    if (ar != null && false) {
1172                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1173                                ar.packageName)) {
1174                            int mode = mCompatModePackages.computeCompatModeLocked(
1175                                    ar.info.applicationInfo);
1176                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1177                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1178                                mCompatModeDialog = new CompatModeDialog(
1179                                        ActivityManagerService.this, mContext,
1180                                        ar.info.applicationInfo);
1181                                mCompatModeDialog.show();
1182                            }
1183                        }
1184                    }
1185                }
1186                break;
1187            }
1188            case DISPATCH_PROCESSES_CHANGED: {
1189                dispatchProcessesChanged();
1190                break;
1191            }
1192            case DISPATCH_PROCESS_DIED: {
1193                final int pid = msg.arg1;
1194                final int uid = msg.arg2;
1195                dispatchProcessDied(pid, uid);
1196                break;
1197            }
1198            case REPORT_MEM_USAGE: {
1199                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1200                if (!isDebuggable) {
1201                    return;
1202                }
1203                synchronized (ActivityManagerService.this) {
1204                    long now = SystemClock.uptimeMillis();
1205                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1206                        // Don't report more than every 5 minutes to somewhat
1207                        // avoid spamming.
1208                        return;
1209                    }
1210                    mLastMemUsageReportTime = now;
1211                }
1212                Thread thread = new Thread() {
1213                    @Override public void run() {
1214                        StringBuilder dropBuilder = new StringBuilder(1024);
1215                        StringBuilder logBuilder = new StringBuilder(1024);
1216                        StringWriter oomSw = new StringWriter();
1217                        PrintWriter oomPw = new PrintWriter(oomSw);
1218                        StringWriter catSw = new StringWriter();
1219                        PrintWriter catPw = new PrintWriter(catSw);
1220                        String[] emptyArgs = new String[] { };
1221                        StringBuilder tag = new StringBuilder(128);
1222                        StringBuilder stack = new StringBuilder(128);
1223                        tag.append("Low on memory -- ");
1224                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1225                                tag, stack);
1226                        dropBuilder.append(stack);
1227                        dropBuilder.append('\n');
1228                        dropBuilder.append('\n');
1229                        String oomString = oomSw.toString();
1230                        dropBuilder.append(oomString);
1231                        dropBuilder.append('\n');
1232                        logBuilder.append(oomString);
1233                        try {
1234                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1235                                    "procrank", });
1236                            final InputStreamReader converter = new InputStreamReader(
1237                                    proc.getInputStream());
1238                            BufferedReader in = new BufferedReader(converter);
1239                            String line;
1240                            while (true) {
1241                                line = in.readLine();
1242                                if (line == null) {
1243                                    break;
1244                                }
1245                                if (line.length() > 0) {
1246                                    logBuilder.append(line);
1247                                    logBuilder.append('\n');
1248                                }
1249                                dropBuilder.append(line);
1250                                dropBuilder.append('\n');
1251                            }
1252                            converter.close();
1253                        } catch (IOException e) {
1254                        }
1255                        synchronized (ActivityManagerService.this) {
1256                            catPw.println();
1257                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1258                            catPw.println();
1259                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1260                                    false, false, null);
1261                            catPw.println();
1262                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1263                        }
1264                        dropBuilder.append(catSw.toString());
1265                        addErrorToDropBox("lowmem", null, "system_server", null,
1266                                null, tag.toString(), dropBuilder.toString(), null, null);
1267                        Slog.i(TAG, logBuilder.toString());
1268                        synchronized (ActivityManagerService.this) {
1269                            long now = SystemClock.uptimeMillis();
1270                            if (mLastMemUsageReportTime < now) {
1271                                mLastMemUsageReportTime = now;
1272                            }
1273                        }
1274                    }
1275                };
1276                thread.start();
1277                break;
1278            }
1279            }
1280        }
1281    };
1282
1283    public static void setSystemProcess() {
1284        try {
1285            ActivityManagerService m = mSelf;
1286
1287            ServiceManager.addService("activity", m, true);
1288            ServiceManager.addService("meminfo", new MemBinder(m));
1289            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1290            ServiceManager.addService("dbinfo", new DbBinder(m));
1291            if (MONITOR_CPU_USAGE) {
1292                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1293            }
1294            ServiceManager.addService("permission", new PermissionController(m));
1295
1296            ApplicationInfo info =
1297                mSelf.mContext.getPackageManager().getApplicationInfo(
1298                            "android", STOCK_PM_FLAGS);
1299            mSystemThread.installSystemApplicationInfo(info);
1300
1301            synchronized (mSelf) {
1302                ProcessRecord app = mSelf.newProcessRecordLocked(
1303                        mSystemThread.getApplicationThread(), info,
1304                        info.processName, false);
1305                app.persistent = true;
1306                app.pid = MY_PID;
1307                app.maxAdj = ProcessList.SYSTEM_ADJ;
1308                mSelf.mProcessNames.put(app.processName, app.uid, app);
1309                synchronized (mSelf.mPidsSelfLocked) {
1310                    mSelf.mPidsSelfLocked.put(app.pid, app);
1311                }
1312                mSelf.updateLruProcessLocked(app, true, true);
1313            }
1314        } catch (PackageManager.NameNotFoundException e) {
1315            throw new RuntimeException(
1316                    "Unable to find android system package", e);
1317        }
1318    }
1319
1320    public void setWindowManager(WindowManagerService wm) {
1321        mWindowManager = wm;
1322    }
1323
1324    public static final Context main(int factoryTest) {
1325        AThread thr = new AThread();
1326        thr.start();
1327
1328        synchronized (thr) {
1329            while (thr.mService == null) {
1330                try {
1331                    thr.wait();
1332                } catch (InterruptedException e) {
1333                }
1334            }
1335        }
1336
1337        ActivityManagerService m = thr.mService;
1338        mSelf = m;
1339        ActivityThread at = ActivityThread.systemMain();
1340        mSystemThread = at;
1341        Context context = at.getSystemContext();
1342        context.setTheme(android.R.style.Theme_Holo);
1343        m.mContext = context;
1344        m.mFactoryTest = factoryTest;
1345        m.mMainStack = new ActivityStack(m, context, true);
1346
1347        m.mBatteryStatsService.publish(context);
1348        m.mUsageStatsService.publish(context);
1349
1350        synchronized (thr) {
1351            thr.mReady = true;
1352            thr.notifyAll();
1353        }
1354
1355        m.startRunning(null, null, null, null);
1356
1357        return context;
1358    }
1359
1360    public static ActivityManagerService self() {
1361        return mSelf;
1362    }
1363
1364    static class AThread extends Thread {
1365        ActivityManagerService mService;
1366        boolean mReady = false;
1367
1368        public AThread() {
1369            super("ActivityManager");
1370        }
1371
1372        public void run() {
1373            Looper.prepare();
1374
1375            android.os.Process.setThreadPriority(
1376                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1377            android.os.Process.setCanSelfBackground(false);
1378
1379            ActivityManagerService m = new ActivityManagerService();
1380
1381            synchronized (this) {
1382                mService = m;
1383                notifyAll();
1384            }
1385
1386            synchronized (this) {
1387                while (!mReady) {
1388                    try {
1389                        wait();
1390                    } catch (InterruptedException e) {
1391                    }
1392                }
1393            }
1394
1395            // For debug builds, log event loop stalls to dropbox for analysis.
1396            if (StrictMode.conditionallyEnableDebugLogging()) {
1397                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1398            }
1399
1400            Looper.loop();
1401        }
1402    }
1403
1404    static class MemBinder extends Binder {
1405        ActivityManagerService mActivityManagerService;
1406        MemBinder(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 meminfo from from pid="
1415                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1416                        + " without permission " + android.Manifest.permission.DUMP);
1417                return;
1418            }
1419
1420            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1421                    false, null, null, null);
1422        }
1423    }
1424
1425    static class GraphicsBinder extends Binder {
1426        ActivityManagerService mActivityManagerService;
1427        GraphicsBinder(ActivityManagerService activityManagerService) {
1428            mActivityManagerService = activityManagerService;
1429        }
1430
1431        @Override
1432        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1433            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1434                    != PackageManager.PERMISSION_GRANTED) {
1435                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1436                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1437                        + " without permission " + android.Manifest.permission.DUMP);
1438                return;
1439            }
1440
1441            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1442        }
1443    }
1444
1445    static class DbBinder extends Binder {
1446        ActivityManagerService mActivityManagerService;
1447        DbBinder(ActivityManagerService activityManagerService) {
1448            mActivityManagerService = activityManagerService;
1449        }
1450
1451        @Override
1452        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1453            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1454                    != PackageManager.PERMISSION_GRANTED) {
1455                pw.println("Permission Denial: can't dump dbinfo from from pid="
1456                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1457                        + " without permission " + android.Manifest.permission.DUMP);
1458                return;
1459            }
1460
1461            mActivityManagerService.dumpDbInfo(fd, pw, args);
1462        }
1463    }
1464
1465    static class CpuBinder extends Binder {
1466        ActivityManagerService mActivityManagerService;
1467        CpuBinder(ActivityManagerService activityManagerService) {
1468            mActivityManagerService = activityManagerService;
1469        }
1470
1471        @Override
1472        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1473            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1474                    != PackageManager.PERMISSION_GRANTED) {
1475                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1476                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1477                        + " without permission " + android.Manifest.permission.DUMP);
1478                return;
1479            }
1480
1481            synchronized (mActivityManagerService.mProcessStatsThread) {
1482                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1483                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1484                        SystemClock.uptimeMillis()));
1485            }
1486        }
1487    }
1488
1489    private ActivityManagerService() {
1490        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1491
1492        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1493        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1494        mBroadcastQueues[0] = mFgBroadcastQueue;
1495        mBroadcastQueues[1] = mBgBroadcastQueue;
1496
1497        mServices = new ActiveServices(this);
1498
1499        File dataDir = Environment.getDataDirectory();
1500        File systemDir = new File(dataDir, "system");
1501        systemDir.mkdirs();
1502        mBatteryStatsService = new BatteryStatsService(new File(
1503                systemDir, "batterystats.bin").toString());
1504        mBatteryStatsService.getActiveStatistics().readLocked();
1505        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1506        mOnBattery = DEBUG_POWER ? true
1507                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1508        mBatteryStatsService.getActiveStatistics().setCallback(this);
1509
1510        mUsageStatsService = new UsageStatsService(new File(
1511                systemDir, "usagestats").toString());
1512        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1513
1514        // User 0 is the first and only user that runs at boot.
1515        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1516
1517        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1518            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1519
1520        mConfiguration.setToDefaults();
1521        mConfiguration.locale = Locale.getDefault();
1522        mConfigurationSeq = mConfiguration.seq = 1;
1523        mProcessStats.init();
1524
1525        mCompatModePackages = new CompatModePackages(this, systemDir);
1526
1527        // Add ourself to the Watchdog monitors.
1528        Watchdog.getInstance().addMonitor(this);
1529
1530        mProcessStatsThread = new Thread("ProcessStats") {
1531            public void run() {
1532                while (true) {
1533                    try {
1534                        try {
1535                            synchronized(this) {
1536                                final long now = SystemClock.uptimeMillis();
1537                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1538                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1539                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1540                                //        + ", write delay=" + nextWriteDelay);
1541                                if (nextWriteDelay < nextCpuDelay) {
1542                                    nextCpuDelay = nextWriteDelay;
1543                                }
1544                                if (nextCpuDelay > 0) {
1545                                    mProcessStatsMutexFree.set(true);
1546                                    this.wait(nextCpuDelay);
1547                                }
1548                            }
1549                        } catch (InterruptedException e) {
1550                        }
1551                        updateCpuStatsNow();
1552                    } catch (Exception e) {
1553                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1554                    }
1555                }
1556            }
1557        };
1558        mProcessStatsThread.start();
1559    }
1560
1561    @Override
1562    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1563            throws RemoteException {
1564        if (code == SYSPROPS_TRANSACTION) {
1565            // We need to tell all apps about the system property change.
1566            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1567            synchronized(this) {
1568                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1569                    final int NA = apps.size();
1570                    for (int ia=0; ia<NA; ia++) {
1571                        ProcessRecord app = apps.valueAt(ia);
1572                        if (app.thread != null) {
1573                            procs.add(app.thread.asBinder());
1574                        }
1575                    }
1576                }
1577            }
1578
1579            int N = procs.size();
1580            for (int i=0; i<N; i++) {
1581                Parcel data2 = Parcel.obtain();
1582                try {
1583                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1584                } catch (RemoteException e) {
1585                }
1586                data2.recycle();
1587            }
1588        }
1589        try {
1590            return super.onTransact(code, data, reply, flags);
1591        } catch (RuntimeException e) {
1592            // The activity manager only throws security exceptions, so let's
1593            // log all others.
1594            if (!(e instanceof SecurityException)) {
1595                Slog.e(TAG, "Activity Manager Crash", e);
1596            }
1597            throw e;
1598        }
1599    }
1600
1601    void updateCpuStats() {
1602        final long now = SystemClock.uptimeMillis();
1603        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1604            return;
1605        }
1606        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1607            synchronized (mProcessStatsThread) {
1608                mProcessStatsThread.notify();
1609            }
1610        }
1611    }
1612
1613    void updateCpuStatsNow() {
1614        synchronized (mProcessStatsThread) {
1615            mProcessStatsMutexFree.set(false);
1616            final long now = SystemClock.uptimeMillis();
1617            boolean haveNewCpuStats = false;
1618
1619            if (MONITOR_CPU_USAGE &&
1620                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1621                mLastCpuTime.set(now);
1622                haveNewCpuStats = true;
1623                mProcessStats.update();
1624                //Slog.i(TAG, mProcessStats.printCurrentState());
1625                //Slog.i(TAG, "Total CPU usage: "
1626                //        + mProcessStats.getTotalCpuPercent() + "%");
1627
1628                // Slog the cpu usage if the property is set.
1629                if ("true".equals(SystemProperties.get("events.cpu"))) {
1630                    int user = mProcessStats.getLastUserTime();
1631                    int system = mProcessStats.getLastSystemTime();
1632                    int iowait = mProcessStats.getLastIoWaitTime();
1633                    int irq = mProcessStats.getLastIrqTime();
1634                    int softIrq = mProcessStats.getLastSoftIrqTime();
1635                    int idle = mProcessStats.getLastIdleTime();
1636
1637                    int total = user + system + iowait + irq + softIrq + idle;
1638                    if (total == 0) total = 1;
1639
1640                    EventLog.writeEvent(EventLogTags.CPU,
1641                            ((user+system+iowait+irq+softIrq) * 100) / total,
1642                            (user * 100) / total,
1643                            (system * 100) / total,
1644                            (iowait * 100) / total,
1645                            (irq * 100) / total,
1646                            (softIrq * 100) / total);
1647                }
1648            }
1649
1650            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1651            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1652            synchronized(bstats) {
1653                synchronized(mPidsSelfLocked) {
1654                    if (haveNewCpuStats) {
1655                        if (mOnBattery) {
1656                            int perc = bstats.startAddingCpuLocked();
1657                            int totalUTime = 0;
1658                            int totalSTime = 0;
1659                            final int N = mProcessStats.countStats();
1660                            for (int i=0; i<N; i++) {
1661                                ProcessStats.Stats st = mProcessStats.getStats(i);
1662                                if (!st.working) {
1663                                    continue;
1664                                }
1665                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1666                                int otherUTime = (st.rel_utime*perc)/100;
1667                                int otherSTime = (st.rel_stime*perc)/100;
1668                                totalUTime += otherUTime;
1669                                totalSTime += otherSTime;
1670                                if (pr != null) {
1671                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1672                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1673                                            st.rel_stime-otherSTime);
1674                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1675                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1676                                } else {
1677                                    BatteryStatsImpl.Uid.Proc ps =
1678                                            bstats.getProcessStatsLocked(st.name, st.pid);
1679                                    if (ps != null) {
1680                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1681                                                st.rel_stime-otherSTime);
1682                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1683                                    }
1684                                }
1685                            }
1686                            bstats.finishAddingCpuLocked(perc, totalUTime,
1687                                    totalSTime, cpuSpeedTimes);
1688                        }
1689                    }
1690                }
1691
1692                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1693                    mLastWriteTime = now;
1694                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1695                }
1696            }
1697        }
1698    }
1699
1700    @Override
1701    public void batteryNeedsCpuUpdate() {
1702        updateCpuStatsNow();
1703    }
1704
1705    @Override
1706    public void batteryPowerChanged(boolean onBattery) {
1707        // When plugging in, update the CPU stats first before changing
1708        // the plug state.
1709        updateCpuStatsNow();
1710        synchronized (this) {
1711            synchronized(mPidsSelfLocked) {
1712                mOnBattery = DEBUG_POWER ? true : onBattery;
1713            }
1714        }
1715    }
1716
1717    /**
1718     * Initialize the application bind args. These are passed to each
1719     * process when the bindApplication() IPC is sent to the process. They're
1720     * lazily setup to make sure the services are running when they're asked for.
1721     */
1722    private HashMap<String, IBinder> getCommonServicesLocked() {
1723        if (mAppBindArgs == null) {
1724            mAppBindArgs = new HashMap<String, IBinder>();
1725
1726            // Setup the application init args
1727            mAppBindArgs.put("package", ServiceManager.getService("package"));
1728            mAppBindArgs.put("window", ServiceManager.getService("window"));
1729            mAppBindArgs.put(Context.ALARM_SERVICE,
1730                    ServiceManager.getService(Context.ALARM_SERVICE));
1731        }
1732        return mAppBindArgs;
1733    }
1734
1735    final void setFocusedActivityLocked(ActivityRecord r) {
1736        if (mFocusedActivity != r) {
1737            mFocusedActivity = r;
1738            if (r != null) {
1739                mWindowManager.setFocusedApp(r.appToken, true);
1740            }
1741        }
1742    }
1743
1744    private final void updateLruProcessInternalLocked(ProcessRecord app,
1745            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1746        // put it on the LRU to keep track of when it should be exited.
1747        int lrui = mLruProcesses.indexOf(app);
1748        if (lrui >= 0) mLruProcesses.remove(lrui);
1749
1750        int i = mLruProcesses.size()-1;
1751        int skipTop = 0;
1752
1753        app.lruSeq = mLruSeq;
1754
1755        // compute the new weight for this process.
1756        if (updateActivityTime) {
1757            app.lastActivityTime = SystemClock.uptimeMillis();
1758        }
1759        if (app.activities.size() > 0) {
1760            // If this process has activities, we more strongly want to keep
1761            // it around.
1762            app.lruWeight = app.lastActivityTime;
1763        } else if (app.pubProviders.size() > 0) {
1764            // If this process contains content providers, we want to keep
1765            // it a little more strongly.
1766            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1767            // Also don't let it kick out the first few "real" hidden processes.
1768            skipTop = ProcessList.MIN_HIDDEN_APPS;
1769        } else {
1770            // If this process doesn't have activities, we less strongly
1771            // want to keep it around, and generally want to avoid getting
1772            // in front of any very recently used activities.
1773            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1774            // Also don't let it kick out the first few "real" hidden processes.
1775            skipTop = ProcessList.MIN_HIDDEN_APPS;
1776        }
1777
1778        while (i >= 0) {
1779            ProcessRecord p = mLruProcesses.get(i);
1780            // If this app shouldn't be in front of the first N background
1781            // apps, then skip over that many that are currently hidden.
1782            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1783                skipTop--;
1784            }
1785            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1786                mLruProcesses.add(i+1, app);
1787                break;
1788            }
1789            i--;
1790        }
1791        if (i < 0) {
1792            mLruProcesses.add(0, app);
1793        }
1794
1795        // If the app is currently using a content provider or service,
1796        // bump those processes as well.
1797        if (app.connections.size() > 0) {
1798            for (ConnectionRecord cr : app.connections) {
1799                if (cr.binding != null && cr.binding.service != null
1800                        && cr.binding.service.app != null
1801                        && cr.binding.service.app.lruSeq != mLruSeq) {
1802                    updateLruProcessInternalLocked(cr.binding.service.app, false,
1803                            updateActivityTime, i+1);
1804                }
1805            }
1806        }
1807        for (int j=app.conProviders.size()-1; j>=0; j--) {
1808            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1809            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1810                updateLruProcessInternalLocked(cpr.proc, false,
1811                        updateActivityTime, i+1);
1812            }
1813        }
1814
1815        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1816        if (oomAdj) {
1817            updateOomAdjLocked();
1818        }
1819    }
1820
1821    final void updateLruProcessLocked(ProcessRecord app,
1822            boolean oomAdj, boolean updateActivityTime) {
1823        mLruSeq++;
1824        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1825    }
1826
1827    final ProcessRecord getProcessRecordLocked(
1828            String processName, int uid) {
1829        if (uid == Process.SYSTEM_UID) {
1830            // The system gets to run in any process.  If there are multiple
1831            // processes with the same uid, just pick the first (this
1832            // should never happen).
1833            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1834                    processName);
1835            if (procs == null) return null;
1836            final int N = procs.size();
1837            for (int i = 0; i < N; i++) {
1838                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1839            }
1840        }
1841        ProcessRecord proc = mProcessNames.get(processName, uid);
1842        return proc;
1843    }
1844
1845    void ensurePackageDexOpt(String packageName) {
1846        IPackageManager pm = AppGlobals.getPackageManager();
1847        try {
1848            if (pm.performDexOpt(packageName)) {
1849                mDidDexOpt = true;
1850            }
1851        } catch (RemoteException e) {
1852        }
1853    }
1854
1855    boolean isNextTransitionForward() {
1856        int transit = mWindowManager.getPendingAppTransition();
1857        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1858                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1859                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1860    }
1861
1862    final ProcessRecord startProcessLocked(String processName,
1863            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1864            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1865            boolean isolated) {
1866        ProcessRecord app;
1867        if (!isolated) {
1868            app = getProcessRecordLocked(processName, info.uid);
1869        } else {
1870            // If this is an isolated process, it can't re-use an existing process.
1871            app = null;
1872        }
1873        // We don't have to do anything more if:
1874        // (1) There is an existing application record; and
1875        // (2) The caller doesn't think it is dead, OR there is no thread
1876        //     object attached to it so we know it couldn't have crashed; and
1877        // (3) There is a pid assigned to it, so it is either starting or
1878        //     already running.
1879        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1880                + " app=" + app + " knownToBeDead=" + knownToBeDead
1881                + " thread=" + (app != null ? app.thread : null)
1882                + " pid=" + (app != null ? app.pid : -1));
1883        if (app != null && app.pid > 0) {
1884            if (!knownToBeDead || app.thread == null) {
1885                // We already have the app running, or are waiting for it to
1886                // come up (we have a pid but not yet its thread), so keep it.
1887                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1888                // If this is a new package in the process, add the package to the list
1889                app.addPackage(info.packageName);
1890                return app;
1891            } else {
1892                // An application record is attached to a previous process,
1893                // clean it up now.
1894                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1895                handleAppDiedLocked(app, true, true);
1896            }
1897        }
1898
1899        String hostingNameStr = hostingName != null
1900                ? hostingName.flattenToShortString() : null;
1901
1902        if (!isolated) {
1903            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1904                // If we are in the background, then check to see if this process
1905                // is bad.  If so, we will just silently fail.
1906                if (mBadProcesses.get(info.processName, info.uid) != null) {
1907                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1908                            + "/" + info.processName);
1909                    return null;
1910                }
1911            } else {
1912                // When the user is explicitly starting a process, then clear its
1913                // crash count so that we won't make it bad until they see at
1914                // least one crash dialog again, and make the process good again
1915                // if it had been bad.
1916                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1917                        + "/" + info.processName);
1918                mProcessCrashTimes.remove(info.processName, info.uid);
1919                if (mBadProcesses.get(info.processName, info.uid) != null) {
1920                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1921                            info.processName);
1922                    mBadProcesses.remove(info.processName, info.uid);
1923                    if (app != null) {
1924                        app.bad = false;
1925                    }
1926                }
1927            }
1928        }
1929
1930        if (app == null) {
1931            app = newProcessRecordLocked(null, info, processName, isolated);
1932            if (app == null) {
1933                Slog.w(TAG, "Failed making new process record for "
1934                        + processName + "/" + info.uid + " isolated=" + isolated);
1935                return null;
1936            }
1937            mProcessNames.put(processName, app.uid, app);
1938            if (isolated) {
1939                mIsolatedProcesses.put(app.uid, app);
1940            }
1941        } else {
1942            // If this is a new package in the process, add the package to the list
1943            app.addPackage(info.packageName);
1944        }
1945
1946        // If the system is not ready yet, then hold off on starting this
1947        // process until it is.
1948        if (!mProcessesReady
1949                && !isAllowedWhileBooting(info)
1950                && !allowWhileBooting) {
1951            if (!mProcessesOnHold.contains(app)) {
1952                mProcessesOnHold.add(app);
1953            }
1954            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1955            return app;
1956        }
1957
1958        startProcessLocked(app, hostingType, hostingNameStr);
1959        return (app.pid != 0) ? app : null;
1960    }
1961
1962    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1963        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1964    }
1965
1966    private final void startProcessLocked(ProcessRecord app,
1967            String hostingType, String hostingNameStr) {
1968        if (app.pid > 0 && app.pid != MY_PID) {
1969            synchronized (mPidsSelfLocked) {
1970                mPidsSelfLocked.remove(app.pid);
1971                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1972            }
1973            app.setPid(0);
1974        }
1975
1976        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1977                "startProcessLocked removing on hold: " + app);
1978        mProcessesOnHold.remove(app);
1979
1980        updateCpuStats();
1981
1982        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1983        mProcDeaths[0] = 0;
1984
1985        try {
1986            int uid = app.uid;
1987
1988            int[] gids = null;
1989            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
1990            if (!app.isolated) {
1991                try {
1992                    final PackageManager pm = mContext.getPackageManager();
1993                    gids = pm.getPackageGids(app.info.packageName);
1994                } catch (PackageManager.NameNotFoundException e) {
1995                    Slog.w(TAG, "Unable to retrieve gids", e);
1996                }
1997
1998                if (Environment.isExternalStorageEmulated()) {
1999                    mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2000                }
2001            }
2002            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2003                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2004                        && mTopComponent != null
2005                        && app.processName.equals(mTopComponent.getPackageName())) {
2006                    uid = 0;
2007                }
2008                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2009                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2010                    uid = 0;
2011                }
2012            }
2013            int debugFlags = 0;
2014            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2015                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2016                // Also turn on CheckJNI for debuggable apps. It's quite
2017                // awkward to turn on otherwise.
2018                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2019            }
2020            // Run the app in safe mode if its manifest requests so or the
2021            // system is booted in safe mode.
2022            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2023                Zygote.systemInSafeMode == true) {
2024                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2025            }
2026            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2027                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2028            }
2029            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2030                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2031            }
2032            if ("1".equals(SystemProperties.get("debug.assert"))) {
2033                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2034            }
2035
2036            // Start the process.  It will either succeed and return a result containing
2037            // the PID of the new process, or else throw a RuntimeException.
2038            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2039                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2040                    app.info.targetSdkVersion, null, null);
2041
2042            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2043            synchronized (bs) {
2044                if (bs.isOnBattery()) {
2045                    app.batteryStats.incStartsLocked();
2046                }
2047            }
2048
2049            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2050                    app.processName, hostingType,
2051                    hostingNameStr != null ? hostingNameStr : "");
2052
2053            if (app.persistent) {
2054                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2055            }
2056
2057            StringBuilder buf = mStringBuilder;
2058            buf.setLength(0);
2059            buf.append("Start proc ");
2060            buf.append(app.processName);
2061            buf.append(" for ");
2062            buf.append(hostingType);
2063            if (hostingNameStr != null) {
2064                buf.append(" ");
2065                buf.append(hostingNameStr);
2066            }
2067            buf.append(": pid=");
2068            buf.append(startResult.pid);
2069            buf.append(" uid=");
2070            buf.append(uid);
2071            buf.append(" gids={");
2072            if (gids != null) {
2073                for (int gi=0; gi<gids.length; gi++) {
2074                    if (gi != 0) buf.append(", ");
2075                    buf.append(gids[gi]);
2076
2077                }
2078            }
2079            buf.append("}");
2080            Slog.i(TAG, buf.toString());
2081            app.setPid(startResult.pid);
2082            app.usingWrapper = startResult.usingWrapper;
2083            app.removed = false;
2084            synchronized (mPidsSelfLocked) {
2085                this.mPidsSelfLocked.put(startResult.pid, app);
2086                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2087                msg.obj = app;
2088                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2089                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2090            }
2091        } catch (RuntimeException e) {
2092            // XXX do better error recovery.
2093            app.setPid(0);
2094            Slog.e(TAG, "Failure starting process " + app.processName, e);
2095        }
2096    }
2097
2098    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2099        if (resumed) {
2100            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2101        } else {
2102            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2103        }
2104    }
2105
2106    boolean startHomeActivityLocked(int userId, UserStartedState startingUser) {
2107        if (mHeadless) {
2108            // Added because none of the other calls to ensureBootCompleted seem to fire
2109            // when running headless.
2110            ensureBootCompleted();
2111            return false;
2112        }
2113
2114        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2115                && mTopAction == null) {
2116            // We are running in factory test mode, but unable to find
2117            // the factory test app, so just sit around displaying the
2118            // error message and don't try to start anything.
2119            return false;
2120        }
2121        Intent intent = new Intent(
2122            mTopAction,
2123            mTopData != null ? Uri.parse(mTopData) : null);
2124        intent.setComponent(mTopComponent);
2125        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2126            intent.addCategory(Intent.CATEGORY_HOME);
2127        }
2128        ActivityInfo aInfo =
2129            intent.resolveActivityInfo(mContext.getPackageManager(),
2130                    STOCK_PM_FLAGS);
2131        if (aInfo != null) {
2132            intent.setComponent(new ComponentName(
2133                    aInfo.applicationInfo.packageName, aInfo.name));
2134            // Don't do this if the home app is currently being
2135            // instrumented.
2136            aInfo = new ActivityInfo(aInfo);
2137            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2138            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2139                    aInfo.applicationInfo.uid);
2140            if (app == null || app.instrumentationClass == null) {
2141                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2142                mMainStack.startActivityLocked(null, intent, null, aInfo,
2143                        null, null, 0, 0, 0, 0, null, false, null);
2144            }
2145        }
2146        if (startingUser != null) {
2147            mMainStack.addStartingUserLocked(startingUser);
2148        }
2149
2150        return true;
2151    }
2152
2153    /**
2154     * Starts the "new version setup screen" if appropriate.
2155     */
2156    void startSetupActivityLocked() {
2157        // Only do this once per boot.
2158        if (mCheckedForSetup) {
2159            return;
2160        }
2161
2162        // We will show this screen if the current one is a different
2163        // version than the last one shown, and we are not running in
2164        // low-level factory test mode.
2165        final ContentResolver resolver = mContext.getContentResolver();
2166        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2167                Settings.Secure.getInt(resolver,
2168                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2169            mCheckedForSetup = true;
2170
2171            // See if we should be showing the platform update setup UI.
2172            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2173            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2174                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2175
2176            // We don't allow third party apps to replace this.
2177            ResolveInfo ri = null;
2178            for (int i=0; ris != null && i<ris.size(); i++) {
2179                if ((ris.get(i).activityInfo.applicationInfo.flags
2180                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2181                    ri = ris.get(i);
2182                    break;
2183                }
2184            }
2185
2186            if (ri != null) {
2187                String vers = ri.activityInfo.metaData != null
2188                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2189                        : null;
2190                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2191                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2192                            Intent.METADATA_SETUP_VERSION);
2193                }
2194                String lastVers = Settings.Secure.getString(
2195                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2196                if (vers != null && !vers.equals(lastVers)) {
2197                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2198                    intent.setComponent(new ComponentName(
2199                            ri.activityInfo.packageName, ri.activityInfo.name));
2200                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2201                            null, null, 0, 0, 0, 0, null, false, null);
2202                }
2203            }
2204        }
2205    }
2206
2207    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2208        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2209    }
2210
2211    void enforceNotIsolatedCaller(String caller) {
2212        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2213            throw new SecurityException("Isolated process not allowed to call " + caller);
2214        }
2215    }
2216
2217    public int getFrontActivityScreenCompatMode() {
2218        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2219        synchronized (this) {
2220            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2221        }
2222    }
2223
2224    public void setFrontActivityScreenCompatMode(int mode) {
2225        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2226                "setFrontActivityScreenCompatMode");
2227        synchronized (this) {
2228            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2229        }
2230    }
2231
2232    public int getPackageScreenCompatMode(String packageName) {
2233        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2234        synchronized (this) {
2235            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2236        }
2237    }
2238
2239    public void setPackageScreenCompatMode(String packageName, int mode) {
2240        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2241                "setPackageScreenCompatMode");
2242        synchronized (this) {
2243            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2244        }
2245    }
2246
2247    public boolean getPackageAskScreenCompat(String packageName) {
2248        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2249        synchronized (this) {
2250            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2251        }
2252    }
2253
2254    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2255        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2256                "setPackageAskScreenCompat");
2257        synchronized (this) {
2258            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2259        }
2260    }
2261
2262    void reportResumedActivityLocked(ActivityRecord r) {
2263        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2264        updateUsageStats(r, true);
2265    }
2266
2267    private void dispatchProcessesChanged() {
2268        int N;
2269        synchronized (this) {
2270            N = mPendingProcessChanges.size();
2271            if (mActiveProcessChanges.length < N) {
2272                mActiveProcessChanges = new ProcessChangeItem[N];
2273            }
2274            mPendingProcessChanges.toArray(mActiveProcessChanges);
2275            mAvailProcessChanges.addAll(mPendingProcessChanges);
2276            mPendingProcessChanges.clear();
2277            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2278        }
2279        int i = mProcessObservers.beginBroadcast();
2280        while (i > 0) {
2281            i--;
2282            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2283            if (observer != null) {
2284                try {
2285                    for (int j=0; j<N; j++) {
2286                        ProcessChangeItem item = mActiveProcessChanges[j];
2287                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2288                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2289                                    + item.pid + " uid=" + item.uid + ": "
2290                                    + item.foregroundActivities);
2291                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2292                                    item.foregroundActivities);
2293                        }
2294                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2295                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2296                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2297                            observer.onImportanceChanged(item.pid, item.uid,
2298                                    item.importance);
2299                        }
2300                    }
2301                } catch (RemoteException e) {
2302                }
2303            }
2304        }
2305        mProcessObservers.finishBroadcast();
2306    }
2307
2308    private void dispatchProcessDied(int pid, int uid) {
2309        int i = mProcessObservers.beginBroadcast();
2310        while (i > 0) {
2311            i--;
2312            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2313            if (observer != null) {
2314                try {
2315                    observer.onProcessDied(pid, uid);
2316                } catch (RemoteException e) {
2317                }
2318            }
2319        }
2320        mProcessObservers.finishBroadcast();
2321    }
2322
2323    final void doPendingActivityLaunchesLocked(boolean doResume) {
2324        final int N = mPendingActivityLaunches.size();
2325        if (N <= 0) {
2326            return;
2327        }
2328        for (int i=0; i<N; i++) {
2329            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2330            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2331                    pal.startFlags, doResume && i == (N-1), null);
2332        }
2333        mPendingActivityLaunches.clear();
2334    }
2335
2336    public final int startActivity(IApplicationThread caller,
2337            Intent intent, String resolvedType, IBinder resultTo,
2338            String resultWho, int requestCode, int startFlags,
2339            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2340        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2341                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2342    }
2343
2344    public final int startActivityAsUser(IApplicationThread caller,
2345            Intent intent, String resolvedType, IBinder resultTo,
2346            String resultWho, int requestCode, int startFlags,
2347            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2348        enforceNotIsolatedCaller("startActivity");
2349        if (userId != UserHandle.getCallingUserId()) {
2350            // Requesting a different user, make sure that they have the permission
2351            if (checkComponentPermission(
2352                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2353                    Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
2354                    == PackageManager.PERMISSION_GRANTED) {
2355                // Translate to the current user id, if caller wasn't aware
2356                if (userId == UserHandle.USER_CURRENT) {
2357                    userId = mCurrentUserId;
2358                }
2359            } else {
2360                String msg = "Permission Denial: "
2361                        + "Request to startActivity as user " + userId
2362                        + " but is calling from user " + UserHandle.getCallingUserId()
2363                        + "; this requires "
2364                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
2365                Slog.w(TAG, msg);
2366                throw new SecurityException(msg);
2367            }
2368        } else {
2369            if (intent.getCategories() != null
2370                    && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2371                // Requesting home, set the identity to the current user
2372                // HACK!
2373                userId = mCurrentUserId;
2374            } else {
2375                // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
2376                // the current user's userId
2377                if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
2378                    userId = 0;
2379                } else {
2380                    userId = Binder.getOrigCallingUser();
2381                }
2382            }
2383        }
2384        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2385                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2386                null, null, options, userId);
2387    }
2388
2389    public final WaitResult startActivityAndWait(IApplicationThread caller,
2390            Intent intent, String resolvedType, IBinder resultTo,
2391            String resultWho, int requestCode, int startFlags, String profileFile,
2392            ParcelFileDescriptor profileFd, Bundle options) {
2393        enforceNotIsolatedCaller("startActivityAndWait");
2394        WaitResult res = new WaitResult();
2395        int userId = Binder.getOrigCallingUser();
2396        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2397                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2398                res, null, options, userId);
2399        return res;
2400    }
2401
2402    public final int startActivityWithConfig(IApplicationThread caller,
2403            Intent intent, String resolvedType, IBinder resultTo,
2404            String resultWho, int requestCode, int startFlags, Configuration config,
2405            Bundle options) {
2406        enforceNotIsolatedCaller("startActivityWithConfig");
2407        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2408                resultTo, resultWho, requestCode, startFlags,
2409                null, null, null, config, options, Binder.getOrigCallingUser());
2410        return ret;
2411    }
2412
2413    public int startActivityIntentSender(IApplicationThread caller,
2414            IntentSender intent, Intent fillInIntent, String resolvedType,
2415            IBinder resultTo, String resultWho, int requestCode,
2416            int flagsMask, int flagsValues, Bundle options) {
2417        enforceNotIsolatedCaller("startActivityIntentSender");
2418        // Refuse possible leaked file descriptors
2419        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2420            throw new IllegalArgumentException("File descriptors passed in Intent");
2421        }
2422
2423        IIntentSender sender = intent.getTarget();
2424        if (!(sender instanceof PendingIntentRecord)) {
2425            throw new IllegalArgumentException("Bad PendingIntent object");
2426        }
2427
2428        PendingIntentRecord pir = (PendingIntentRecord)sender;
2429
2430        synchronized (this) {
2431            // If this is coming from the currently resumed activity, it is
2432            // effectively saying that app switches are allowed at this point.
2433            if (mMainStack.mResumedActivity != null
2434                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2435                            Binder.getCallingUid()) {
2436                mAppSwitchesAllowedTime = 0;
2437            }
2438        }
2439        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2440                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2441        return ret;
2442    }
2443
2444    public boolean startNextMatchingActivity(IBinder callingActivity,
2445            Intent intent, Bundle options) {
2446        // Refuse possible leaked file descriptors
2447        if (intent != null && intent.hasFileDescriptors() == true) {
2448            throw new IllegalArgumentException("File descriptors passed in Intent");
2449        }
2450
2451        synchronized (this) {
2452            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2453            if (r == null) {
2454                ActivityOptions.abort(options);
2455                return false;
2456            }
2457            if (r.app == null || r.app.thread == null) {
2458                // The caller is not running...  d'oh!
2459                ActivityOptions.abort(options);
2460                return false;
2461            }
2462            intent = new Intent(intent);
2463            // The caller is not allowed to change the data.
2464            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2465            // And we are resetting to find the next component...
2466            intent.setComponent(null);
2467
2468            ActivityInfo aInfo = null;
2469            try {
2470                List<ResolveInfo> resolves =
2471                    AppGlobals.getPackageManager().queryIntentActivities(
2472                            intent, r.resolvedType,
2473                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2474                            UserHandle.getCallingUserId());
2475
2476                // Look for the original activity in the list...
2477                final int N = resolves != null ? resolves.size() : 0;
2478                for (int i=0; i<N; i++) {
2479                    ResolveInfo rInfo = resolves.get(i);
2480                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2481                            && rInfo.activityInfo.name.equals(r.info.name)) {
2482                        // We found the current one...  the next matching is
2483                        // after it.
2484                        i++;
2485                        if (i<N) {
2486                            aInfo = resolves.get(i).activityInfo;
2487                        }
2488                        break;
2489                    }
2490                }
2491            } catch (RemoteException e) {
2492            }
2493
2494            if (aInfo == null) {
2495                // Nobody who is next!
2496                ActivityOptions.abort(options);
2497                return false;
2498            }
2499
2500            intent.setComponent(new ComponentName(
2501                    aInfo.applicationInfo.packageName, aInfo.name));
2502            intent.setFlags(intent.getFlags()&~(
2503                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2504                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2505                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2506                    Intent.FLAG_ACTIVITY_NEW_TASK));
2507
2508            // Okay now we need to start the new activity, replacing the
2509            // currently running activity.  This is a little tricky because
2510            // we want to start the new one as if the current one is finished,
2511            // but not finish the current one first so that there is no flicker.
2512            // And thus...
2513            final boolean wasFinishing = r.finishing;
2514            r.finishing = true;
2515
2516            // Propagate reply information over to the new activity.
2517            final ActivityRecord resultTo = r.resultTo;
2518            final String resultWho = r.resultWho;
2519            final int requestCode = r.requestCode;
2520            r.resultTo = null;
2521            if (resultTo != null) {
2522                resultTo.removeResultsLocked(r, resultWho, requestCode);
2523            }
2524
2525            final long origId = Binder.clearCallingIdentity();
2526            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2527                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2528                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2529                    options, false, null);
2530            Binder.restoreCallingIdentity(origId);
2531
2532            r.finishing = wasFinishing;
2533            if (res != ActivityManager.START_SUCCESS) {
2534                return false;
2535            }
2536            return true;
2537        }
2538    }
2539
2540    public final int startActivityInPackage(int uid,
2541            Intent intent, String resolvedType, IBinder resultTo,
2542            String resultWho, int requestCode, int startFlags, Bundle options) {
2543
2544        // This is so super not safe, that only the system (or okay root)
2545        // can do it.
2546        final int callingUid = Binder.getCallingUid();
2547        if (callingUid != 0 && callingUid != Process.myUid()) {
2548            throw new SecurityException(
2549                    "startActivityInPackage only available to the system");
2550        }
2551
2552        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2553                resultTo, resultWho, requestCode, startFlags,
2554                null, null, null, null, options, UserHandle.getUserId(uid));
2555        return ret;
2556    }
2557
2558    public final int startActivities(IApplicationThread caller,
2559            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2560        enforceNotIsolatedCaller("startActivities");
2561        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2562                options, Binder.getOrigCallingUser());
2563        return ret;
2564    }
2565
2566    public final int startActivitiesInPackage(int uid,
2567            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2568            Bundle options) {
2569
2570        // This is so super not safe, that only the system (or okay root)
2571        // can do it.
2572        final int callingUid = Binder.getCallingUid();
2573        if (callingUid != 0 && callingUid != Process.myUid()) {
2574            throw new SecurityException(
2575                    "startActivityInPackage only available to the system");
2576        }
2577        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2578                options, UserHandle.getUserId(uid));
2579        return ret;
2580    }
2581
2582    final void addRecentTaskLocked(TaskRecord task) {
2583        int N = mRecentTasks.size();
2584        // Quick case: check if the top-most recent task is the same.
2585        if (N > 0 && mRecentTasks.get(0) == task) {
2586            return;
2587        }
2588        // Remove any existing entries that are the same kind of task.
2589        for (int i=0; i<N; i++) {
2590            TaskRecord tr = mRecentTasks.get(i);
2591            if (task.userId == tr.userId
2592                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2593                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2594                mRecentTasks.remove(i);
2595                i--;
2596                N--;
2597                if (task.intent == null) {
2598                    // If the new recent task we are adding is not fully
2599                    // specified, then replace it with the existing recent task.
2600                    task = tr;
2601                }
2602            }
2603        }
2604        if (N >= MAX_RECENT_TASKS) {
2605            mRecentTasks.remove(N-1);
2606        }
2607        mRecentTasks.add(0, task);
2608    }
2609
2610    public void setRequestedOrientation(IBinder token,
2611            int requestedOrientation) {
2612        synchronized (this) {
2613            ActivityRecord r = mMainStack.isInStackLocked(token);
2614            if (r == null) {
2615                return;
2616            }
2617            final long origId = Binder.clearCallingIdentity();
2618            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2619            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2620                    mConfiguration,
2621                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2622            if (config != null) {
2623                r.frozenBeforeDestroy = true;
2624                if (!updateConfigurationLocked(config, r, false, false)) {
2625                    mMainStack.resumeTopActivityLocked(null);
2626                }
2627            }
2628            Binder.restoreCallingIdentity(origId);
2629        }
2630    }
2631
2632    public int getRequestedOrientation(IBinder token) {
2633        synchronized (this) {
2634            ActivityRecord r = mMainStack.isInStackLocked(token);
2635            if (r == null) {
2636                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2637            }
2638            return mWindowManager.getAppOrientation(r.appToken);
2639        }
2640    }
2641
2642    /**
2643     * This is the internal entry point for handling Activity.finish().
2644     *
2645     * @param token The Binder token referencing the Activity we want to finish.
2646     * @param resultCode Result code, if any, from this Activity.
2647     * @param resultData Result data (Intent), if any, from this Activity.
2648     *
2649     * @return Returns true if the activity successfully finished, or false if it is still running.
2650     */
2651    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2652        // Refuse possible leaked file descriptors
2653        if (resultData != null && resultData.hasFileDescriptors() == true) {
2654            throw new IllegalArgumentException("File descriptors passed in Intent");
2655        }
2656
2657        synchronized(this) {
2658            if (mController != null) {
2659                // Find the first activity that is not finishing.
2660                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2661                if (next != null) {
2662                    // ask watcher if this is allowed
2663                    boolean resumeOK = true;
2664                    try {
2665                        resumeOK = mController.activityResuming(next.packageName);
2666                    } catch (RemoteException e) {
2667                        mController = null;
2668                    }
2669
2670                    if (!resumeOK) {
2671                        return false;
2672                    }
2673                }
2674            }
2675            final long origId = Binder.clearCallingIdentity();
2676            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2677                    resultData, "app-request");
2678            Binder.restoreCallingIdentity(origId);
2679            return res;
2680        }
2681    }
2682
2683    public final void finishHeavyWeightApp() {
2684        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2685                != PackageManager.PERMISSION_GRANTED) {
2686            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2687                    + Binder.getCallingPid()
2688                    + ", uid=" + Binder.getCallingUid()
2689                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2690            Slog.w(TAG, msg);
2691            throw new SecurityException(msg);
2692        }
2693
2694        synchronized(this) {
2695            if (mHeavyWeightProcess == null) {
2696                return;
2697            }
2698
2699            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2700                    mHeavyWeightProcess.activities);
2701            for (int i=0; i<activities.size(); i++) {
2702                ActivityRecord r = activities.get(i);
2703                if (!r.finishing) {
2704                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2705                    if (index >= 0) {
2706                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2707                                null, "finish-heavy");
2708                    }
2709                }
2710            }
2711
2712            mHeavyWeightProcess = null;
2713            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2714        }
2715    }
2716
2717    public void crashApplication(int uid, int initialPid, String packageName,
2718            String message) {
2719        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2720                != PackageManager.PERMISSION_GRANTED) {
2721            String msg = "Permission Denial: crashApplication() from pid="
2722                    + Binder.getCallingPid()
2723                    + ", uid=" + Binder.getCallingUid()
2724                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2725            Slog.w(TAG, msg);
2726            throw new SecurityException(msg);
2727        }
2728
2729        synchronized(this) {
2730            ProcessRecord proc = null;
2731
2732            // Figure out which process to kill.  We don't trust that initialPid
2733            // still has any relation to current pids, so must scan through the
2734            // list.
2735            synchronized (mPidsSelfLocked) {
2736                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2737                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2738                    if (p.uid != uid) {
2739                        continue;
2740                    }
2741                    if (p.pid == initialPid) {
2742                        proc = p;
2743                        break;
2744                    }
2745                    for (String str : p.pkgList) {
2746                        if (str.equals(packageName)) {
2747                            proc = p;
2748                        }
2749                    }
2750                }
2751            }
2752
2753            if (proc == null) {
2754                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2755                        + " initialPid=" + initialPid
2756                        + " packageName=" + packageName);
2757                return;
2758            }
2759
2760            if (proc.thread != null) {
2761                if (proc.pid == Process.myPid()) {
2762                    Log.w(TAG, "crashApplication: trying to crash self!");
2763                    return;
2764                }
2765                long ident = Binder.clearCallingIdentity();
2766                try {
2767                    proc.thread.scheduleCrash(message);
2768                } catch (RemoteException e) {
2769                }
2770                Binder.restoreCallingIdentity(ident);
2771            }
2772        }
2773    }
2774
2775    public final void finishSubActivity(IBinder token, String resultWho,
2776            int requestCode) {
2777        synchronized(this) {
2778            final long origId = Binder.clearCallingIdentity();
2779            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2780            Binder.restoreCallingIdentity(origId);
2781        }
2782    }
2783
2784    public boolean finishActivityAffinity(IBinder token) {
2785        synchronized(this) {
2786            final long origId = Binder.clearCallingIdentity();
2787            boolean res = mMainStack.finishActivityAffinityLocked(token);
2788            Binder.restoreCallingIdentity(origId);
2789            return res;
2790        }
2791    }
2792
2793    public boolean willActivityBeVisible(IBinder token) {
2794        synchronized(this) {
2795            int i;
2796            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2797                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2798                if (r.appToken == token) {
2799                    return true;
2800                }
2801                if (r.fullscreen && !r.finishing) {
2802                    return false;
2803                }
2804            }
2805            return true;
2806        }
2807    }
2808
2809    public void overridePendingTransition(IBinder token, String packageName,
2810            int enterAnim, int exitAnim) {
2811        synchronized(this) {
2812            ActivityRecord self = mMainStack.isInStackLocked(token);
2813            if (self == null) {
2814                return;
2815            }
2816
2817            final long origId = Binder.clearCallingIdentity();
2818
2819            if (self.state == ActivityState.RESUMED
2820                    || self.state == ActivityState.PAUSING) {
2821                mWindowManager.overridePendingAppTransition(packageName,
2822                        enterAnim, exitAnim, null);
2823            }
2824
2825            Binder.restoreCallingIdentity(origId);
2826        }
2827    }
2828
2829    /**
2830     * Main function for removing an existing process from the activity manager
2831     * as a result of that process going away.  Clears out all connections
2832     * to the process.
2833     */
2834    private final void handleAppDiedLocked(ProcessRecord app,
2835            boolean restarting, boolean allowRestart) {
2836        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2837        if (!restarting) {
2838            mLruProcesses.remove(app);
2839        }
2840
2841        if (mProfileProc == app) {
2842            clearProfilerLocked();
2843        }
2844
2845        // Just in case...
2846        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2847            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2848            mMainStack.mPausingActivity = null;
2849        }
2850        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2851            mMainStack.mLastPausedActivity = null;
2852        }
2853
2854        // Remove this application's activities from active lists.
2855        mMainStack.removeHistoryRecordsForAppLocked(app);
2856
2857        boolean atTop = true;
2858        boolean hasVisibleActivities = false;
2859
2860        // Clean out the history list.
2861        int i = mMainStack.mHistory.size();
2862        if (localLOGV) Slog.v(
2863            TAG, "Removing app " + app + " from history with " + i + " entries");
2864        while (i > 0) {
2865            i--;
2866            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2867            if (localLOGV) Slog.v(
2868                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2869            if (r.app == app) {
2870                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2871                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2872                        RuntimeException here = new RuntimeException("here");
2873                        here.fillInStackTrace();
2874                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2875                                + ": haveState=" + r.haveState
2876                                + " stateNotNeeded=" + r.stateNotNeeded
2877                                + " finishing=" + r.finishing
2878                                + " state=" + r.state, here);
2879                    }
2880                    if (!r.finishing) {
2881                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2882                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2883                                System.identityHashCode(r),
2884                                r.task.taskId, r.shortComponentName,
2885                                "proc died without state saved");
2886                    }
2887                    mMainStack.removeActivityFromHistoryLocked(r);
2888
2889                } else {
2890                    // We have the current state for this activity, so
2891                    // it can be restarted later when needed.
2892                    if (localLOGV) Slog.v(
2893                        TAG, "Keeping entry, setting app to null");
2894                    if (r.visible) {
2895                        hasVisibleActivities = true;
2896                    }
2897                    r.app = null;
2898                    r.nowVisible = false;
2899                    if (!r.haveState) {
2900                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2901                                "App died, clearing saved state of " + r);
2902                        r.icicle = null;
2903                    }
2904                }
2905
2906                r.stack.cleanUpActivityLocked(r, true, true);
2907            }
2908            atTop = false;
2909        }
2910
2911        app.activities.clear();
2912
2913        if (app.instrumentationClass != null) {
2914            Slog.w(TAG, "Crash of app " + app.processName
2915                  + " running instrumentation " + app.instrumentationClass);
2916            Bundle info = new Bundle();
2917            info.putString("shortMsg", "Process crashed.");
2918            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2919        }
2920
2921        if (!restarting) {
2922            if (!mMainStack.resumeTopActivityLocked(null)) {
2923                // If there was nothing to resume, and we are not already
2924                // restarting this process, but there is a visible activity that
2925                // is hosted by the process...  then make sure all visible
2926                // activities are running, taking care of restarting this
2927                // process.
2928                if (hasVisibleActivities) {
2929                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2930                }
2931            }
2932        }
2933    }
2934
2935    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2936        IBinder threadBinder = thread.asBinder();
2937        // Find the application record.
2938        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2939            ProcessRecord rec = mLruProcesses.get(i);
2940            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2941                return i;
2942            }
2943        }
2944        return -1;
2945    }
2946
2947    final ProcessRecord getRecordForAppLocked(
2948            IApplicationThread thread) {
2949        if (thread == null) {
2950            return null;
2951        }
2952
2953        int appIndex = getLRURecordIndexForAppLocked(thread);
2954        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2955    }
2956
2957    final void appDiedLocked(ProcessRecord app, int pid,
2958            IApplicationThread thread) {
2959
2960        mProcDeaths[0]++;
2961
2962        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2963        synchronized (stats) {
2964            stats.noteProcessDiedLocked(app.info.uid, pid);
2965        }
2966
2967        // Clean up already done if the process has been re-started.
2968        if (app.pid == pid && app.thread != null &&
2969                app.thread.asBinder() == thread.asBinder()) {
2970            if (!app.killedBackground) {
2971                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2972                        + ") has died.");
2973            }
2974            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2975            if (localLOGV) Slog.v(
2976                TAG, "Dying app: " + app + ", pid: " + pid
2977                + ", thread: " + thread.asBinder());
2978            boolean doLowMem = app.instrumentationClass == null;
2979            handleAppDiedLocked(app, false, true);
2980
2981            if (doLowMem) {
2982                // If there are no longer any background processes running,
2983                // and the app that died was not running instrumentation,
2984                // then tell everyone we are now low on memory.
2985                boolean haveBg = false;
2986                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2987                    ProcessRecord rec = mLruProcesses.get(i);
2988                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2989                        haveBg = true;
2990                        break;
2991                    }
2992                }
2993
2994                if (!haveBg) {
2995                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2996                    long now = SystemClock.uptimeMillis();
2997                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2998                        ProcessRecord rec = mLruProcesses.get(i);
2999                        if (rec != app && rec.thread != null &&
3000                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3001                            // The low memory report is overriding any current
3002                            // state for a GC request.  Make sure to do
3003                            // heavy/important/visible/foreground processes first.
3004                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3005                                rec.lastRequestedGc = 0;
3006                            } else {
3007                                rec.lastRequestedGc = rec.lastLowMemory;
3008                            }
3009                            rec.reportLowMemory = true;
3010                            rec.lastLowMemory = now;
3011                            mProcessesToGc.remove(rec);
3012                            addProcessToGcListLocked(rec);
3013                        }
3014                    }
3015                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3016                    scheduleAppGcsLocked();
3017                }
3018            }
3019        } else if (app.pid != pid) {
3020            // A new process has already been started.
3021            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3022                    + ") has died and restarted (pid " + app.pid + ").");
3023            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3024        } else if (DEBUG_PROCESSES) {
3025            Slog.d(TAG, "Received spurious death notification for thread "
3026                    + thread.asBinder());
3027        }
3028    }
3029
3030    /**
3031     * If a stack trace dump file is configured, dump process stack traces.
3032     * @param clearTraces causes the dump file to be erased prior to the new
3033     *    traces being written, if true; when false, the new traces will be
3034     *    appended to any existing file content.
3035     * @param firstPids of dalvik VM processes to dump stack traces for first
3036     * @param lastPids of dalvik VM processes to dump stack traces for last
3037     * @param nativeProcs optional list of native process names to dump stack crawls
3038     * @return file containing stack traces, or null if no dump file is configured
3039     */
3040    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3041            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3042        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3043        if (tracesPath == null || tracesPath.length() == 0) {
3044            return null;
3045        }
3046
3047        File tracesFile = new File(tracesPath);
3048        try {
3049            File tracesDir = tracesFile.getParentFile();
3050            if (!tracesDir.exists()) {
3051                tracesFile.mkdirs();
3052                if (!SELinux.restorecon(tracesDir)) {
3053                    return null;
3054                }
3055            }
3056            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3057
3058            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3059            tracesFile.createNewFile();
3060            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3061        } catch (IOException e) {
3062            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3063            return null;
3064        }
3065
3066        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3067        return tracesFile;
3068    }
3069
3070    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3071            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3072        // Use a FileObserver to detect when traces finish writing.
3073        // The order of traces is considered important to maintain for legibility.
3074        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3075            public synchronized void onEvent(int event, String path) { notify(); }
3076        };
3077
3078        try {
3079            observer.startWatching();
3080
3081            // First collect all of the stacks of the most important pids.
3082            if (firstPids != null) {
3083                try {
3084                    int num = firstPids.size();
3085                    for (int i = 0; i < num; i++) {
3086                        synchronized (observer) {
3087                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3088                            observer.wait(200);  // Wait for write-close, give up after 200msec
3089                        }
3090                    }
3091                } catch (InterruptedException e) {
3092                    Log.wtf(TAG, e);
3093                }
3094            }
3095
3096            // Next measure CPU usage.
3097            if (processStats != null) {
3098                processStats.init();
3099                System.gc();
3100                processStats.update();
3101                try {
3102                    synchronized (processStats) {
3103                        processStats.wait(500); // measure over 1/2 second.
3104                    }
3105                } catch (InterruptedException e) {
3106                }
3107                processStats.update();
3108
3109                // We'll take the stack crawls of just the top apps using CPU.
3110                final int N = processStats.countWorkingStats();
3111                int numProcs = 0;
3112                for (int i=0; i<N && numProcs<5; i++) {
3113                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3114                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3115                        numProcs++;
3116                        try {
3117                            synchronized (observer) {
3118                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3119                                observer.wait(200);  // Wait for write-close, give up after 200msec
3120                            }
3121                        } catch (InterruptedException e) {
3122                            Log.wtf(TAG, e);
3123                        }
3124
3125                    }
3126                }
3127            }
3128
3129        } finally {
3130            observer.stopWatching();
3131        }
3132
3133        if (nativeProcs != null) {
3134            int[] pids = Process.getPidsForCommands(nativeProcs);
3135            if (pids != null) {
3136                for (int pid : pids) {
3137                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3138                }
3139            }
3140        }
3141    }
3142
3143    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3144        if (true || IS_USER_BUILD) {
3145            return;
3146        }
3147        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3148        if (tracesPath == null || tracesPath.length() == 0) {
3149            return;
3150        }
3151
3152        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3153        StrictMode.allowThreadDiskWrites();
3154        try {
3155            final File tracesFile = new File(tracesPath);
3156            final File tracesDir = tracesFile.getParentFile();
3157            final File tracesTmp = new File(tracesDir, "__tmp__");
3158            try {
3159                if (!tracesDir.exists()) {
3160                    tracesFile.mkdirs();
3161                    if (!SELinux.restorecon(tracesDir.getPath())) {
3162                        return;
3163                    }
3164                }
3165                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3166
3167                if (tracesFile.exists()) {
3168                    tracesTmp.delete();
3169                    tracesFile.renameTo(tracesTmp);
3170                }
3171                StringBuilder sb = new StringBuilder();
3172                Time tobj = new Time();
3173                tobj.set(System.currentTimeMillis());
3174                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3175                sb.append(": ");
3176                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3177                sb.append(" since ");
3178                sb.append(msg);
3179                FileOutputStream fos = new FileOutputStream(tracesFile);
3180                fos.write(sb.toString().getBytes());
3181                if (app == null) {
3182                    fos.write("\n*** No application process!".getBytes());
3183                }
3184                fos.close();
3185                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3186            } catch (IOException e) {
3187                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3188                return;
3189            }
3190
3191            if (app != null) {
3192                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3193                firstPids.add(app.pid);
3194                dumpStackTraces(tracesPath, firstPids, null, null, null);
3195            }
3196
3197            File lastTracesFile = null;
3198            File curTracesFile = null;
3199            for (int i=9; i>=0; i--) {
3200                String name = String.format("slow%02d.txt", i);
3201                curTracesFile = new File(tracesDir, name);
3202                if (curTracesFile.exists()) {
3203                    if (lastTracesFile != null) {
3204                        curTracesFile.renameTo(lastTracesFile);
3205                    } else {
3206                        curTracesFile.delete();
3207                    }
3208                }
3209                lastTracesFile = curTracesFile;
3210            }
3211            tracesFile.renameTo(curTracesFile);
3212            if (tracesTmp.exists()) {
3213                tracesTmp.renameTo(tracesFile);
3214            }
3215        } finally {
3216            StrictMode.setThreadPolicy(oldPolicy);
3217        }
3218    }
3219
3220    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3221            ActivityRecord parent, final String annotation) {
3222        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3223        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3224
3225        if (mController != null) {
3226            try {
3227                // 0 == continue, -1 = kill process immediately
3228                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3229                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3230            } catch (RemoteException e) {
3231                mController = null;
3232            }
3233        }
3234
3235        long anrTime = SystemClock.uptimeMillis();
3236        if (MONITOR_CPU_USAGE) {
3237            updateCpuStatsNow();
3238        }
3239
3240        synchronized (this) {
3241            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3242            if (mShuttingDown) {
3243                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3244                return;
3245            } else if (app.notResponding) {
3246                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3247                return;
3248            } else if (app.crashing) {
3249                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3250                return;
3251            }
3252
3253            // In case we come through here for the same app before completing
3254            // this one, mark as anring now so we will bail out.
3255            app.notResponding = true;
3256
3257            // Log the ANR to the event log.
3258            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3259                    annotation);
3260
3261            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3262            firstPids.add(app.pid);
3263
3264            int parentPid = app.pid;
3265            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3266            if (parentPid != app.pid) firstPids.add(parentPid);
3267
3268            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3269
3270            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3271                ProcessRecord r = mLruProcesses.get(i);
3272                if (r != null && r.thread != null) {
3273                    int pid = r.pid;
3274                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3275                        if (r.persistent) {
3276                            firstPids.add(pid);
3277                        } else {
3278                            lastPids.put(pid, Boolean.TRUE);
3279                        }
3280                    }
3281                }
3282            }
3283        }
3284
3285        // Log the ANR to the main log.
3286        StringBuilder info = new StringBuilder();
3287        info.setLength(0);
3288        info.append("ANR in ").append(app.processName);
3289        if (activity != null && activity.shortComponentName != null) {
3290            info.append(" (").append(activity.shortComponentName).append(")");
3291        }
3292        info.append("\n");
3293        if (annotation != null) {
3294            info.append("Reason: ").append(annotation).append("\n");
3295        }
3296        if (parent != null && parent != activity) {
3297            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3298        }
3299
3300        final ProcessStats processStats = new ProcessStats(true);
3301
3302        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3303
3304        String cpuInfo = null;
3305        if (MONITOR_CPU_USAGE) {
3306            updateCpuStatsNow();
3307            synchronized (mProcessStatsThread) {
3308                cpuInfo = mProcessStats.printCurrentState(anrTime);
3309            }
3310            info.append(processStats.printCurrentLoad());
3311            info.append(cpuInfo);
3312        }
3313
3314        info.append(processStats.printCurrentState(anrTime));
3315
3316        Slog.e(TAG, info.toString());
3317        if (tracesFile == null) {
3318            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3319            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3320        }
3321
3322        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3323                cpuInfo, tracesFile, null);
3324
3325        if (mController != null) {
3326            try {
3327                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3328                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3329                if (res != 0) {
3330                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3331                    return;
3332                }
3333            } catch (RemoteException e) {
3334                mController = null;
3335            }
3336        }
3337
3338        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3339        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3340                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3341
3342        synchronized (this) {
3343            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3344                Slog.w(TAG, "Killing " + app + ": background ANR");
3345                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3346                        app.processName, app.setAdj, "background ANR");
3347                Process.killProcessQuiet(app.pid);
3348                return;
3349            }
3350
3351            // Set the app's notResponding state, and look up the errorReportReceiver
3352            makeAppNotRespondingLocked(app,
3353                    activity != null ? activity.shortComponentName : null,
3354                    annotation != null ? "ANR " + annotation : "ANR",
3355                    info.toString());
3356
3357            // Bring up the infamous App Not Responding dialog
3358            Message msg = Message.obtain();
3359            HashMap map = new HashMap();
3360            msg.what = SHOW_NOT_RESPONDING_MSG;
3361            msg.obj = map;
3362            map.put("app", app);
3363            if (activity != null) {
3364                map.put("activity", activity);
3365            }
3366
3367            mHandler.sendMessage(msg);
3368        }
3369    }
3370
3371    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3372        if (!mLaunchWarningShown) {
3373            mLaunchWarningShown = true;
3374            mHandler.post(new Runnable() {
3375                @Override
3376                public void run() {
3377                    synchronized (ActivityManagerService.this) {
3378                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3379                        d.show();
3380                        mHandler.postDelayed(new Runnable() {
3381                            @Override
3382                            public void run() {
3383                                synchronized (ActivityManagerService.this) {
3384                                    d.dismiss();
3385                                    mLaunchWarningShown = false;
3386                                }
3387                            }
3388                        }, 4000);
3389                    }
3390                }
3391            });
3392        }
3393    }
3394
3395    public boolean clearApplicationUserData(final String packageName,
3396            final IPackageDataObserver observer, final int userId) {
3397        enforceNotIsolatedCaller("clearApplicationUserData");
3398        int uid = Binder.getCallingUid();
3399        int pid = Binder.getCallingPid();
3400        long callingId = Binder.clearCallingIdentity();
3401        try {
3402            IPackageManager pm = AppGlobals.getPackageManager();
3403            int pkgUid = -1;
3404            synchronized(this) {
3405                try {
3406                    pkgUid = pm.getPackageUid(packageName, userId);
3407                } catch (RemoteException e) {
3408                }
3409                if (pkgUid == -1) {
3410                    Slog.w(TAG, "Invalid packageName:" + packageName);
3411                    return false;
3412                }
3413                if (uid == pkgUid || checkComponentPermission(
3414                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3415                        pid, uid, -1, true)
3416                        == PackageManager.PERMISSION_GRANTED) {
3417                    forceStopPackageLocked(packageName, pkgUid);
3418                } else {
3419                    throw new SecurityException(pid+" does not have permission:"+
3420                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3421                                    "for process:"+packageName);
3422                }
3423            }
3424
3425            try {
3426                //clear application user data
3427                pm.clearApplicationUserData(packageName, observer, userId);
3428                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3429                        Uri.fromParts("package", packageName, null));
3430                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3431                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3432                        null, null, 0, null, null, null, false, false, userId);
3433            } catch (RemoteException e) {
3434            }
3435        } finally {
3436            Binder.restoreCallingIdentity(callingId);
3437        }
3438        return true;
3439    }
3440
3441    public void killBackgroundProcesses(final String packageName) {
3442        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3443                != PackageManager.PERMISSION_GRANTED &&
3444                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3445                        != PackageManager.PERMISSION_GRANTED) {
3446            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3447                    + Binder.getCallingPid()
3448                    + ", uid=" + Binder.getCallingUid()
3449                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3450            Slog.w(TAG, msg);
3451            throw new SecurityException(msg);
3452        }
3453
3454        int userId = UserHandle.getCallingUserId();
3455        long callingId = Binder.clearCallingIdentity();
3456        try {
3457            IPackageManager pm = AppGlobals.getPackageManager();
3458            int pkgUid = -1;
3459            synchronized(this) {
3460                try {
3461                    pkgUid = pm.getPackageUid(packageName, userId);
3462                } catch (RemoteException e) {
3463                }
3464                if (pkgUid == -1) {
3465                    Slog.w(TAG, "Invalid packageName: " + packageName);
3466                    return;
3467                }
3468                killPackageProcessesLocked(packageName, pkgUid, -1,
3469                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3470            }
3471        } finally {
3472            Binder.restoreCallingIdentity(callingId);
3473        }
3474    }
3475
3476    public void killAllBackgroundProcesses() {
3477        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3478                != PackageManager.PERMISSION_GRANTED) {
3479            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3480                    + Binder.getCallingPid()
3481                    + ", uid=" + Binder.getCallingUid()
3482                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3483            Slog.w(TAG, msg);
3484            throw new SecurityException(msg);
3485        }
3486
3487        long callingId = Binder.clearCallingIdentity();
3488        try {
3489            synchronized(this) {
3490                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3491                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3492                    final int NA = apps.size();
3493                    for (int ia=0; ia<NA; ia++) {
3494                        ProcessRecord app = apps.valueAt(ia);
3495                        if (app.persistent) {
3496                            // we don't kill persistent processes
3497                            continue;
3498                        }
3499                        if (app.removed) {
3500                            procs.add(app);
3501                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3502                            app.removed = true;
3503                            procs.add(app);
3504                        }
3505                    }
3506                }
3507
3508                int N = procs.size();
3509                for (int i=0; i<N; i++) {
3510                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3511                }
3512            }
3513        } finally {
3514            Binder.restoreCallingIdentity(callingId);
3515        }
3516    }
3517
3518    public void forceStopPackage(final String packageName) {
3519        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3520                != PackageManager.PERMISSION_GRANTED) {
3521            String msg = "Permission Denial: forceStopPackage() from pid="
3522                    + Binder.getCallingPid()
3523                    + ", uid=" + Binder.getCallingUid()
3524                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3525            Slog.w(TAG, msg);
3526            throw new SecurityException(msg);
3527        }
3528        final int userId = UserHandle.getCallingUserId();
3529        long callingId = Binder.clearCallingIdentity();
3530        try {
3531            IPackageManager pm = AppGlobals.getPackageManager();
3532            int pkgUid = -1;
3533            synchronized(this) {
3534                try {
3535                    pkgUid = pm.getPackageUid(packageName, userId);
3536                } catch (RemoteException e) {
3537                }
3538                if (pkgUid == -1) {
3539                    Slog.w(TAG, "Invalid packageName: " + packageName);
3540                    return;
3541                }
3542                forceStopPackageLocked(packageName, pkgUid);
3543                try {
3544                    pm.setPackageStoppedState(packageName, true, userId);
3545                } catch (RemoteException e) {
3546                } catch (IllegalArgumentException e) {
3547                    Slog.w(TAG, "Failed trying to unstop package "
3548                            + packageName + ": " + e);
3549                }
3550            }
3551        } finally {
3552            Binder.restoreCallingIdentity(callingId);
3553        }
3554    }
3555
3556    /*
3557     * The pkg name and uid have to be specified.
3558     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3559     */
3560    public void killApplicationWithUid(String pkg, int uid) {
3561        if (pkg == null) {
3562            return;
3563        }
3564        // Make sure the uid is valid.
3565        if (uid < 0) {
3566            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3567            return;
3568        }
3569        int callerUid = Binder.getCallingUid();
3570        // Only the system server can kill an application
3571        if (callerUid == Process.SYSTEM_UID) {
3572            // Post an aysnc message to kill the application
3573            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3574            msg.arg1 = uid;
3575            msg.arg2 = 0;
3576            msg.obj = pkg;
3577            mHandler.sendMessage(msg);
3578        } else {
3579            throw new SecurityException(callerUid + " cannot kill pkg: " +
3580                    pkg);
3581        }
3582    }
3583
3584    public void closeSystemDialogs(String reason) {
3585        enforceNotIsolatedCaller("closeSystemDialogs");
3586
3587        final int uid = Binder.getCallingUid();
3588        final long origId = Binder.clearCallingIdentity();
3589        synchronized (this) {
3590            closeSystemDialogsLocked(uid, reason);
3591        }
3592        Binder.restoreCallingIdentity(origId);
3593    }
3594
3595    void closeSystemDialogsLocked(int callingUid, String reason) {
3596        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3597        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3598        if (reason != null) {
3599            intent.putExtra("reason", reason);
3600        }
3601        mWindowManager.closeSystemDialogs(reason);
3602
3603        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3604            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3605            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3606                r.stack.finishActivityLocked(r, i,
3607                        Activity.RESULT_CANCELED, null, "close-sys");
3608            }
3609        }
3610
3611        broadcastIntentLocked(null, null, intent, null,
3612                null, 0, null, null, null, false, false, -1,
3613                callingUid, 0 /* TODO: Verify */);
3614    }
3615
3616    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3617            throws RemoteException {
3618        enforceNotIsolatedCaller("getProcessMemoryInfo");
3619        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3620        for (int i=pids.length-1; i>=0; i--) {
3621            infos[i] = new Debug.MemoryInfo();
3622            Debug.getMemoryInfo(pids[i], infos[i]);
3623        }
3624        return infos;
3625    }
3626
3627    public long[] getProcessPss(int[] pids) throws RemoteException {
3628        enforceNotIsolatedCaller("getProcessPss");
3629        long[] pss = new long[pids.length];
3630        for (int i=pids.length-1; i>=0; i--) {
3631            pss[i] = Debug.getPss(pids[i]);
3632        }
3633        return pss;
3634    }
3635
3636    public void killApplicationProcess(String processName, int uid) {
3637        if (processName == null) {
3638            return;
3639        }
3640
3641        int callerUid = Binder.getCallingUid();
3642        // Only the system server can kill an application
3643        if (callerUid == Process.SYSTEM_UID) {
3644            synchronized (this) {
3645                ProcessRecord app = getProcessRecordLocked(processName, uid);
3646                if (app != null && app.thread != null) {
3647                    try {
3648                        app.thread.scheduleSuicide();
3649                    } catch (RemoteException e) {
3650                        // If the other end already died, then our work here is done.
3651                    }
3652                } else {
3653                    Slog.w(TAG, "Process/uid not found attempting kill of "
3654                            + processName + " / " + uid);
3655                }
3656            }
3657        } else {
3658            throw new SecurityException(callerUid + " cannot kill app process: " +
3659                    processName);
3660        }
3661    }
3662
3663    private void forceStopPackageLocked(final String packageName, int uid) {
3664        forceStopPackageLocked(packageName, uid, false, false, true, false,
3665                UserHandle.getUserId(uid));
3666        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3667                Uri.fromParts("package", packageName, null));
3668        if (!mProcessesReady) {
3669            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3670        }
3671        intent.putExtra(Intent.EXTRA_UID, uid);
3672        broadcastIntentLocked(null, null, intent,
3673                null, null, 0, null, null, null,
3674                false, false,
3675                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3676    }
3677
3678    private void forceStopUserLocked(int userId) {
3679        forceStopPackageLocked(null, -1, false, false, true, false, userId);
3680        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3681        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3682        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3683        broadcastIntentLocked(null, null, intent,
3684                null, null, 0, null, null, null,
3685                false, false,
3686                MY_PID, Process.SYSTEM_UID, userId);
3687    }
3688
3689    private final boolean killPackageProcessesLocked(String packageName, int uid,
3690            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3691            boolean doit, boolean evenPersistent, String reason) {
3692        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3693
3694        // Remove all processes this package may have touched: all with the
3695        // same UID (except for the system or root user), and all whose name
3696        // matches the package name.
3697        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3698        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3699            final int NA = apps.size();
3700            for (int ia=0; ia<NA; ia++) {
3701                ProcessRecord app = apps.valueAt(ia);
3702                if (app.persistent && !evenPersistent) {
3703                    // we don't kill persistent processes
3704                    continue;
3705                }
3706                if (app.removed) {
3707                    if (doit) {
3708                        procs.add(app);
3709                    }
3710                // If no package is specified, we call all processes under the
3711                // give user id.
3712                } else if (packageName == null) {
3713                    if (app.userId == userId) {
3714                        if (app.setAdj >= minOomAdj) {
3715                            if (!doit) {
3716                                return true;
3717                            }
3718                            app.removed = true;
3719                            procs.add(app);
3720                        }
3721                    }
3722                // If uid is specified and the uid and process name match
3723                // Or, the uid is not specified and the process name matches
3724                } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3725                            || ((app.processName.equals(packageName)
3726                                 || app.processName.startsWith(procNamePrefix))
3727                                && uid < 0))) {
3728                    if (app.setAdj >= minOomAdj) {
3729                        if (!doit) {
3730                            return true;
3731                        }
3732                        app.removed = true;
3733                        procs.add(app);
3734                    }
3735                }
3736            }
3737        }
3738
3739        int N = procs.size();
3740        for (int i=0; i<N; i++) {
3741            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3742        }
3743        return N > 0;
3744    }
3745
3746    private final boolean forceStopPackageLocked(String name, int uid,
3747            boolean callerWillRestart, boolean purgeCache, boolean doit,
3748            boolean evenPersistent, int userId) {
3749        int i;
3750        int N;
3751
3752        if (uid < 0 && name != null) {
3753            try {
3754                uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
3755            } catch (RemoteException e) {
3756            }
3757        }
3758
3759        if (doit) {
3760            if (name != null) {
3761                Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3762            } else {
3763                Slog.i(TAG, "Force stopping user " + userId);
3764            }
3765
3766            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3767            while (badApps.hasNext()) {
3768                SparseArray<Long> ba = badApps.next();
3769                for (i=ba.size()-1; i>=0; i--) {
3770                    boolean remove = false;
3771                    final int entUid = ba.keyAt(i);
3772                    if (name != null) {
3773                        if (entUid == uid) {
3774                            remove = true;
3775                        }
3776                    } else if (UserHandle.getUserId(entUid) == userId) {
3777                        remove = true;
3778                    }
3779                    if (remove) {
3780                        ba.removeAt(i);
3781                    }
3782                }
3783                if (ba.size() == 0) {
3784                    badApps.remove();
3785                }
3786            }
3787        }
3788
3789        boolean didSomething = killPackageProcessesLocked(name, uid,
3790                name == null ? userId : -1 , -100, callerWillRestart, false,
3791                doit, evenPersistent,
3792                name == null ? ("force stop user " + userId) : ("force stop " + name));
3793
3794        TaskRecord lastTask = null;
3795        for (i=0; i<mMainStack.mHistory.size(); i++) {
3796            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3797            final boolean samePackage = r.packageName.equals(name)
3798                    || (name == null && r.userId == userId);
3799            if (r.userId == userId
3800                    && (samePackage || r.task == lastTask)
3801                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3802                if (!doit) {
3803                    if (r.finishing) {
3804                        // If this activity is just finishing, then it is not
3805                        // interesting as far as something to stop.
3806                        continue;
3807                    }
3808                    return true;
3809                }
3810                didSomething = true;
3811                Slog.i(TAG, "  Force finishing activity " + r);
3812                if (samePackage) {
3813                    if (r.app != null) {
3814                        r.app.removed = true;
3815                    }
3816                    r.app = null;
3817                }
3818                lastTask = r.task;
3819                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3820                        null, "force-stop", true)) {
3821                    i--;
3822                }
3823            }
3824        }
3825
3826        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3827            if (!doit) {
3828                return true;
3829            }
3830            didSomething = true;
3831        }
3832
3833        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3834        for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
3835            if ((name == null || provider.info.packageName.equals(name))
3836                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3837                if (!doit) {
3838                    return true;
3839                }
3840                didSomething = true;
3841                providers.add(provider);
3842            }
3843        }
3844
3845        N = providers.size();
3846        for (i=0; i<N; i++) {
3847            removeDyingProviderLocked(null, providers.get(i), true);
3848        }
3849
3850        if (doit) {
3851            if (purgeCache && name != null) {
3852                AttributeCache ac = AttributeCache.instance();
3853                if (ac != null) {
3854                    ac.removePackage(name);
3855                }
3856            }
3857            if (mBooted) {
3858                mMainStack.resumeTopActivityLocked(null);
3859                mMainStack.scheduleIdleLocked();
3860            }
3861        }
3862
3863        return didSomething;
3864    }
3865
3866    private final boolean removeProcessLocked(ProcessRecord app,
3867            boolean callerWillRestart, boolean allowRestart, String reason) {
3868        final String name = app.processName;
3869        final int uid = app.uid;
3870        if (DEBUG_PROCESSES) Slog.d(
3871            TAG, "Force removing proc " + app.toShortString() + " (" + name
3872            + "/" + uid + ")");
3873
3874        mProcessNames.remove(name, uid);
3875        mIsolatedProcesses.remove(app.uid);
3876        if (mHeavyWeightProcess == app) {
3877            mHeavyWeightProcess = null;
3878            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3879        }
3880        boolean needRestart = false;
3881        if (app.pid > 0 && app.pid != MY_PID) {
3882            int pid = app.pid;
3883            synchronized (mPidsSelfLocked) {
3884                mPidsSelfLocked.remove(pid);
3885                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3886            }
3887            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3888            handleAppDiedLocked(app, true, allowRestart);
3889            mLruProcesses.remove(app);
3890            Process.killProcessQuiet(pid);
3891
3892            if (app.persistent && !app.isolated) {
3893                if (!callerWillRestart) {
3894                    addAppLocked(app.info, false);
3895                } else {
3896                    needRestart = true;
3897                }
3898            }
3899        } else {
3900            mRemovedProcesses.add(app);
3901        }
3902
3903        return needRestart;
3904    }
3905
3906    private final void processStartTimedOutLocked(ProcessRecord app) {
3907        final int pid = app.pid;
3908        boolean gone = false;
3909        synchronized (mPidsSelfLocked) {
3910            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3911            if (knownApp != null && knownApp.thread == null) {
3912                mPidsSelfLocked.remove(pid);
3913                gone = true;
3914            }
3915        }
3916
3917        if (gone) {
3918            Slog.w(TAG, "Process " + app + " failed to attach");
3919            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
3920                    app.processName);
3921            mProcessNames.remove(app.processName, app.uid);
3922            mIsolatedProcesses.remove(app.uid);
3923            if (mHeavyWeightProcess == app) {
3924                mHeavyWeightProcess = null;
3925                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3926            }
3927            // Take care of any launching providers waiting for this process.
3928            checkAppInLaunchingProvidersLocked(app, true);
3929            // Take care of any services that are waiting for the process.
3930            mServices.processStartTimedOutLocked(app);
3931            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3932                    app.processName, app.setAdj, "start timeout");
3933            Process.killProcessQuiet(pid);
3934            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3935                Slog.w(TAG, "Unattached app died before backup, skipping");
3936                try {
3937                    IBackupManager bm = IBackupManager.Stub.asInterface(
3938                            ServiceManager.getService(Context.BACKUP_SERVICE));
3939                    bm.agentDisconnected(app.info.packageName);
3940                } catch (RemoteException e) {
3941                    // Can't happen; the backup manager is local
3942                }
3943            }
3944            if (isPendingBroadcastProcessLocked(pid)) {
3945                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3946                skipPendingBroadcastLocked(pid);
3947            }
3948        } else {
3949            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3950        }
3951    }
3952
3953    private final boolean attachApplicationLocked(IApplicationThread thread,
3954            int pid) {
3955
3956        // Find the application record that is being attached...  either via
3957        // the pid if we are running in multiple processes, or just pull the
3958        // next app record if we are emulating process with anonymous threads.
3959        ProcessRecord app;
3960        if (pid != MY_PID && pid >= 0) {
3961            synchronized (mPidsSelfLocked) {
3962                app = mPidsSelfLocked.get(pid);
3963            }
3964        } else {
3965            app = null;
3966        }
3967
3968        if (app == null) {
3969            Slog.w(TAG, "No pending application record for pid " + pid
3970                    + " (IApplicationThread " + thread + "); dropping process");
3971            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3972            if (pid > 0 && pid != MY_PID) {
3973                Process.killProcessQuiet(pid);
3974            } else {
3975                try {
3976                    thread.scheduleExit();
3977                } catch (Exception e) {
3978                    // Ignore exceptions.
3979                }
3980            }
3981            return false;
3982        }
3983
3984        // If this application record is still attached to a previous
3985        // process, clean it up now.
3986        if (app.thread != null) {
3987            handleAppDiedLocked(app, true, true);
3988        }
3989
3990        // Tell the process all about itself.
3991
3992        if (localLOGV) Slog.v(
3993                TAG, "Binding process pid " + pid + " to record " + app);
3994
3995        String processName = app.processName;
3996        try {
3997            AppDeathRecipient adr = new AppDeathRecipient(
3998                    app, pid, thread);
3999            thread.asBinder().linkToDeath(adr, 0);
4000            app.deathRecipient = adr;
4001        } catch (RemoteException e) {
4002            app.resetPackageList();
4003            startProcessLocked(app, "link fail", processName);
4004            return false;
4005        }
4006
4007        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
4008
4009        app.thread = thread;
4010        app.curAdj = app.setAdj = -100;
4011        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4012        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4013        app.forcingToForeground = null;
4014        app.foregroundServices = false;
4015        app.hasShownUi = false;
4016        app.debugging = false;
4017
4018        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4019
4020        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4021        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4022
4023        if (!normalMode) {
4024            Slog.i(TAG, "Launching preboot mode app: " + app);
4025        }
4026
4027        if (localLOGV) Slog.v(
4028            TAG, "New app record " + app
4029            + " thread=" + thread.asBinder() + " pid=" + pid);
4030        try {
4031            int testMode = IApplicationThread.DEBUG_OFF;
4032            if (mDebugApp != null && mDebugApp.equals(processName)) {
4033                testMode = mWaitForDebugger
4034                    ? IApplicationThread.DEBUG_WAIT
4035                    : IApplicationThread.DEBUG_ON;
4036                app.debugging = true;
4037                if (mDebugTransient) {
4038                    mDebugApp = mOrigDebugApp;
4039                    mWaitForDebugger = mOrigWaitForDebugger;
4040                }
4041            }
4042            String profileFile = app.instrumentationProfileFile;
4043            ParcelFileDescriptor profileFd = null;
4044            boolean profileAutoStop = false;
4045            if (mProfileApp != null && mProfileApp.equals(processName)) {
4046                mProfileProc = app;
4047                profileFile = mProfileFile;
4048                profileFd = mProfileFd;
4049                profileAutoStop = mAutoStopProfiler;
4050            }
4051            boolean enableOpenGlTrace = false;
4052            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4053                enableOpenGlTrace = true;
4054                mOpenGlTraceApp = null;
4055            }
4056
4057            // If the app is being launched for restore or full backup, set it up specially
4058            boolean isRestrictedBackupMode = false;
4059            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4060                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4061                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4062                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4063            }
4064
4065            ensurePackageDexOpt(app.instrumentationInfo != null
4066                    ? app.instrumentationInfo.packageName
4067                    : app.info.packageName);
4068            if (app.instrumentationClass != null) {
4069                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4070            }
4071            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4072                    + processName + " with config " + mConfiguration);
4073            ApplicationInfo appInfo = app.instrumentationInfo != null
4074                    ? app.instrumentationInfo : app.info;
4075            app.compat = compatibilityInfoForPackageLocked(appInfo);
4076            if (profileFd != null) {
4077                profileFd = profileFd.dup();
4078            }
4079            thread.bindApplication(processName, appInfo, providers,
4080                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4081                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4082                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4083                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4084                    mCoreSettingsObserver.getCoreSettingsLocked());
4085            updateLruProcessLocked(app, false, true);
4086            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4087        } catch (Exception e) {
4088            // todo: Yikes!  What should we do?  For now we will try to
4089            // start another process, but that could easily get us in
4090            // an infinite loop of restarting processes...
4091            Slog.w(TAG, "Exception thrown during bind!", e);
4092
4093            app.resetPackageList();
4094            app.unlinkDeathRecipient();
4095            startProcessLocked(app, "bind fail", processName);
4096            return false;
4097        }
4098
4099        // Remove this record from the list of starting applications.
4100        mPersistentStartingProcesses.remove(app);
4101        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4102                "Attach application locked removing on hold: " + app);
4103        mProcessesOnHold.remove(app);
4104
4105        boolean badApp = false;
4106        boolean didSomething = false;
4107
4108        // See if the top visible activity is waiting to run in this process...
4109        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4110        if (hr != null && normalMode) {
4111            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4112                    && processName.equals(hr.processName)) {
4113                try {
4114                    if (mHeadless) {
4115                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4116                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4117                        didSomething = true;
4118                    }
4119                } catch (Exception e) {
4120                    Slog.w(TAG, "Exception in new application when starting activity "
4121                          + hr.intent.getComponent().flattenToShortString(), e);
4122                    badApp = true;
4123                }
4124            } else {
4125                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4126            }
4127        }
4128
4129        // Find any services that should be running in this process...
4130        if (!badApp) {
4131            try {
4132                didSomething |= mServices.attachApplicationLocked(app, processName);
4133            } catch (Exception e) {
4134                badApp = true;
4135            }
4136        }
4137
4138        // Check if a next-broadcast receiver is in this process...
4139        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4140            try {
4141                didSomething = sendPendingBroadcastsLocked(app);
4142            } catch (Exception e) {
4143                // If the app died trying to launch the receiver we declare it 'bad'
4144                badApp = true;
4145            }
4146        }
4147
4148        // Check whether the next backup agent is in this process...
4149        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4150            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4151            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4152            try {
4153                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4154                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4155                        mBackupTarget.backupMode);
4156            } catch (Exception e) {
4157                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4158                e.printStackTrace();
4159            }
4160        }
4161
4162        if (badApp) {
4163            // todo: Also need to kill application to deal with all
4164            // kinds of exceptions.
4165            handleAppDiedLocked(app, false, true);
4166            return false;
4167        }
4168
4169        if (!didSomething) {
4170            updateOomAdjLocked();
4171        }
4172
4173        return true;
4174    }
4175
4176    public final void attachApplication(IApplicationThread thread) {
4177        synchronized (this) {
4178            int callingPid = Binder.getCallingPid();
4179            final long origId = Binder.clearCallingIdentity();
4180            attachApplicationLocked(thread, callingPid);
4181            Binder.restoreCallingIdentity(origId);
4182        }
4183    }
4184
4185    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4186        final long origId = Binder.clearCallingIdentity();
4187        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4188        if (stopProfiling) {
4189            synchronized (this) {
4190                if (mProfileProc == r.app) {
4191                    if (mProfileFd != null) {
4192                        try {
4193                            mProfileFd.close();
4194                        } catch (IOException e) {
4195                        }
4196                        clearProfilerLocked();
4197                    }
4198                }
4199            }
4200        }
4201        Binder.restoreCallingIdentity(origId);
4202    }
4203
4204    void enableScreenAfterBoot() {
4205        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4206                SystemClock.uptimeMillis());
4207        mWindowManager.enableScreenAfterBoot();
4208
4209        synchronized (this) {
4210            updateEventDispatchingLocked();
4211        }
4212    }
4213
4214    public void showBootMessage(final CharSequence msg, final boolean always) {
4215        enforceNotIsolatedCaller("showBootMessage");
4216        mWindowManager.showBootMessage(msg, always);
4217    }
4218
4219    public void dismissKeyguardOnNextActivity() {
4220        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4221        final long token = Binder.clearCallingIdentity();
4222        try {
4223            synchronized (this) {
4224                if (mLockScreenShown) {
4225                    mLockScreenShown = false;
4226                    comeOutOfSleepIfNeededLocked();
4227                }
4228                mMainStack.dismissKeyguardOnNextActivityLocked();
4229            }
4230        } finally {
4231            Binder.restoreCallingIdentity(token);
4232        }
4233    }
4234
4235    final void finishBooting() {
4236        IntentFilter pkgFilter = new IntentFilter();
4237        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4238        pkgFilter.addDataScheme("package");
4239        mContext.registerReceiver(new BroadcastReceiver() {
4240            @Override
4241            public void onReceive(Context context, Intent intent) {
4242                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4243                if (pkgs != null) {
4244                    for (String pkg : pkgs) {
4245                        synchronized (ActivityManagerService.this) {
4246                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4247                                setResultCode(Activity.RESULT_OK);
4248                                return;
4249                            }
4250                        }
4251                    }
4252                }
4253            }
4254        }, pkgFilter);
4255
4256        synchronized (this) {
4257            // Ensure that any processes we had put on hold are now started
4258            // up.
4259            final int NP = mProcessesOnHold.size();
4260            if (NP > 0) {
4261                ArrayList<ProcessRecord> procs =
4262                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4263                for (int ip=0; ip<NP; ip++) {
4264                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4265                            + procs.get(ip));
4266                    startProcessLocked(procs.get(ip), "on-hold", null);
4267                }
4268            }
4269
4270            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4271                // Start looking for apps that are abusing wake locks.
4272                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4273                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4274                // Tell anyone interested that we are done booting!
4275                SystemProperties.set("sys.boot_completed", "1");
4276                SystemProperties.set("dev.bootcomplete", "1");
4277                for (int i=0; i<mStartedUsers.size(); i++) {
4278                    UserStartedState uss = mStartedUsers.valueAt(i);
4279                    if (uss.mState == UserStartedState.STATE_BOOTING) {
4280                        uss.mState = UserStartedState.STATE_RUNNING;
4281                        broadcastIntentLocked(null, null,
4282                                new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4283                                null, null, 0, null, null,
4284                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4285                                false, false, MY_PID, Process.SYSTEM_UID,
4286                                mStartedUsers.keyAt(i));
4287                    }
4288                }
4289            }
4290        }
4291    }
4292
4293    final void ensureBootCompleted() {
4294        boolean booting;
4295        boolean enableScreen;
4296        synchronized (this) {
4297            booting = mBooting;
4298            mBooting = false;
4299            enableScreen = !mBooted;
4300            mBooted = true;
4301        }
4302
4303        if (booting) {
4304            finishBooting();
4305        }
4306
4307        if (enableScreen) {
4308            enableScreenAfterBoot();
4309        }
4310    }
4311
4312    public final void activityPaused(IBinder token) {
4313        final long origId = Binder.clearCallingIdentity();
4314        mMainStack.activityPaused(token, false);
4315        Binder.restoreCallingIdentity(origId);
4316    }
4317
4318    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4319            CharSequence description) {
4320        if (localLOGV) Slog.v(
4321            TAG, "Activity stopped: token=" + token);
4322
4323        // Refuse possible leaked file descriptors
4324        if (icicle != null && icicle.hasFileDescriptors()) {
4325            throw new IllegalArgumentException("File descriptors passed in Bundle");
4326        }
4327
4328        ActivityRecord r = null;
4329
4330        final long origId = Binder.clearCallingIdentity();
4331
4332        synchronized (this) {
4333            r = mMainStack.isInStackLocked(token);
4334            if (r != null) {
4335                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4336            }
4337        }
4338
4339        if (r != null) {
4340            sendPendingThumbnail(r, null, null, null, false);
4341        }
4342
4343        trimApplications();
4344
4345        Binder.restoreCallingIdentity(origId);
4346    }
4347
4348    public final void activityDestroyed(IBinder token) {
4349        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4350        mMainStack.activityDestroyed(token);
4351    }
4352
4353    public String getCallingPackage(IBinder token) {
4354        synchronized (this) {
4355            ActivityRecord r = getCallingRecordLocked(token);
4356            return r != null && r.app != null ? r.info.packageName : null;
4357        }
4358    }
4359
4360    public ComponentName getCallingActivity(IBinder token) {
4361        synchronized (this) {
4362            ActivityRecord r = getCallingRecordLocked(token);
4363            return r != null ? r.intent.getComponent() : null;
4364        }
4365    }
4366
4367    private ActivityRecord getCallingRecordLocked(IBinder token) {
4368        ActivityRecord r = mMainStack.isInStackLocked(token);
4369        if (r == null) {
4370            return null;
4371        }
4372        return r.resultTo;
4373    }
4374
4375    public ComponentName getActivityClassForToken(IBinder token) {
4376        synchronized(this) {
4377            ActivityRecord r = mMainStack.isInStackLocked(token);
4378            if (r == null) {
4379                return null;
4380            }
4381            return r.intent.getComponent();
4382        }
4383    }
4384
4385    public String getPackageForToken(IBinder token) {
4386        synchronized(this) {
4387            ActivityRecord r = mMainStack.isInStackLocked(token);
4388            if (r == null) {
4389                return null;
4390            }
4391            return r.packageName;
4392        }
4393    }
4394
4395    public IIntentSender getIntentSender(int type,
4396            String packageName, IBinder token, String resultWho,
4397            int requestCode, Intent[] intents, String[] resolvedTypes,
4398            int flags, Bundle options) {
4399        enforceNotIsolatedCaller("getIntentSender");
4400        // Refuse possible leaked file descriptors
4401        if (intents != null) {
4402            if (intents.length < 1) {
4403                throw new IllegalArgumentException("Intents array length must be >= 1");
4404            }
4405            for (int i=0; i<intents.length; i++) {
4406                Intent intent = intents[i];
4407                if (intent != null) {
4408                    if (intent.hasFileDescriptors()) {
4409                        throw new IllegalArgumentException("File descriptors passed in Intent");
4410                    }
4411                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4412                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4413                        throw new IllegalArgumentException(
4414                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4415                    }
4416                    intents[i] = new Intent(intent);
4417                }
4418            }
4419            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4420                throw new IllegalArgumentException(
4421                        "Intent array length does not match resolvedTypes length");
4422            }
4423        }
4424        if (options != null) {
4425            if (options.hasFileDescriptors()) {
4426                throw new IllegalArgumentException("File descriptors passed in options");
4427            }
4428        }
4429
4430        synchronized(this) {
4431            int callingUid = Binder.getCallingUid();
4432            try {
4433                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4434                    int uid = AppGlobals.getPackageManager()
4435                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4436                    if (!UserHandle.isSameApp(callingUid, uid)) {
4437                        String msg = "Permission Denial: getIntentSender() from pid="
4438                            + Binder.getCallingPid()
4439                            + ", uid=" + Binder.getCallingUid()
4440                            + ", (need uid=" + uid + ")"
4441                            + " is not allowed to send as package " + packageName;
4442                        Slog.w(TAG, msg);
4443                        throw new SecurityException(msg);
4444                    }
4445                }
4446
4447                if (DEBUG_MU)
4448                    Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
4449                            + Binder.getOrigCallingUid());
4450                return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
4451                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4452
4453            } catch (RemoteException e) {
4454                throw new SecurityException(e);
4455            }
4456        }
4457    }
4458
4459    IIntentSender getIntentSenderLocked(int type,
4460            String packageName, int callingUid, IBinder token, String resultWho,
4461            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4462            Bundle options) {
4463        if (DEBUG_MU)
4464            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4465        ActivityRecord activity = null;
4466        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4467            activity = mMainStack.isInStackLocked(token);
4468            if (activity == null) {
4469                return null;
4470            }
4471            if (activity.finishing) {
4472                return null;
4473            }
4474        }
4475
4476        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4477        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4478        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4479        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4480                |PendingIntent.FLAG_UPDATE_CURRENT);
4481
4482        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4483                type, packageName, activity, resultWho,
4484                requestCode, intents, resolvedTypes, flags, options);
4485        WeakReference<PendingIntentRecord> ref;
4486        ref = mIntentSenderRecords.get(key);
4487        PendingIntentRecord rec = ref != null ? ref.get() : null;
4488        if (rec != null) {
4489            if (!cancelCurrent) {
4490                if (updateCurrent) {
4491                    if (rec.key.requestIntent != null) {
4492                        rec.key.requestIntent.replaceExtras(intents != null ?
4493                                intents[intents.length - 1] : null);
4494                    }
4495                    if (intents != null) {
4496                        intents[intents.length-1] = rec.key.requestIntent;
4497                        rec.key.allIntents = intents;
4498                        rec.key.allResolvedTypes = resolvedTypes;
4499                    } else {
4500                        rec.key.allIntents = null;
4501                        rec.key.allResolvedTypes = null;
4502                    }
4503                }
4504                return rec;
4505            }
4506            rec.canceled = true;
4507            mIntentSenderRecords.remove(key);
4508        }
4509        if (noCreate) {
4510            return rec;
4511        }
4512        rec = new PendingIntentRecord(this, key, callingUid);
4513        mIntentSenderRecords.put(key, rec.ref);
4514        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4515            if (activity.pendingResults == null) {
4516                activity.pendingResults
4517                        = new HashSet<WeakReference<PendingIntentRecord>>();
4518            }
4519            activity.pendingResults.add(rec.ref);
4520        }
4521        return rec;
4522    }
4523
4524    public void cancelIntentSender(IIntentSender sender) {
4525        if (!(sender instanceof PendingIntentRecord)) {
4526            return;
4527        }
4528        synchronized(this) {
4529            PendingIntentRecord rec = (PendingIntentRecord)sender;
4530            try {
4531                int uid = AppGlobals.getPackageManager()
4532                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4533                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4534                    String msg = "Permission Denial: cancelIntentSender() from pid="
4535                        + Binder.getCallingPid()
4536                        + ", uid=" + Binder.getCallingUid()
4537                        + " is not allowed to cancel packges "
4538                        + rec.key.packageName;
4539                    Slog.w(TAG, msg);
4540                    throw new SecurityException(msg);
4541                }
4542            } catch (RemoteException e) {
4543                throw new SecurityException(e);
4544            }
4545            cancelIntentSenderLocked(rec, true);
4546        }
4547    }
4548
4549    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4550        rec.canceled = true;
4551        mIntentSenderRecords.remove(rec.key);
4552        if (cleanActivity && rec.key.activity != null) {
4553            rec.key.activity.pendingResults.remove(rec.ref);
4554        }
4555    }
4556
4557    public String getPackageForIntentSender(IIntentSender pendingResult) {
4558        if (!(pendingResult instanceof PendingIntentRecord)) {
4559            return null;
4560        }
4561        try {
4562            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4563            return res.key.packageName;
4564        } catch (ClassCastException e) {
4565        }
4566        return null;
4567    }
4568
4569    public int getUidForIntentSender(IIntentSender sender) {
4570        if (sender instanceof PendingIntentRecord) {
4571            try {
4572                PendingIntentRecord res = (PendingIntentRecord)sender;
4573                return res.uid;
4574            } catch (ClassCastException e) {
4575            }
4576        }
4577        return -1;
4578    }
4579
4580    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4581        if (!(pendingResult instanceof PendingIntentRecord)) {
4582            return false;
4583        }
4584        try {
4585            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4586            if (res.key.allIntents == null) {
4587                return false;
4588            }
4589            for (int i=0; i<res.key.allIntents.length; i++) {
4590                Intent intent = res.key.allIntents[i];
4591                if (intent.getPackage() != null && intent.getComponent() != null) {
4592                    return false;
4593                }
4594            }
4595            return true;
4596        } catch (ClassCastException e) {
4597        }
4598        return false;
4599    }
4600
4601    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4602        if (!(pendingResult instanceof PendingIntentRecord)) {
4603            return false;
4604        }
4605        try {
4606            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4607            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4608                return true;
4609            }
4610            return false;
4611        } catch (ClassCastException e) {
4612        }
4613        return false;
4614    }
4615
4616    public void setProcessLimit(int max) {
4617        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4618                "setProcessLimit()");
4619        synchronized (this) {
4620            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4621            mProcessLimitOverride = max;
4622        }
4623        trimApplications();
4624    }
4625
4626    public int getProcessLimit() {
4627        synchronized (this) {
4628            return mProcessLimitOverride;
4629        }
4630    }
4631
4632    void foregroundTokenDied(ForegroundToken token) {
4633        synchronized (ActivityManagerService.this) {
4634            synchronized (mPidsSelfLocked) {
4635                ForegroundToken cur
4636                    = mForegroundProcesses.get(token.pid);
4637                if (cur != token) {
4638                    return;
4639                }
4640                mForegroundProcesses.remove(token.pid);
4641                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4642                if (pr == null) {
4643                    return;
4644                }
4645                pr.forcingToForeground = null;
4646                pr.foregroundServices = false;
4647            }
4648            updateOomAdjLocked();
4649        }
4650    }
4651
4652    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4653        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4654                "setProcessForeground()");
4655        synchronized(this) {
4656            boolean changed = false;
4657
4658            synchronized (mPidsSelfLocked) {
4659                ProcessRecord pr = mPidsSelfLocked.get(pid);
4660                if (pr == null && isForeground) {
4661                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4662                    return;
4663                }
4664                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4665                if (oldToken != null) {
4666                    oldToken.token.unlinkToDeath(oldToken, 0);
4667                    mForegroundProcesses.remove(pid);
4668                    if (pr != null) {
4669                        pr.forcingToForeground = null;
4670                    }
4671                    changed = true;
4672                }
4673                if (isForeground && token != null) {
4674                    ForegroundToken newToken = new ForegroundToken() {
4675                        public void binderDied() {
4676                            foregroundTokenDied(this);
4677                        }
4678                    };
4679                    newToken.pid = pid;
4680                    newToken.token = token;
4681                    try {
4682                        token.linkToDeath(newToken, 0);
4683                        mForegroundProcesses.put(pid, newToken);
4684                        pr.forcingToForeground = token;
4685                        changed = true;
4686                    } catch (RemoteException e) {
4687                        // If the process died while doing this, we will later
4688                        // do the cleanup with the process death link.
4689                    }
4690                }
4691            }
4692
4693            if (changed) {
4694                updateOomAdjLocked();
4695            }
4696        }
4697    }
4698
4699    // =========================================================
4700    // PERMISSIONS
4701    // =========================================================
4702
4703    static class PermissionController extends IPermissionController.Stub {
4704        ActivityManagerService mActivityManagerService;
4705        PermissionController(ActivityManagerService activityManagerService) {
4706            mActivityManagerService = activityManagerService;
4707        }
4708
4709        public boolean checkPermission(String permission, int pid, int uid) {
4710            return mActivityManagerService.checkPermission(permission, pid,
4711                    uid) == PackageManager.PERMISSION_GRANTED;
4712        }
4713    }
4714
4715    /**
4716     * This can be called with or without the global lock held.
4717     */
4718    int checkComponentPermission(String permission, int pid, int uid,
4719            int owningUid, boolean exported) {
4720        // We might be performing an operation on behalf of an indirect binder
4721        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4722        // client identity accordingly before proceeding.
4723        Identity tlsIdentity = sCallerIdentity.get();
4724        if (tlsIdentity != null) {
4725            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4726                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4727            uid = tlsIdentity.uid;
4728            pid = tlsIdentity.pid;
4729        }
4730
4731        if (pid == MY_PID) {
4732            return PackageManager.PERMISSION_GRANTED;
4733        }
4734
4735        return ActivityManager.checkComponentPermission(permission, uid,
4736                owningUid, exported);
4737    }
4738
4739    /**
4740     * As the only public entry point for permissions checking, this method
4741     * can enforce the semantic that requesting a check on a null global
4742     * permission is automatically denied.  (Internally a null permission
4743     * string is used when calling {@link #checkComponentPermission} in cases
4744     * when only uid-based security is needed.)
4745     *
4746     * This can be called with or without the global lock held.
4747     */
4748    public int checkPermission(String permission, int pid, int uid) {
4749        if (permission == null) {
4750            return PackageManager.PERMISSION_DENIED;
4751        }
4752        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4753    }
4754
4755    /**
4756     * Binder IPC calls go through the public entry point.
4757     * This can be called with or without the global lock held.
4758     */
4759    int checkCallingPermission(String permission) {
4760        return checkPermission(permission,
4761                Binder.getCallingPid(),
4762                UserHandle.getAppId(Binder.getCallingUid()));
4763    }
4764
4765    /**
4766     * This can be called with or without the global lock held.
4767     */
4768    void enforceCallingPermission(String permission, String func) {
4769        if (checkCallingPermission(permission)
4770                == PackageManager.PERMISSION_GRANTED) {
4771            return;
4772        }
4773
4774        String msg = "Permission Denial: " + func + " from pid="
4775                + Binder.getCallingPid()
4776                + ", uid=" + Binder.getCallingUid()
4777                + " requires " + permission;
4778        Slog.w(TAG, msg);
4779        throw new SecurityException(msg);
4780    }
4781
4782    /**
4783     * Determine if UID is holding permissions required to access {@link Uri} in
4784     * the given {@link ProviderInfo}. Final permission checking is always done
4785     * in {@link ContentProvider}.
4786     */
4787    private final boolean checkHoldingPermissionsLocked(
4788            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4789        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4790                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4791
4792        if (pi.applicationInfo.uid == uid) {
4793            return true;
4794        } else if (!pi.exported) {
4795            return false;
4796        }
4797
4798        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4799        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4800        try {
4801            // check if target holds top-level <provider> permissions
4802            if (!readMet && pi.readPermission != null
4803                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4804                readMet = true;
4805            }
4806            if (!writeMet && pi.writePermission != null
4807                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4808                writeMet = true;
4809            }
4810
4811            // track if unprotected read/write is allowed; any denied
4812            // <path-permission> below removes this ability
4813            boolean allowDefaultRead = pi.readPermission == null;
4814            boolean allowDefaultWrite = pi.writePermission == null;
4815
4816            // check if target holds any <path-permission> that match uri
4817            final PathPermission[] pps = pi.pathPermissions;
4818            if (pps != null) {
4819                final String path = uri.getPath();
4820                int i = pps.length;
4821                while (i > 0 && (!readMet || !writeMet)) {
4822                    i--;
4823                    PathPermission pp = pps[i];
4824                    if (pp.match(path)) {
4825                        if (!readMet) {
4826                            final String pprperm = pp.getReadPermission();
4827                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4828                                    + pprperm + " for " + pp.getPath()
4829                                    + ": match=" + pp.match(path)
4830                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4831                            if (pprperm != null) {
4832                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4833                                    readMet = true;
4834                                } else {
4835                                    allowDefaultRead = false;
4836                                }
4837                            }
4838                        }
4839                        if (!writeMet) {
4840                            final String ppwperm = pp.getWritePermission();
4841                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4842                                    + ppwperm + " for " + pp.getPath()
4843                                    + ": match=" + pp.match(path)
4844                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4845                            if (ppwperm != null) {
4846                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4847                                    writeMet = true;
4848                                } else {
4849                                    allowDefaultWrite = false;
4850                                }
4851                            }
4852                        }
4853                    }
4854                }
4855            }
4856
4857            // grant unprotected <provider> read/write, if not blocked by
4858            // <path-permission> above
4859            if (allowDefaultRead) readMet = true;
4860            if (allowDefaultWrite) writeMet = true;
4861
4862        } catch (RemoteException e) {
4863            return false;
4864        }
4865
4866        return readMet && writeMet;
4867    }
4868
4869    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4870            int modeFlags) {
4871        // Root gets to do everything.
4872        if (uid == 0) {
4873            return true;
4874        }
4875        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4876        if (perms == null) return false;
4877        UriPermission perm = perms.get(uri);
4878        if (perm == null) return false;
4879        return (modeFlags&perm.modeFlags) == modeFlags;
4880    }
4881
4882    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4883        enforceNotIsolatedCaller("checkUriPermission");
4884
4885        // Another redirected-binder-call permissions check as in
4886        // {@link checkComponentPermission}.
4887        Identity tlsIdentity = sCallerIdentity.get();
4888        if (tlsIdentity != null) {
4889            uid = tlsIdentity.uid;
4890            pid = tlsIdentity.pid;
4891        }
4892
4893        uid = UserHandle.getAppId(uid);
4894        // Our own process gets to do everything.
4895        if (pid == MY_PID) {
4896            return PackageManager.PERMISSION_GRANTED;
4897        }
4898        synchronized(this) {
4899            return checkUriPermissionLocked(uri, uid, modeFlags)
4900                    ? PackageManager.PERMISSION_GRANTED
4901                    : PackageManager.PERMISSION_DENIED;
4902        }
4903    }
4904
4905    /**
4906     * Check if the targetPkg can be granted permission to access uri by
4907     * the callingUid using the given modeFlags.  Throws a security exception
4908     * if callingUid is not allowed to do this.  Returns the uid of the target
4909     * if the URI permission grant should be performed; returns -1 if it is not
4910     * needed (for example targetPkg already has permission to access the URI).
4911     * If you already know the uid of the target, you can supply it in
4912     * lastTargetUid else set that to -1.
4913     */
4914    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4915            Uri uri, int modeFlags, int lastTargetUid) {
4916        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4917                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4918        if (modeFlags == 0) {
4919            return -1;
4920        }
4921
4922        if (targetPkg != null) {
4923            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4924                    "Checking grant " + targetPkg + " permission to " + uri);
4925        }
4926
4927        final IPackageManager pm = AppGlobals.getPackageManager();
4928
4929        // If this is not a content: uri, we can't do anything with it.
4930        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4931            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4932                    "Can't grant URI permission for non-content URI: " + uri);
4933            return -1;
4934        }
4935
4936        String name = uri.getAuthority();
4937        ProviderInfo pi = null;
4938        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4939                UserHandle.getUserId(callingUid));
4940        if (cpr != null) {
4941            pi = cpr.info;
4942        } else {
4943            try {
4944                pi = pm.resolveContentProvider(name,
4945                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid));
4946            } catch (RemoteException ex) {
4947            }
4948        }
4949        if (pi == null) {
4950            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4951            return -1;
4952        }
4953
4954        int targetUid = lastTargetUid;
4955        if (targetUid < 0 && targetPkg != null) {
4956            try {
4957                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
4958                if (targetUid < 0) {
4959                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4960                            "Can't grant URI permission no uid for: " + targetPkg);
4961                    return -1;
4962                }
4963            } catch (RemoteException ex) {
4964                return -1;
4965            }
4966        }
4967
4968        if (targetUid >= 0) {
4969            // First...  does the target actually need this permission?
4970            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4971                // No need to grant the target this permission.
4972                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4973                        "Target " + targetPkg + " already has full permission to " + uri);
4974                return -1;
4975            }
4976        } else {
4977            // First...  there is no target package, so can anyone access it?
4978            boolean allowed = pi.exported;
4979            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4980                if (pi.readPermission != null) {
4981                    allowed = false;
4982                }
4983            }
4984            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4985                if (pi.writePermission != null) {
4986                    allowed = false;
4987                }
4988            }
4989            if (allowed) {
4990                return -1;
4991            }
4992        }
4993
4994        // Second...  is the provider allowing granting of URI permissions?
4995        if (!pi.grantUriPermissions) {
4996            throw new SecurityException("Provider " + pi.packageName
4997                    + "/" + pi.name
4998                    + " does not allow granting of Uri permissions (uri "
4999                    + uri + ")");
5000        }
5001        if (pi.uriPermissionPatterns != null) {
5002            final int N = pi.uriPermissionPatterns.length;
5003            boolean allowed = false;
5004            for (int i=0; i<N; i++) {
5005                if (pi.uriPermissionPatterns[i] != null
5006                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5007                    allowed = true;
5008                    break;
5009                }
5010            }
5011            if (!allowed) {
5012                throw new SecurityException("Provider " + pi.packageName
5013                        + "/" + pi.name
5014                        + " does not allow granting of permission to path of Uri "
5015                        + uri);
5016            }
5017        }
5018
5019        // Third...  does the caller itself have permission to access
5020        // this uri?
5021        if (callingUid != Process.myUid()) {
5022            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5023                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5024                    throw new SecurityException("Uid " + callingUid
5025                            + " does not have permission to uri " + uri);
5026                }
5027            }
5028        }
5029
5030        return targetUid;
5031    }
5032
5033    public int checkGrantUriPermission(int callingUid, String targetPkg,
5034            Uri uri, int modeFlags) {
5035        enforceNotIsolatedCaller("checkGrantUriPermission");
5036        synchronized(this) {
5037            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5038        }
5039    }
5040
5041    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5042            Uri uri, int modeFlags, UriPermissionOwner owner) {
5043        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5044                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5045        if (modeFlags == 0) {
5046            return;
5047        }
5048
5049        // So here we are: the caller has the assumed permission
5050        // to the uri, and the target doesn't.  Let's now give this to
5051        // the target.
5052
5053        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5054                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5055
5056        HashMap<Uri, UriPermission> targetUris
5057                = mGrantedUriPermissions.get(targetUid);
5058        if (targetUris == null) {
5059            targetUris = new HashMap<Uri, UriPermission>();
5060            mGrantedUriPermissions.put(targetUid, targetUris);
5061        }
5062
5063        UriPermission perm = targetUris.get(uri);
5064        if (perm == null) {
5065            perm = new UriPermission(targetUid, uri);
5066            targetUris.put(uri, perm);
5067        }
5068
5069        perm.modeFlags |= modeFlags;
5070        if (owner == null) {
5071            perm.globalModeFlags |= modeFlags;
5072        } else {
5073            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5074                 perm.readOwners.add(owner);
5075                 owner.addReadPermission(perm);
5076            }
5077            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5078                 perm.writeOwners.add(owner);
5079                 owner.addWritePermission(perm);
5080            }
5081        }
5082    }
5083
5084    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5085            int modeFlags, UriPermissionOwner owner) {
5086        if (targetPkg == null) {
5087            throw new NullPointerException("targetPkg");
5088        }
5089
5090        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5091        if (targetUid < 0) {
5092            return;
5093        }
5094
5095        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5096    }
5097
5098    static class NeededUriGrants extends ArrayList<Uri> {
5099        final String targetPkg;
5100        final int targetUid;
5101        final int flags;
5102
5103        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5104            targetPkg = _targetPkg;
5105            targetUid = _targetUid;
5106            flags = _flags;
5107        }
5108    }
5109
5110    /**
5111     * Like checkGrantUriPermissionLocked, but takes an Intent.
5112     */
5113    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5114            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5115        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5116                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5117                + " clip=" + (intent != null ? intent.getClipData() : null)
5118                + " from " + intent + "; flags=0x"
5119                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5120
5121        if (targetPkg == null) {
5122            throw new NullPointerException("targetPkg");
5123        }
5124
5125        if (intent == null) {
5126            return null;
5127        }
5128        Uri data = intent.getData();
5129        ClipData clip = intent.getClipData();
5130        if (data == null && clip == null) {
5131            return null;
5132        }
5133        if (data != null) {
5134            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5135                mode, needed != null ? needed.targetUid : -1);
5136            if (target > 0) {
5137                if (needed == null) {
5138                    needed = new NeededUriGrants(targetPkg, target, mode);
5139                }
5140                needed.add(data);
5141            }
5142        }
5143        if (clip != null) {
5144            for (int i=0; i<clip.getItemCount(); i++) {
5145                Uri uri = clip.getItemAt(i).getUri();
5146                if (uri != null) {
5147                    int target = -1;
5148                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5149                            mode, needed != null ? needed.targetUid : -1);
5150                    if (target > 0) {
5151                        if (needed == null) {
5152                            needed = new NeededUriGrants(targetPkg, target, mode);
5153                        }
5154                        needed.add(uri);
5155                    }
5156                } else {
5157                    Intent clipIntent = clip.getItemAt(i).getIntent();
5158                    if (clipIntent != null) {
5159                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5160                                callingUid, targetPkg, clipIntent, mode, needed);
5161                        if (newNeeded != null) {
5162                            needed = newNeeded;
5163                        }
5164                    }
5165                }
5166            }
5167        }
5168
5169        return needed;
5170    }
5171
5172    /**
5173     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5174     */
5175    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5176            UriPermissionOwner owner) {
5177        if (needed != null) {
5178            for (int i=0; i<needed.size(); i++) {
5179                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5180                        needed.get(i), needed.flags, owner);
5181            }
5182        }
5183    }
5184
5185    void grantUriPermissionFromIntentLocked(int callingUid,
5186            String targetPkg, Intent intent, UriPermissionOwner owner) {
5187        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5188                intent, intent != null ? intent.getFlags() : 0, null);
5189        if (needed == null) {
5190            return;
5191        }
5192
5193        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5194    }
5195
5196    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5197            Uri uri, int modeFlags) {
5198        enforceNotIsolatedCaller("grantUriPermission");
5199        synchronized(this) {
5200            final ProcessRecord r = getRecordForAppLocked(caller);
5201            if (r == null) {
5202                throw new SecurityException("Unable to find app for caller "
5203                        + caller
5204                        + " when granting permission to uri " + uri);
5205            }
5206            if (targetPkg == null) {
5207                throw new IllegalArgumentException("null target");
5208            }
5209            if (uri == null) {
5210                throw new IllegalArgumentException("null uri");
5211            }
5212
5213            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5214                    null);
5215        }
5216    }
5217
5218    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5219        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5220                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5221            HashMap<Uri, UriPermission> perms
5222                    = mGrantedUriPermissions.get(perm.uid);
5223            if (perms != null) {
5224                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5225                        "Removing " + perm.uid + " permission to " + perm.uri);
5226                perms.remove(perm.uri);
5227                if (perms.size() == 0) {
5228                    mGrantedUriPermissions.remove(perm.uid);
5229                }
5230            }
5231        }
5232    }
5233
5234    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5235            int modeFlags) {
5236        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5237                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5238        if (modeFlags == 0) {
5239            return;
5240        }
5241
5242        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5243                "Revoking all granted permissions to " + uri);
5244
5245        final IPackageManager pm = AppGlobals.getPackageManager();
5246
5247        final String authority = uri.getAuthority();
5248        ProviderInfo pi = null;
5249        int userId = UserHandle.getUserId(callingUid);
5250        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5251        if (cpr != null) {
5252            pi = cpr.info;
5253        } else {
5254            try {
5255                pi = pm.resolveContentProvider(authority,
5256                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5257            } catch (RemoteException ex) {
5258            }
5259        }
5260        if (pi == null) {
5261            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5262            return;
5263        }
5264
5265        // Does the caller have this permission on the URI?
5266        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5267            // Right now, if you are not the original owner of the permission,
5268            // you are not allowed to revoke it.
5269            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5270                throw new SecurityException("Uid " + callingUid
5271                        + " does not have permission to uri " + uri);
5272            //}
5273        }
5274
5275        // Go through all of the permissions and remove any that match.
5276        final List<String> SEGMENTS = uri.getPathSegments();
5277        if (SEGMENTS != null) {
5278            final int NS = SEGMENTS.size();
5279            int N = mGrantedUriPermissions.size();
5280            for (int i=0; i<N; i++) {
5281                HashMap<Uri, UriPermission> perms
5282                        = mGrantedUriPermissions.valueAt(i);
5283                Iterator<UriPermission> it = perms.values().iterator();
5284            toploop:
5285                while (it.hasNext()) {
5286                    UriPermission perm = it.next();
5287                    Uri targetUri = perm.uri;
5288                    if (!authority.equals(targetUri.getAuthority())) {
5289                        continue;
5290                    }
5291                    List<String> targetSegments = targetUri.getPathSegments();
5292                    if (targetSegments == null) {
5293                        continue;
5294                    }
5295                    if (targetSegments.size() < NS) {
5296                        continue;
5297                    }
5298                    for (int j=0; j<NS; j++) {
5299                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5300                            continue toploop;
5301                        }
5302                    }
5303                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5304                            "Revoking " + perm.uid + " permission to " + perm.uri);
5305                    perm.clearModes(modeFlags);
5306                    if (perm.modeFlags == 0) {
5307                        it.remove();
5308                    }
5309                }
5310                if (perms.size() == 0) {
5311                    mGrantedUriPermissions.remove(
5312                            mGrantedUriPermissions.keyAt(i));
5313                    N--;
5314                    i--;
5315                }
5316            }
5317        }
5318    }
5319
5320    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5321            int modeFlags) {
5322        enforceNotIsolatedCaller("revokeUriPermission");
5323        synchronized(this) {
5324            final ProcessRecord r = getRecordForAppLocked(caller);
5325            if (r == null) {
5326                throw new SecurityException("Unable to find app for caller "
5327                        + caller
5328                        + " when revoking permission to uri " + uri);
5329            }
5330            if (uri == null) {
5331                Slog.w(TAG, "revokeUriPermission: null uri");
5332                return;
5333            }
5334
5335            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5336                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5337            if (modeFlags == 0) {
5338                return;
5339            }
5340
5341            final IPackageManager pm = AppGlobals.getPackageManager();
5342
5343            final String authority = uri.getAuthority();
5344            ProviderInfo pi = null;
5345            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5346            if (cpr != null) {
5347                pi = cpr.info;
5348            } else {
5349                try {
5350                    pi = pm.resolveContentProvider(authority,
5351                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5352                } catch (RemoteException ex) {
5353                }
5354            }
5355            if (pi == null) {
5356                Slog.w(TAG, "No content provider found for permission revoke: "
5357                        + uri.toSafeString());
5358                return;
5359            }
5360
5361            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5362        }
5363    }
5364
5365    @Override
5366    public IBinder newUriPermissionOwner(String name) {
5367        enforceNotIsolatedCaller("newUriPermissionOwner");
5368        synchronized(this) {
5369            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5370            return owner.getExternalTokenLocked();
5371        }
5372    }
5373
5374    @Override
5375    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5376            Uri uri, int modeFlags) {
5377        synchronized(this) {
5378            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5379            if (owner == null) {
5380                throw new IllegalArgumentException("Unknown owner: " + token);
5381            }
5382            if (fromUid != Binder.getCallingUid()) {
5383                if (Binder.getCallingUid() != Process.myUid()) {
5384                    // Only system code can grant URI permissions on behalf
5385                    // of other users.
5386                    throw new SecurityException("nice try");
5387                }
5388            }
5389            if (targetPkg == null) {
5390                throw new IllegalArgumentException("null target");
5391            }
5392            if (uri == null) {
5393                throw new IllegalArgumentException("null uri");
5394            }
5395
5396            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5397        }
5398    }
5399
5400    @Override
5401    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5402        synchronized(this) {
5403            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5404            if (owner == null) {
5405                throw new IllegalArgumentException("Unknown owner: " + token);
5406            }
5407
5408            if (uri == null) {
5409                owner.removeUriPermissionsLocked(mode);
5410            } else {
5411                owner.removeUriPermissionLocked(uri, mode);
5412            }
5413        }
5414    }
5415
5416    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5417        synchronized (this) {
5418            ProcessRecord app =
5419                who != null ? getRecordForAppLocked(who) : null;
5420            if (app == null) return;
5421
5422            Message msg = Message.obtain();
5423            msg.what = WAIT_FOR_DEBUGGER_MSG;
5424            msg.obj = app;
5425            msg.arg1 = waiting ? 1 : 0;
5426            mHandler.sendMessage(msg);
5427        }
5428    }
5429
5430    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5431        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5432        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5433        outInfo.availMem = Process.getFreeMemory();
5434        outInfo.totalMem = Process.getTotalMemory();
5435        outInfo.threshold = homeAppMem;
5436        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5437        outInfo.hiddenAppThreshold = hiddenAppMem;
5438        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5439                ProcessList.SERVICE_ADJ);
5440        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5441                ProcessList.VISIBLE_APP_ADJ);
5442        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5443                ProcessList.FOREGROUND_APP_ADJ);
5444    }
5445
5446    // =========================================================
5447    // TASK MANAGEMENT
5448    // =========================================================
5449
5450    public List getTasks(int maxNum, int flags,
5451                         IThumbnailReceiver receiver) {
5452        ArrayList list = new ArrayList();
5453
5454        PendingThumbnailsRecord pending = null;
5455        IApplicationThread topThumbnail = null;
5456        ActivityRecord topRecord = null;
5457
5458        synchronized(this) {
5459            if (localLOGV) Slog.v(
5460                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5461                + ", receiver=" + receiver);
5462
5463            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5464                    != PackageManager.PERMISSION_GRANTED) {
5465                if (receiver != null) {
5466                    // If the caller wants to wait for pending thumbnails,
5467                    // it ain't gonna get them.
5468                    try {
5469                        receiver.finished();
5470                    } catch (RemoteException ex) {
5471                    }
5472                }
5473                String msg = "Permission Denial: getTasks() from pid="
5474                        + Binder.getCallingPid()
5475                        + ", uid=" + Binder.getCallingUid()
5476                        + " requires " + android.Manifest.permission.GET_TASKS;
5477                Slog.w(TAG, msg);
5478                throw new SecurityException(msg);
5479            }
5480
5481            int pos = mMainStack.mHistory.size()-1;
5482            ActivityRecord next =
5483                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5484            ActivityRecord top = null;
5485            TaskRecord curTask = null;
5486            int numActivities = 0;
5487            int numRunning = 0;
5488            while (pos >= 0 && maxNum > 0) {
5489                final ActivityRecord r = next;
5490                pos--;
5491                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5492
5493                // Initialize state for next task if needed.
5494                if (top == null ||
5495                        (top.state == ActivityState.INITIALIZING
5496                            && top.task == r.task)) {
5497                    top = r;
5498                    curTask = r.task;
5499                    numActivities = numRunning = 0;
5500                }
5501
5502                // Add 'r' into the current task.
5503                numActivities++;
5504                if (r.app != null && r.app.thread != null) {
5505                    numRunning++;
5506                }
5507
5508                if (localLOGV) Slog.v(
5509                    TAG, r.intent.getComponent().flattenToShortString()
5510                    + ": task=" + r.task);
5511
5512                // If the next one is a different task, generate a new
5513                // TaskInfo entry for what we have.
5514                if (next == null || next.task != curTask) {
5515                    ActivityManager.RunningTaskInfo ci
5516                            = new ActivityManager.RunningTaskInfo();
5517                    ci.id = curTask.taskId;
5518                    ci.baseActivity = r.intent.getComponent();
5519                    ci.topActivity = top.intent.getComponent();
5520                    if (top.thumbHolder != null) {
5521                        ci.description = top.thumbHolder.lastDescription;
5522                    }
5523                    ci.numActivities = numActivities;
5524                    ci.numRunning = numRunning;
5525                    //System.out.println(
5526                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5527                    if (ci.thumbnail == null && receiver != null) {
5528                        if (localLOGV) Slog.v(
5529                            TAG, "State=" + top.state + "Idle=" + top.idle
5530                            + " app=" + top.app
5531                            + " thr=" + (top.app != null ? top.app.thread : null));
5532                        if (top.state == ActivityState.RESUMED
5533                                || top.state == ActivityState.PAUSING) {
5534                            if (top.idle && top.app != null
5535                                && top.app.thread != null) {
5536                                topRecord = top;
5537                                topThumbnail = top.app.thread;
5538                            } else {
5539                                top.thumbnailNeeded = true;
5540                            }
5541                        }
5542                        if (pending == null) {
5543                            pending = new PendingThumbnailsRecord(receiver);
5544                        }
5545                        pending.pendingRecords.add(top);
5546                    }
5547                    list.add(ci);
5548                    maxNum--;
5549                    top = null;
5550                }
5551            }
5552
5553            if (pending != null) {
5554                mPendingThumbnails.add(pending);
5555            }
5556        }
5557
5558        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5559
5560        if (topThumbnail != null) {
5561            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5562            try {
5563                topThumbnail.requestThumbnail(topRecord.appToken);
5564            } catch (Exception e) {
5565                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5566                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5567            }
5568        }
5569
5570        if (pending == null && receiver != null) {
5571            // In this case all thumbnails were available and the client
5572            // is being asked to be told when the remaining ones come in...
5573            // which is unusually, since the top-most currently running
5574            // activity should never have a canned thumbnail!  Oh well.
5575            try {
5576                receiver.finished();
5577            } catch (RemoteException ex) {
5578            }
5579        }
5580
5581        return list;
5582    }
5583
5584    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5585            int flags, int userId) {
5586        final int callingUid = Binder.getCallingUid();
5587        if (userId != UserHandle.getCallingUserId()) {
5588            // Check if the caller is holding permissions for cross-user requests.
5589            if (checkComponentPermission(
5590                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5591                    Binder.getCallingPid(), callingUid, -1, true)
5592                    != PackageManager.PERMISSION_GRANTED) {
5593                String msg = "Permission Denial: "
5594                        + "Request to get recent tasks for user " + userId
5595                        + " but is calling from user " + UserHandle.getUserId(callingUid)
5596                        + "; this requires "
5597                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5598                Slog.w(TAG, msg);
5599                throw new SecurityException(msg);
5600            } else {
5601                if (userId == UserHandle.USER_CURRENT) {
5602                    userId = mCurrentUserId;
5603                }
5604            }
5605        }
5606
5607        synchronized (this) {
5608            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5609                    "getRecentTasks()");
5610            final boolean detailed = checkCallingPermission(
5611                    android.Manifest.permission.GET_DETAILED_TASKS)
5612                    == PackageManager.PERMISSION_GRANTED;
5613
5614            IPackageManager pm = AppGlobals.getPackageManager();
5615
5616            final int N = mRecentTasks.size();
5617            ArrayList<ActivityManager.RecentTaskInfo> res
5618                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5619                            maxNum < N ? maxNum : N);
5620            for (int i=0; i<N && maxNum > 0; i++) {
5621                TaskRecord tr = mRecentTasks.get(i);
5622                // Only add calling user's recent tasks
5623                if (tr.userId != userId) continue;
5624                // Return the entry if desired by the caller.  We always return
5625                // the first entry, because callers always expect this to be the
5626                // foreground app.  We may filter others if the caller has
5627                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5628                // we should exclude the entry.
5629
5630                if (i == 0
5631                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5632                        || (tr.intent == null)
5633                        || ((tr.intent.getFlags()
5634                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5635                    ActivityManager.RecentTaskInfo rti
5636                            = new ActivityManager.RecentTaskInfo();
5637                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5638                    rti.persistentId = tr.taskId;
5639                    rti.baseIntent = new Intent(
5640                            tr.intent != null ? tr.intent : tr.affinityIntent);
5641                    if (!detailed) {
5642                        rti.baseIntent.replaceExtras((Bundle)null);
5643                    }
5644                    rti.origActivity = tr.origActivity;
5645                    rti.description = tr.lastDescription;
5646
5647                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5648                        // Check whether this activity is currently available.
5649                        try {
5650                            if (rti.origActivity != null) {
5651                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5652                                        == null) {
5653                                    continue;
5654                                }
5655                            } else if (rti.baseIntent != null) {
5656                                if (pm.queryIntentActivities(rti.baseIntent,
5657                                        null, 0, userId) == null) {
5658                                    continue;
5659                                }
5660                            }
5661                        } catch (RemoteException e) {
5662                            // Will never happen.
5663                        }
5664                    }
5665
5666                    res.add(rti);
5667                    maxNum--;
5668                }
5669            }
5670            return res;
5671        }
5672    }
5673
5674    private TaskRecord taskForIdLocked(int id) {
5675        final int N = mRecentTasks.size();
5676        for (int i=0; i<N; i++) {
5677            TaskRecord tr = mRecentTasks.get(i);
5678            if (tr.taskId == id) {
5679                return tr;
5680            }
5681        }
5682        return null;
5683    }
5684
5685    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5686        synchronized (this) {
5687            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5688                    "getTaskThumbnails()");
5689            TaskRecord tr = taskForIdLocked(id);
5690            if (tr != null) {
5691                return mMainStack.getTaskThumbnailsLocked(tr);
5692            }
5693        }
5694        return null;
5695    }
5696
5697    public boolean removeSubTask(int taskId, int subTaskIndex) {
5698        synchronized (this) {
5699            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5700                    "removeSubTask()");
5701            long ident = Binder.clearCallingIdentity();
5702            try {
5703                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5704                        true) != null;
5705            } finally {
5706                Binder.restoreCallingIdentity(ident);
5707            }
5708        }
5709    }
5710
5711    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5712        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5713        Intent baseIntent = new Intent(
5714                tr.intent != null ? tr.intent : tr.affinityIntent);
5715        ComponentName component = baseIntent.getComponent();
5716        if (component == null) {
5717            Slog.w(TAG, "Now component for base intent of task: " + tr);
5718            return;
5719        }
5720
5721        // Find any running services associated with this app.
5722        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5723
5724        if (killProcesses) {
5725            // Find any running processes associated with this app.
5726            final String pkg = component.getPackageName();
5727            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5728            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5729            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5730                for (int i=0; i<uids.size(); i++) {
5731                    ProcessRecord proc = uids.valueAt(i);
5732                    if (proc.userId != tr.userId) {
5733                        continue;
5734                    }
5735                    if (!proc.pkgList.contains(pkg)) {
5736                        continue;
5737                    }
5738                    procs.add(proc);
5739                }
5740            }
5741
5742            // Kill the running processes.
5743            for (int i=0; i<procs.size(); i++) {
5744                ProcessRecord pr = procs.get(i);
5745                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5746                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5747                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5748                            pr.processName, pr.setAdj, "remove task");
5749                    pr.killedBackground = true;
5750                    Process.killProcessQuiet(pr.pid);
5751                } else {
5752                    pr.waitingToKill = "remove task";
5753                }
5754            }
5755        }
5756    }
5757
5758    public boolean removeTask(int taskId, int flags) {
5759        synchronized (this) {
5760            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5761                    "removeTask()");
5762            long ident = Binder.clearCallingIdentity();
5763            try {
5764                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5765                        false);
5766                if (r != null) {
5767                    mRecentTasks.remove(r.task);
5768                    cleanUpRemovedTaskLocked(r.task, flags);
5769                    return true;
5770                } else {
5771                    TaskRecord tr = null;
5772                    int i=0;
5773                    while (i < mRecentTasks.size()) {
5774                        TaskRecord t = mRecentTasks.get(i);
5775                        if (t.taskId == taskId) {
5776                            tr = t;
5777                            break;
5778                        }
5779                        i++;
5780                    }
5781                    if (tr != null) {
5782                        if (tr.numActivities <= 0) {
5783                            // Caller is just removing a recent task that is
5784                            // not actively running.  That is easy!
5785                            mRecentTasks.remove(i);
5786                            cleanUpRemovedTaskLocked(tr, flags);
5787                            return true;
5788                        } else {
5789                            Slog.w(TAG, "removeTask: task " + taskId
5790                                    + " does not have activities to remove, "
5791                                    + " but numActivities=" + tr.numActivities
5792                                    + ": " + tr);
5793                        }
5794                    }
5795                }
5796            } finally {
5797                Binder.restoreCallingIdentity(ident);
5798            }
5799        }
5800        return false;
5801    }
5802
5803    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5804        int j;
5805        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5806        TaskRecord jt = startTask;
5807
5808        // First look backwards
5809        for (j=startIndex-1; j>=0; j--) {
5810            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5811            if (r.task != jt) {
5812                jt = r.task;
5813                if (affinity.equals(jt.affinity)) {
5814                    return j;
5815                }
5816            }
5817        }
5818
5819        // Now look forwards
5820        final int N = mMainStack.mHistory.size();
5821        jt = startTask;
5822        for (j=startIndex+1; j<N; j++) {
5823            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5824            if (r.task != jt) {
5825                if (affinity.equals(jt.affinity)) {
5826                    return j;
5827                }
5828                jt = r.task;
5829            }
5830        }
5831
5832        // Might it be at the top?
5833        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5834            return N-1;
5835        }
5836
5837        return -1;
5838    }
5839
5840    /**
5841     * TODO: Add mController hook
5842     */
5843    public void moveTaskToFront(int task, int flags, Bundle options) {
5844        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5845                "moveTaskToFront()");
5846
5847        synchronized(this) {
5848            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5849                    Binder.getCallingUid(), "Task to front")) {
5850                ActivityOptions.abort(options);
5851                return;
5852            }
5853            final long origId = Binder.clearCallingIdentity();
5854            try {
5855                TaskRecord tr = taskForIdLocked(task);
5856                if (tr != null) {
5857                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5858                        mMainStack.mUserLeaving = true;
5859                    }
5860                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5861                        // Caller wants the home activity moved with it.  To accomplish this,
5862                        // we'll just move the home task to the top first.
5863                        mMainStack.moveHomeToFrontLocked();
5864                    }
5865                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5866                    return;
5867                }
5868                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5869                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5870                    if (hr.task.taskId == task) {
5871                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5872                            mMainStack.mUserLeaving = true;
5873                        }
5874                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5875                            // Caller wants the home activity moved with it.  To accomplish this,
5876                            // we'll just move the home task to the top first.
5877                            mMainStack.moveHomeToFrontLocked();
5878                        }
5879                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5880                        return;
5881                    }
5882                }
5883            } finally {
5884                Binder.restoreCallingIdentity(origId);
5885            }
5886            ActivityOptions.abort(options);
5887        }
5888    }
5889
5890    public void moveTaskToBack(int task) {
5891        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5892                "moveTaskToBack()");
5893
5894        synchronized(this) {
5895            if (mMainStack.mResumedActivity != null
5896                    && mMainStack.mResumedActivity.task.taskId == task) {
5897                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5898                        Binder.getCallingUid(), "Task to back")) {
5899                    return;
5900                }
5901            }
5902            final long origId = Binder.clearCallingIdentity();
5903            mMainStack.moveTaskToBackLocked(task, null);
5904            Binder.restoreCallingIdentity(origId);
5905        }
5906    }
5907
5908    /**
5909     * Moves an activity, and all of the other activities within the same task, to the bottom
5910     * of the history stack.  The activity's order within the task is unchanged.
5911     *
5912     * @param token A reference to the activity we wish to move
5913     * @param nonRoot If false then this only works if the activity is the root
5914     *                of a task; if true it will work for any activity in a task.
5915     * @return Returns true if the move completed, false if not.
5916     */
5917    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5918        enforceNotIsolatedCaller("moveActivityTaskToBack");
5919        synchronized(this) {
5920            final long origId = Binder.clearCallingIdentity();
5921            int taskId = getTaskForActivityLocked(token, !nonRoot);
5922            if (taskId >= 0) {
5923                return mMainStack.moveTaskToBackLocked(taskId, null);
5924            }
5925            Binder.restoreCallingIdentity(origId);
5926        }
5927        return false;
5928    }
5929
5930    public void moveTaskBackwards(int task) {
5931        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5932                "moveTaskBackwards()");
5933
5934        synchronized(this) {
5935            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5936                    Binder.getCallingUid(), "Task backwards")) {
5937                return;
5938            }
5939            final long origId = Binder.clearCallingIdentity();
5940            moveTaskBackwardsLocked(task);
5941            Binder.restoreCallingIdentity(origId);
5942        }
5943    }
5944
5945    private final void moveTaskBackwardsLocked(int task) {
5946        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5947    }
5948
5949    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5950        synchronized(this) {
5951            return getTaskForActivityLocked(token, onlyRoot);
5952        }
5953    }
5954
5955    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5956        final int N = mMainStack.mHistory.size();
5957        TaskRecord lastTask = null;
5958        for (int i=0; i<N; i++) {
5959            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5960            if (r.appToken == token) {
5961                if (!onlyRoot || lastTask != r.task) {
5962                    return r.task.taskId;
5963                }
5964                return -1;
5965            }
5966            lastTask = r.task;
5967        }
5968
5969        return -1;
5970    }
5971
5972    // =========================================================
5973    // THUMBNAILS
5974    // =========================================================
5975
5976    public void reportThumbnail(IBinder token,
5977            Bitmap thumbnail, CharSequence description) {
5978        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5979        final long origId = Binder.clearCallingIdentity();
5980        sendPendingThumbnail(null, token, thumbnail, description, true);
5981        Binder.restoreCallingIdentity(origId);
5982    }
5983
5984    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5985            Bitmap thumbnail, CharSequence description, boolean always) {
5986        TaskRecord task = null;
5987        ArrayList receivers = null;
5988
5989        //System.out.println("Send pending thumbnail: " + r);
5990
5991        synchronized(this) {
5992            if (r == null) {
5993                r = mMainStack.isInStackLocked(token);
5994                if (r == null) {
5995                    return;
5996                }
5997            }
5998            if (thumbnail == null && r.thumbHolder != null) {
5999                thumbnail = r.thumbHolder.lastThumbnail;
6000                description = r.thumbHolder.lastDescription;
6001            }
6002            if (thumbnail == null && !always) {
6003                // If there is no thumbnail, and this entry is not actually
6004                // going away, then abort for now and pick up the next
6005                // thumbnail we get.
6006                return;
6007            }
6008            task = r.task;
6009
6010            int N = mPendingThumbnails.size();
6011            int i=0;
6012            while (i<N) {
6013                PendingThumbnailsRecord pr =
6014                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6015                //System.out.println("Looking in " + pr.pendingRecords);
6016                if (pr.pendingRecords.remove(r)) {
6017                    if (receivers == null) {
6018                        receivers = new ArrayList();
6019                    }
6020                    receivers.add(pr);
6021                    if (pr.pendingRecords.size() == 0) {
6022                        pr.finished = true;
6023                        mPendingThumbnails.remove(i);
6024                        N--;
6025                        continue;
6026                    }
6027                }
6028                i++;
6029            }
6030        }
6031
6032        if (receivers != null) {
6033            final int N = receivers.size();
6034            for (int i=0; i<N; i++) {
6035                try {
6036                    PendingThumbnailsRecord pr =
6037                        (PendingThumbnailsRecord)receivers.get(i);
6038                    pr.receiver.newThumbnail(
6039                        task != null ? task.taskId : -1, thumbnail, description);
6040                    if (pr.finished) {
6041                        pr.receiver.finished();
6042                    }
6043                } catch (Exception e) {
6044                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6045                }
6046            }
6047        }
6048    }
6049
6050    // =========================================================
6051    // CONTENT PROVIDERS
6052    // =========================================================
6053
6054    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6055        List<ProviderInfo> providers = null;
6056        try {
6057            providers = AppGlobals.getPackageManager().
6058                queryContentProviders(app.processName, app.uid,
6059                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6060        } catch (RemoteException ex) {
6061        }
6062        if (DEBUG_MU)
6063            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6064        int userId = app.userId;
6065        if (providers != null) {
6066            int N = providers.size();
6067            for (int i=0; i<N; i++) {
6068                ProviderInfo cpi =
6069                    (ProviderInfo)providers.get(i);
6070                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6071                        cpi.name, cpi.flags);
6072                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6073                    // This is a singleton provider, but a user besides the
6074                    // default user is asking to initialize a process it runs
6075                    // in...  well, no, it doesn't actually run in this process,
6076                    // it runs in the process of the default user.  Get rid of it.
6077                    providers.remove(i);
6078                    N--;
6079                    continue;
6080                }
6081
6082                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6083                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6084                if (cpr == null) {
6085                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6086                    mProviderMap.putProviderByClass(comp, cpr);
6087                }
6088                if (DEBUG_MU)
6089                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6090                app.pubProviders.put(cpi.name, cpr);
6091                app.addPackage(cpi.applicationInfo.packageName);
6092                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6093            }
6094        }
6095        return providers;
6096    }
6097
6098    /**
6099     * Check if {@link ProcessRecord} has a possible chance at accessing the
6100     * given {@link ProviderInfo}. Final permission checking is always done
6101     * in {@link ContentProvider}.
6102     */
6103    private final String checkContentProviderPermissionLocked(
6104            ProviderInfo cpi, ProcessRecord r) {
6105        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6106        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6107        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6108                cpi.applicationInfo.uid, cpi.exported)
6109                == PackageManager.PERMISSION_GRANTED) {
6110            return null;
6111        }
6112        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6113                cpi.applicationInfo.uid, cpi.exported)
6114                == PackageManager.PERMISSION_GRANTED) {
6115            return null;
6116        }
6117
6118        PathPermission[] pps = cpi.pathPermissions;
6119        if (pps != null) {
6120            int i = pps.length;
6121            while (i > 0) {
6122                i--;
6123                PathPermission pp = pps[i];
6124                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6125                        cpi.applicationInfo.uid, cpi.exported)
6126                        == PackageManager.PERMISSION_GRANTED) {
6127                    return null;
6128                }
6129                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6130                        cpi.applicationInfo.uid, cpi.exported)
6131                        == PackageManager.PERMISSION_GRANTED) {
6132                    return null;
6133                }
6134            }
6135        }
6136
6137        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6138        if (perms != null) {
6139            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6140                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6141                    return null;
6142                }
6143            }
6144        }
6145
6146        String msg;
6147        if (!cpi.exported) {
6148            msg = "Permission Denial: opening provider " + cpi.name
6149                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6150                    + ", uid=" + callingUid + ") that is not exported from uid "
6151                    + cpi.applicationInfo.uid;
6152        } else {
6153            msg = "Permission Denial: opening provider " + cpi.name
6154                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6155                    + ", uid=" + callingUid + ") requires "
6156                    + cpi.readPermission + " or " + cpi.writePermission;
6157        }
6158        Slog.w(TAG, msg);
6159        return msg;
6160    }
6161
6162    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6163            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6164        if (r != null) {
6165            for (int i=0; i<r.conProviders.size(); i++) {
6166                ContentProviderConnection conn = r.conProviders.get(i);
6167                if (conn.provider == cpr) {
6168                    if (DEBUG_PROVIDER) Slog.v(TAG,
6169                            "Adding provider requested by "
6170                            + r.processName + " from process "
6171                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6172                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6173                    if (stable) {
6174                        conn.stableCount++;
6175                        conn.numStableIncs++;
6176                    } else {
6177                        conn.unstableCount++;
6178                        conn.numUnstableIncs++;
6179                    }
6180                    return conn;
6181                }
6182            }
6183            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6184            if (stable) {
6185                conn.stableCount = 1;
6186                conn.numStableIncs = 1;
6187            } else {
6188                conn.unstableCount = 1;
6189                conn.numUnstableIncs = 1;
6190            }
6191            cpr.connections.add(conn);
6192            r.conProviders.add(conn);
6193            return conn;
6194        }
6195        cpr.addExternalProcessHandleLocked(externalProcessToken);
6196        return null;
6197    }
6198
6199    boolean decProviderCountLocked(ContentProviderConnection conn,
6200            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6201        if (conn != null) {
6202            cpr = conn.provider;
6203            if (DEBUG_PROVIDER) Slog.v(TAG,
6204                    "Removing provider requested by "
6205                    + conn.client.processName + " from process "
6206                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6207                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6208            if (stable) {
6209                conn.stableCount--;
6210            } else {
6211                conn.unstableCount--;
6212            }
6213            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6214                cpr.connections.remove(conn);
6215                conn.client.conProviders.remove(conn);
6216                return true;
6217            }
6218            return false;
6219        }
6220        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6221        return false;
6222    }
6223
6224    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6225            String name, IBinder token, boolean stable) {
6226        ContentProviderRecord cpr;
6227        ContentProviderConnection conn = null;
6228        ProviderInfo cpi = null;
6229
6230        synchronized(this) {
6231            ProcessRecord r = null;
6232            if (caller != null) {
6233                r = getRecordForAppLocked(caller);
6234                if (r == null) {
6235                    throw new SecurityException(
6236                            "Unable to find app for caller " + caller
6237                          + " (pid=" + Binder.getCallingPid()
6238                          + ") when getting content provider " + name);
6239                }
6240            }
6241
6242            // First check if this content provider has been published...
6243            int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid());
6244            cpr = mProviderMap.getProviderByName(name, userId);
6245            boolean providerRunning = cpr != null;
6246            if (providerRunning) {
6247                cpi = cpr.info;
6248                String msg;
6249                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6250                    throw new SecurityException(msg);
6251                }
6252
6253                if (r != null && cpr.canRunHere(r)) {
6254                    // This provider has been published or is in the process
6255                    // of being published...  but it is also allowed to run
6256                    // in the caller's process, so don't make a connection
6257                    // and just let the caller instantiate its own instance.
6258                    ContentProviderHolder holder = cpr.newHolder(null);
6259                    // don't give caller the provider object, it needs
6260                    // to make its own.
6261                    holder.provider = null;
6262                    return holder;
6263                }
6264
6265                final long origId = Binder.clearCallingIdentity();
6266
6267                // In this case the provider instance already exists, so we can
6268                // return it right away.
6269                conn = incProviderCountLocked(r, cpr, token, stable);
6270                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6271                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6272                        // If this is a perceptible app accessing the provider,
6273                        // make sure to count it as being accessed and thus
6274                        // back up on the LRU list.  This is good because
6275                        // content providers are often expensive to start.
6276                        updateLruProcessLocked(cpr.proc, false, true);
6277                    }
6278                }
6279
6280                if (cpr.proc != null) {
6281                    if (false) {
6282                        if (cpr.name.flattenToShortString().equals(
6283                                "com.android.providers.calendar/.CalendarProvider2")) {
6284                            Slog.v(TAG, "****************** KILLING "
6285                                + cpr.name.flattenToShortString());
6286                            Process.killProcess(cpr.proc.pid);
6287                        }
6288                    }
6289                    boolean success = updateOomAdjLocked(cpr.proc);
6290                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6291                    // NOTE: there is still a race here where a signal could be
6292                    // pending on the process even though we managed to update its
6293                    // adj level.  Not sure what to do about this, but at least
6294                    // the race is now smaller.
6295                    if (!success) {
6296                        // Uh oh...  it looks like the provider's process
6297                        // has been killed on us.  We need to wait for a new
6298                        // process to be started, and make sure its death
6299                        // doesn't kill our process.
6300                        Slog.i(TAG,
6301                                "Existing provider " + cpr.name.flattenToShortString()
6302                                + " is crashing; detaching " + r);
6303                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6304                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6305                        if (!lastRef) {
6306                            // This wasn't the last ref our process had on
6307                            // the provider...  we have now been killed, bail.
6308                            return null;
6309                        }
6310                        providerRunning = false;
6311                        conn = null;
6312                    }
6313                }
6314
6315                Binder.restoreCallingIdentity(origId);
6316            }
6317
6318            boolean singleton;
6319            if (!providerRunning) {
6320                try {
6321                    cpi = AppGlobals.getPackageManager().
6322                        resolveContentProvider(name,
6323                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6324                } catch (RemoteException ex) {
6325                }
6326                if (cpi == null) {
6327                    return null;
6328                }
6329                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6330                        cpi.name, cpi.flags);
6331                if (singleton) {
6332                    userId = 0;
6333                }
6334                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6335
6336                String msg;
6337                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6338                    throw new SecurityException(msg);
6339                }
6340
6341                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6342                        && !cpi.processName.equals("system")) {
6343                    // If this content provider does not run in the system
6344                    // process, and the system is not yet ready to run other
6345                    // processes, then fail fast instead of hanging.
6346                    throw new IllegalArgumentException(
6347                            "Attempt to launch content provider before system ready");
6348                }
6349
6350                // Make sure that the user who owns this provider is started.  If not,
6351                // we don't want to allow it to run.
6352                if (mStartedUsers.get(userId) == null) {
6353                    Slog.w(TAG, "Unable to launch app "
6354                            + cpi.applicationInfo.packageName + "/"
6355                            + cpi.applicationInfo.uid + " for provider "
6356                            + name + ": user " + userId + " is stopped");
6357                    return null;
6358                }
6359
6360                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6361                cpr = mProviderMap.getProviderByClass(comp, userId);
6362                final boolean firstClass = cpr == null;
6363                if (firstClass) {
6364                    try {
6365                        ApplicationInfo ai =
6366                            AppGlobals.getPackageManager().
6367                                getApplicationInfo(
6368                                        cpi.applicationInfo.packageName,
6369                                        STOCK_PM_FLAGS, userId);
6370                        if (ai == null) {
6371                            Slog.w(TAG, "No package info for content provider "
6372                                    + cpi.name);
6373                            return null;
6374                        }
6375                        ai = getAppInfoForUser(ai, userId);
6376                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6377                    } catch (RemoteException ex) {
6378                        // pm is in same process, this will never happen.
6379                    }
6380                }
6381
6382                if (r != null && cpr.canRunHere(r)) {
6383                    // If this is a multiprocess provider, then just return its
6384                    // info and allow the caller to instantiate it.  Only do
6385                    // this if the provider is the same user as the caller's
6386                    // process, or can run as root (so can be in any process).
6387                    return cpr.newHolder(null);
6388                }
6389
6390                if (DEBUG_PROVIDER) {
6391                    RuntimeException e = new RuntimeException("here");
6392                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6393                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6394                }
6395
6396                // This is single process, and our app is now connecting to it.
6397                // See if we are already in the process of launching this
6398                // provider.
6399                final int N = mLaunchingProviders.size();
6400                int i;
6401                for (i=0; i<N; i++) {
6402                    if (mLaunchingProviders.get(i) == cpr) {
6403                        break;
6404                    }
6405                }
6406
6407                // If the provider is not already being launched, then get it
6408                // started.
6409                if (i >= N) {
6410                    final long origId = Binder.clearCallingIdentity();
6411
6412                    try {
6413                        // Content provider is now in use, its package can't be stopped.
6414                        try {
6415                            AppGlobals.getPackageManager().setPackageStoppedState(
6416                                    cpr.appInfo.packageName, false, userId);
6417                        } catch (RemoteException e) {
6418                        } catch (IllegalArgumentException e) {
6419                            Slog.w(TAG, "Failed trying to unstop package "
6420                                    + cpr.appInfo.packageName + ": " + e);
6421                        }
6422
6423                        ProcessRecord proc = startProcessLocked(cpi.processName,
6424                                cpr.appInfo, false, 0, "content provider",
6425                                new ComponentName(cpi.applicationInfo.packageName,
6426                                        cpi.name), false, false);
6427                        if (proc == null) {
6428                            Slog.w(TAG, "Unable to launch app "
6429                                    + cpi.applicationInfo.packageName + "/"
6430                                    + cpi.applicationInfo.uid + " for provider "
6431                                    + name + ": process is bad");
6432                            return null;
6433                        }
6434                        cpr.launchingApp = proc;
6435                        mLaunchingProviders.add(cpr);
6436                    } finally {
6437                        Binder.restoreCallingIdentity(origId);
6438                    }
6439                }
6440
6441                // Make sure the provider is published (the same provider class
6442                // may be published under multiple names).
6443                if (firstClass) {
6444                    mProviderMap.putProviderByClass(comp, cpr);
6445                }
6446
6447                mProviderMap.putProviderByName(name, cpr);
6448                conn = incProviderCountLocked(r, cpr, token, stable);
6449                if (conn != null) {
6450                    conn.waiting = true;
6451                }
6452            }
6453        }
6454
6455        // Wait for the provider to be published...
6456        synchronized (cpr) {
6457            while (cpr.provider == null) {
6458                if (cpr.launchingApp == null) {
6459                    Slog.w(TAG, "Unable to launch app "
6460                            + cpi.applicationInfo.packageName + "/"
6461                            + cpi.applicationInfo.uid + " for provider "
6462                            + name + ": launching app became null");
6463                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6464                            cpi.applicationInfo.packageName,
6465                            cpi.applicationInfo.uid, name);
6466                    return null;
6467                }
6468                try {
6469                    if (DEBUG_MU) {
6470                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6471                                + cpr.launchingApp);
6472                    }
6473                    if (conn != null) {
6474                        conn.waiting = true;
6475                    }
6476                    cpr.wait();
6477                } catch (InterruptedException ex) {
6478                } finally {
6479                    if (conn != null) {
6480                        conn.waiting = false;
6481                    }
6482                }
6483            }
6484        }
6485        return cpr != null ? cpr.newHolder(conn) : null;
6486    }
6487
6488    public final ContentProviderHolder getContentProvider(
6489            IApplicationThread caller, String name, boolean stable) {
6490        enforceNotIsolatedCaller("getContentProvider");
6491        if (caller == null) {
6492            String msg = "null IApplicationThread when getting content provider "
6493                    + name;
6494            Slog.w(TAG, msg);
6495            throw new SecurityException(msg);
6496        }
6497
6498        return getContentProviderImpl(caller, name, null, stable);
6499    }
6500
6501    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6502        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6503            "Do not have permission in call getContentProviderExternal()");
6504        return getContentProviderExternalUnchecked(name, token);
6505    }
6506
6507    private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
6508        return getContentProviderImpl(null, name, token, true);
6509    }
6510
6511    /**
6512     * Drop a content provider from a ProcessRecord's bookkeeping
6513     * @param cpr
6514     */
6515    public void removeContentProvider(IBinder connection, boolean stable) {
6516        enforceNotIsolatedCaller("removeContentProvider");
6517        synchronized (this) {
6518            ContentProviderConnection conn;
6519            try {
6520                conn = (ContentProviderConnection)connection;
6521            } catch (ClassCastException e) {
6522                String msg ="removeContentProvider: " + connection
6523                        + " not a ContentProviderConnection";
6524                Slog.w(TAG, msg);
6525                throw new IllegalArgumentException(msg);
6526            }
6527            if (conn == null) {
6528                throw new NullPointerException("connection is null");
6529            }
6530            if (decProviderCountLocked(conn, null, null, stable)) {
6531                updateOomAdjLocked();
6532            }
6533        }
6534    }
6535
6536    public void removeContentProviderExternal(String name, IBinder token) {
6537        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6538            "Do not have permission in call removeContentProviderExternal()");
6539        removeContentProviderExternalUnchecked(name, token);
6540    }
6541
6542    private void removeContentProviderExternalUnchecked(String name, IBinder token) {
6543        synchronized (this) {
6544            ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6545                    Binder.getOrigCallingUser());
6546            if(cpr == null) {
6547                //remove from mProvidersByClass
6548                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6549                return;
6550            }
6551
6552            //update content provider record entry info
6553            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6554            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6555                    Binder.getOrigCallingUser());
6556            if (localCpr.hasExternalProcessHandles()) {
6557                if (localCpr.removeExternalProcessHandleLocked(token)) {
6558                    updateOomAdjLocked();
6559                } else {
6560                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6561                            + " with no external reference for token: "
6562                            + token + ".");
6563                }
6564            } else {
6565                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6566                        + " with no external references.");
6567            }
6568        }
6569    }
6570
6571    public final void publishContentProviders(IApplicationThread caller,
6572            List<ContentProviderHolder> providers) {
6573        if (providers == null) {
6574            return;
6575        }
6576
6577        enforceNotIsolatedCaller("publishContentProviders");
6578        synchronized (this) {
6579            final ProcessRecord r = getRecordForAppLocked(caller);
6580            if (DEBUG_MU)
6581                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6582            if (r == null) {
6583                throw new SecurityException(
6584                        "Unable to find app for caller " + caller
6585                      + " (pid=" + Binder.getCallingPid()
6586                      + ") when publishing content providers");
6587            }
6588
6589            final long origId = Binder.clearCallingIdentity();
6590
6591            final int N = providers.size();
6592            for (int i=0; i<N; i++) {
6593                ContentProviderHolder src = providers.get(i);
6594                if (src == null || src.info == null || src.provider == null) {
6595                    continue;
6596                }
6597                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6598                if (DEBUG_MU)
6599                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6600                if (dst != null) {
6601                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6602                    mProviderMap.putProviderByClass(comp, dst);
6603                    String names[] = dst.info.authority.split(";");
6604                    for (int j = 0; j < names.length; j++) {
6605                        mProviderMap.putProviderByName(names[j], dst);
6606                    }
6607
6608                    int NL = mLaunchingProviders.size();
6609                    int j;
6610                    for (j=0; j<NL; j++) {
6611                        if (mLaunchingProviders.get(j) == dst) {
6612                            mLaunchingProviders.remove(j);
6613                            j--;
6614                            NL--;
6615                        }
6616                    }
6617                    synchronized (dst) {
6618                        dst.provider = src.provider;
6619                        dst.proc = r;
6620                        dst.notifyAll();
6621                    }
6622                    updateOomAdjLocked(r);
6623                }
6624            }
6625
6626            Binder.restoreCallingIdentity(origId);
6627        }
6628    }
6629
6630    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6631        ContentProviderConnection conn;
6632        try {
6633            conn = (ContentProviderConnection)connection;
6634        } catch (ClassCastException e) {
6635            String msg ="refContentProvider: " + connection
6636                    + " not a ContentProviderConnection";
6637            Slog.w(TAG, msg);
6638            throw new IllegalArgumentException(msg);
6639        }
6640        if (conn == null) {
6641            throw new NullPointerException("connection is null");
6642        }
6643
6644        synchronized (this) {
6645            if (stable > 0) {
6646                conn.numStableIncs += stable;
6647            }
6648            stable = conn.stableCount + stable;
6649            if (stable < 0) {
6650                throw new IllegalStateException("stableCount < 0: " + stable);
6651            }
6652
6653            if (unstable > 0) {
6654                conn.numUnstableIncs += unstable;
6655            }
6656            unstable = conn.unstableCount + unstable;
6657            if (unstable < 0) {
6658                throw new IllegalStateException("unstableCount < 0: " + unstable);
6659            }
6660
6661            if ((stable+unstable) <= 0) {
6662                throw new IllegalStateException("ref counts can't go to zero here: stable="
6663                        + stable + " unstable=" + unstable);
6664            }
6665            conn.stableCount = stable;
6666            conn.unstableCount = unstable;
6667            return !conn.dead;
6668        }
6669    }
6670
6671    public void unstableProviderDied(IBinder connection) {
6672        ContentProviderConnection conn;
6673        try {
6674            conn = (ContentProviderConnection)connection;
6675        } catch (ClassCastException e) {
6676            String msg ="refContentProvider: " + connection
6677                    + " not a ContentProviderConnection";
6678            Slog.w(TAG, msg);
6679            throw new IllegalArgumentException(msg);
6680        }
6681        if (conn == null) {
6682            throw new NullPointerException("connection is null");
6683        }
6684
6685        // Safely retrieve the content provider associated with the connection.
6686        IContentProvider provider;
6687        synchronized (this) {
6688            provider = conn.provider.provider;
6689        }
6690
6691        if (provider == null) {
6692            // Um, yeah, we're way ahead of you.
6693            return;
6694        }
6695
6696        // Make sure the caller is being honest with us.
6697        if (provider.asBinder().pingBinder()) {
6698            // Er, no, still looks good to us.
6699            synchronized (this) {
6700                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6701                        + " says " + conn + " died, but we don't agree");
6702                return;
6703            }
6704        }
6705
6706        // Well look at that!  It's dead!
6707        synchronized (this) {
6708            if (conn.provider.provider != provider) {
6709                // But something changed...  good enough.
6710                return;
6711            }
6712
6713            ProcessRecord proc = conn.provider.proc;
6714            if (proc == null || proc.thread == null) {
6715                // Seems like the process is already cleaned up.
6716                return;
6717            }
6718
6719            // As far as we're concerned, this is just like receiving a
6720            // death notification...  just a bit prematurely.
6721            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6722                    + ") early provider death");
6723            final long ident = Binder.clearCallingIdentity();
6724            try {
6725                appDiedLocked(proc, proc.pid, proc.thread);
6726            } finally {
6727                Binder.restoreCallingIdentity(ident);
6728            }
6729        }
6730    }
6731
6732    public static final void installSystemProviders() {
6733        List<ProviderInfo> providers;
6734        synchronized (mSelf) {
6735            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6736            providers = mSelf.generateApplicationProvidersLocked(app);
6737            if (providers != null) {
6738                for (int i=providers.size()-1; i>=0; i--) {
6739                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6740                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6741                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6742                                + ": not system .apk");
6743                        providers.remove(i);
6744                    }
6745                }
6746            }
6747        }
6748        if (providers != null) {
6749            mSystemThread.installSystemProviders(providers);
6750        }
6751
6752        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6753
6754        mSelf.mUsageStatsService.monitorPackages();
6755    }
6756
6757    /**
6758     * Allows app to retrieve the MIME type of a URI without having permission
6759     * to access its content provider.
6760     *
6761     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6762     *
6763     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6764     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6765     */
6766    public String getProviderMimeType(Uri uri) {
6767        enforceNotIsolatedCaller("getProviderMimeType");
6768        final String name = uri.getAuthority();
6769        final long ident = Binder.clearCallingIdentity();
6770        ContentProviderHolder holder = null;
6771
6772        try {
6773            holder = getContentProviderExternalUnchecked(name, null);
6774            if (holder != null) {
6775                return holder.provider.getType(uri);
6776            }
6777        } catch (RemoteException e) {
6778            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6779            return null;
6780        } finally {
6781            if (holder != null) {
6782                removeContentProviderExternalUnchecked(name, null);
6783            }
6784            Binder.restoreCallingIdentity(ident);
6785        }
6786
6787        return null;
6788    }
6789
6790    // =========================================================
6791    // GLOBAL MANAGEMENT
6792    // =========================================================
6793
6794    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6795            ApplicationInfo info, String customProcess, boolean isolated) {
6796        String proc = customProcess != null ? customProcess : info.processName;
6797        BatteryStatsImpl.Uid.Proc ps = null;
6798        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6799        int uid = info.uid;
6800        if (isolated) {
6801            int userId = UserHandle.getUserId(uid);
6802            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6803            uid = 0;
6804            while (true) {
6805                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6806                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6807                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6808                }
6809                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6810                mNextIsolatedProcessUid++;
6811                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6812                    // No process for this uid, use it.
6813                    break;
6814                }
6815                stepsLeft--;
6816                if (stepsLeft <= 0) {
6817                    return null;
6818                }
6819            }
6820        }
6821        synchronized (stats) {
6822            ps = stats.getProcessStatsLocked(info.uid, proc);
6823        }
6824        return new ProcessRecord(ps, thread, info, proc, uid);
6825    }
6826
6827    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6828        ProcessRecord app;
6829        if (!isolated) {
6830            app = getProcessRecordLocked(info.processName, info.uid);
6831        } else {
6832            app = null;
6833        }
6834
6835        if (app == null) {
6836            app = newProcessRecordLocked(null, info, null, isolated);
6837            mProcessNames.put(info.processName, app.uid, app);
6838            if (isolated) {
6839                mIsolatedProcesses.put(app.uid, app);
6840            }
6841            updateLruProcessLocked(app, true, true);
6842        }
6843
6844        // This package really, really can not be stopped.
6845        try {
6846            AppGlobals.getPackageManager().setPackageStoppedState(
6847                    info.packageName, false, UserHandle.getUserId(app.uid));
6848        } catch (RemoteException e) {
6849        } catch (IllegalArgumentException e) {
6850            Slog.w(TAG, "Failed trying to unstop package "
6851                    + info.packageName + ": " + e);
6852        }
6853
6854        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6855                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6856            app.persistent = true;
6857            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6858        }
6859        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6860            mPersistentStartingProcesses.add(app);
6861            startProcessLocked(app, "added application", app.processName);
6862        }
6863
6864        return app;
6865    }
6866
6867    public void unhandledBack() {
6868        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6869                "unhandledBack()");
6870
6871        synchronized(this) {
6872            int count = mMainStack.mHistory.size();
6873            if (DEBUG_SWITCH) Slog.d(
6874                TAG, "Performing unhandledBack(): stack size = " + count);
6875            if (count > 1) {
6876                final long origId = Binder.clearCallingIdentity();
6877                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6878                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6879                Binder.restoreCallingIdentity(origId);
6880            }
6881        }
6882    }
6883
6884    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6885        enforceNotIsolatedCaller("openContentUri");
6886        String name = uri.getAuthority();
6887        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
6888        ParcelFileDescriptor pfd = null;
6889        if (cph != null) {
6890            // We record the binder invoker's uid in thread-local storage before
6891            // going to the content provider to open the file.  Later, in the code
6892            // that handles all permissions checks, we look for this uid and use
6893            // that rather than the Activity Manager's own uid.  The effect is that
6894            // we do the check against the caller's permissions even though it looks
6895            // to the content provider like the Activity Manager itself is making
6896            // the request.
6897            sCallerIdentity.set(new Identity(
6898                    Binder.getCallingPid(), Binder.getCallingUid()));
6899            try {
6900                pfd = cph.provider.openFile(uri, "r");
6901            } catch (FileNotFoundException e) {
6902                // do nothing; pfd will be returned null
6903            } finally {
6904                // Ensure that whatever happens, we clean up the identity state
6905                sCallerIdentity.remove();
6906            }
6907
6908            // We've got the fd now, so we're done with the provider.
6909            removeContentProviderExternalUnchecked(name, null);
6910        } else {
6911            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6912        }
6913        return pfd;
6914    }
6915
6916    // Actually is sleeping or shutting down or whatever else in the future
6917    // is an inactive state.
6918    public boolean isSleeping() {
6919        return mSleeping || mShuttingDown;
6920    }
6921
6922    public void goingToSleep() {
6923        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6924                != PackageManager.PERMISSION_GRANTED) {
6925            throw new SecurityException("Requires permission "
6926                    + android.Manifest.permission.DEVICE_POWER);
6927        }
6928
6929        synchronized(this) {
6930            mWentToSleep = true;
6931            updateEventDispatchingLocked();
6932
6933            if (!mSleeping) {
6934                mSleeping = true;
6935                mMainStack.stopIfSleepingLocked();
6936
6937                // Initialize the wake times of all processes.
6938                checkExcessivePowerUsageLocked(false);
6939                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6940                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6941                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6942            }
6943        }
6944    }
6945
6946    public boolean shutdown(int timeout) {
6947        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6948                != PackageManager.PERMISSION_GRANTED) {
6949            throw new SecurityException("Requires permission "
6950                    + android.Manifest.permission.SHUTDOWN);
6951        }
6952
6953        boolean timedout = false;
6954
6955        synchronized(this) {
6956            mShuttingDown = true;
6957            updateEventDispatchingLocked();
6958
6959            if (mMainStack.mResumedActivity != null) {
6960                mMainStack.stopIfSleepingLocked();
6961                final long endTime = System.currentTimeMillis() + timeout;
6962                while (mMainStack.mResumedActivity != null
6963                        || mMainStack.mPausingActivity != null) {
6964                    long delay = endTime - System.currentTimeMillis();
6965                    if (delay <= 0) {
6966                        Slog.w(TAG, "Activity manager shutdown timed out");
6967                        timedout = true;
6968                        break;
6969                    }
6970                    try {
6971                        this.wait();
6972                    } catch (InterruptedException e) {
6973                    }
6974                }
6975            }
6976        }
6977
6978        mUsageStatsService.shutdown();
6979        mBatteryStatsService.shutdown();
6980
6981        return timedout;
6982    }
6983
6984    public final void activitySlept(IBinder token) {
6985        if (localLOGV) Slog.v(
6986            TAG, "Activity slept: token=" + token);
6987
6988        ActivityRecord r = null;
6989
6990        final long origId = Binder.clearCallingIdentity();
6991
6992        synchronized (this) {
6993            r = mMainStack.isInStackLocked(token);
6994            if (r != null) {
6995                mMainStack.activitySleptLocked(r);
6996            }
6997        }
6998
6999        Binder.restoreCallingIdentity(origId);
7000    }
7001
7002    private void comeOutOfSleepIfNeededLocked() {
7003        if (!mWentToSleep && !mLockScreenShown) {
7004            if (mSleeping) {
7005                mSleeping = false;
7006                mMainStack.awakeFromSleepingLocked();
7007                mMainStack.resumeTopActivityLocked(null);
7008            }
7009        }
7010    }
7011
7012    public void wakingUp() {
7013        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7014                != PackageManager.PERMISSION_GRANTED) {
7015            throw new SecurityException("Requires permission "
7016                    + android.Manifest.permission.DEVICE_POWER);
7017        }
7018
7019        synchronized(this) {
7020            mWentToSleep = false;
7021            updateEventDispatchingLocked();
7022            comeOutOfSleepIfNeededLocked();
7023        }
7024    }
7025
7026    private void updateEventDispatchingLocked() {
7027        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7028    }
7029
7030    public void setLockScreenShown(boolean shown) {
7031        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7032                != PackageManager.PERMISSION_GRANTED) {
7033            throw new SecurityException("Requires permission "
7034                    + android.Manifest.permission.DEVICE_POWER);
7035        }
7036
7037        synchronized(this) {
7038            mLockScreenShown = shown;
7039            comeOutOfSleepIfNeededLocked();
7040        }
7041    }
7042
7043    public void stopAppSwitches() {
7044        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7045                != PackageManager.PERMISSION_GRANTED) {
7046            throw new SecurityException("Requires permission "
7047                    + android.Manifest.permission.STOP_APP_SWITCHES);
7048        }
7049
7050        synchronized(this) {
7051            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7052                    + APP_SWITCH_DELAY_TIME;
7053            mDidAppSwitch = false;
7054            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7055            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7056            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7057        }
7058    }
7059
7060    public void resumeAppSwitches() {
7061        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7062                != PackageManager.PERMISSION_GRANTED) {
7063            throw new SecurityException("Requires permission "
7064                    + android.Manifest.permission.STOP_APP_SWITCHES);
7065        }
7066
7067        synchronized(this) {
7068            // Note that we don't execute any pending app switches... we will
7069            // let those wait until either the timeout, or the next start
7070            // activity request.
7071            mAppSwitchesAllowedTime = 0;
7072        }
7073    }
7074
7075    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7076            String name) {
7077        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7078            return true;
7079        }
7080
7081        final int perm = checkComponentPermission(
7082                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7083                callingUid, -1, true);
7084        if (perm == PackageManager.PERMISSION_GRANTED) {
7085            return true;
7086        }
7087
7088        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7089        return false;
7090    }
7091
7092    public void setDebugApp(String packageName, boolean waitForDebugger,
7093            boolean persistent) {
7094        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7095                "setDebugApp()");
7096
7097        // Note that this is not really thread safe if there are multiple
7098        // callers into it at the same time, but that's not a situation we
7099        // care about.
7100        if (persistent) {
7101            final ContentResolver resolver = mContext.getContentResolver();
7102            Settings.System.putString(
7103                resolver, Settings.System.DEBUG_APP,
7104                packageName);
7105            Settings.System.putInt(
7106                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7107                waitForDebugger ? 1 : 0);
7108        }
7109
7110        synchronized (this) {
7111            if (!persistent) {
7112                mOrigDebugApp = mDebugApp;
7113                mOrigWaitForDebugger = mWaitForDebugger;
7114            }
7115            mDebugApp = packageName;
7116            mWaitForDebugger = waitForDebugger;
7117            mDebugTransient = !persistent;
7118            if (packageName != null) {
7119                final long origId = Binder.clearCallingIdentity();
7120                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
7121                Binder.restoreCallingIdentity(origId);
7122            }
7123        }
7124    }
7125
7126    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7127        synchronized (this) {
7128            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7129            if (!isDebuggable) {
7130                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7131                    throw new SecurityException("Process not debuggable: " + app.packageName);
7132                }
7133            }
7134
7135            mOpenGlTraceApp = processName;
7136        }
7137    }
7138
7139    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7140            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7141        synchronized (this) {
7142            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7143            if (!isDebuggable) {
7144                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7145                    throw new SecurityException("Process not debuggable: " + app.packageName);
7146                }
7147            }
7148            mProfileApp = processName;
7149            mProfileFile = profileFile;
7150            if (mProfileFd != null) {
7151                try {
7152                    mProfileFd.close();
7153                } catch (IOException e) {
7154                }
7155                mProfileFd = null;
7156            }
7157            mProfileFd = profileFd;
7158            mProfileType = 0;
7159            mAutoStopProfiler = autoStopProfiler;
7160        }
7161    }
7162
7163    public void setAlwaysFinish(boolean enabled) {
7164        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7165                "setAlwaysFinish()");
7166
7167        Settings.System.putInt(
7168                mContext.getContentResolver(),
7169                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7170
7171        synchronized (this) {
7172            mAlwaysFinishActivities = enabled;
7173        }
7174    }
7175
7176    public void setActivityController(IActivityController controller) {
7177        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7178                "setActivityController()");
7179        synchronized (this) {
7180            mController = controller;
7181        }
7182    }
7183
7184    public boolean isUserAMonkey() {
7185        // For now the fact that there is a controller implies
7186        // we have a monkey.
7187        synchronized (this) {
7188            return mController != null;
7189        }
7190    }
7191
7192    public void registerProcessObserver(IProcessObserver observer) {
7193        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7194                "registerProcessObserver()");
7195        synchronized (this) {
7196            mProcessObservers.register(observer);
7197        }
7198    }
7199
7200    public void unregisterProcessObserver(IProcessObserver observer) {
7201        synchronized (this) {
7202            mProcessObservers.unregister(observer);
7203        }
7204    }
7205
7206    public void setImmersive(IBinder token, boolean immersive) {
7207        synchronized(this) {
7208            ActivityRecord r = mMainStack.isInStackLocked(token);
7209            if (r == null) {
7210                throw new IllegalArgumentException();
7211            }
7212            r.immersive = immersive;
7213        }
7214    }
7215
7216    public boolean isImmersive(IBinder token) {
7217        synchronized (this) {
7218            ActivityRecord r = mMainStack.isInStackLocked(token);
7219            if (r == null) {
7220                throw new IllegalArgumentException();
7221            }
7222            return r.immersive;
7223        }
7224    }
7225
7226    public boolean isTopActivityImmersive() {
7227        enforceNotIsolatedCaller("startActivity");
7228        synchronized (this) {
7229            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7230            return (r != null) ? r.immersive : false;
7231        }
7232    }
7233
7234    public final void enterSafeMode() {
7235        synchronized(this) {
7236            // It only makes sense to do this before the system is ready
7237            // and started launching other packages.
7238            if (!mSystemReady) {
7239                try {
7240                    AppGlobals.getPackageManager().enterSafeMode();
7241                } catch (RemoteException e) {
7242                }
7243            }
7244        }
7245    }
7246
7247    public final void showSafeModeOverlay() {
7248        View v = LayoutInflater.from(mContext).inflate(
7249                com.android.internal.R.layout.safe_mode, null);
7250        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7251        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7252        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7253        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7254        lp.gravity = Gravity.BOTTOM | Gravity.START;
7255        lp.format = v.getBackground().getOpacity();
7256        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7257                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7258        ((WindowManager)mContext.getSystemService(
7259                Context.WINDOW_SERVICE)).addView(v, lp);
7260    }
7261
7262    public void noteWakeupAlarm(IIntentSender sender) {
7263        if (!(sender instanceof PendingIntentRecord)) {
7264            return;
7265        }
7266        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7267        synchronized (stats) {
7268            if (mBatteryStatsService.isOnBattery()) {
7269                mBatteryStatsService.enforceCallingPermission();
7270                PendingIntentRecord rec = (PendingIntentRecord)sender;
7271                int MY_UID = Binder.getCallingUid();
7272                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7273                BatteryStatsImpl.Uid.Pkg pkg =
7274                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7275                pkg.incWakeupsLocked();
7276            }
7277        }
7278    }
7279
7280    public boolean killPids(int[] pids, String pReason, boolean secure) {
7281        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7282            throw new SecurityException("killPids only available to the system");
7283        }
7284        String reason = (pReason == null) ? "Unknown" : pReason;
7285        // XXX Note: don't acquire main activity lock here, because the window
7286        // manager calls in with its locks held.
7287
7288        boolean killed = false;
7289        synchronized (mPidsSelfLocked) {
7290            int[] types = new int[pids.length];
7291            int worstType = 0;
7292            for (int i=0; i<pids.length; i++) {
7293                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7294                if (proc != null) {
7295                    int type = proc.setAdj;
7296                    types[i] = type;
7297                    if (type > worstType) {
7298                        worstType = type;
7299                    }
7300                }
7301            }
7302
7303            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7304            // then constrain it so we will kill all hidden procs.
7305            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7306                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7307                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7308            }
7309
7310            // If this is not a secure call, don't let it kill processes that
7311            // are important.
7312            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7313                worstType = ProcessList.SERVICE_ADJ;
7314            }
7315
7316            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7317            for (int i=0; i<pids.length; i++) {
7318                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7319                if (proc == null) {
7320                    continue;
7321                }
7322                int adj = proc.setAdj;
7323                if (adj >= worstType && !proc.killedBackground) {
7324                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7325                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7326                            proc.processName, adj, reason);
7327                    killed = true;
7328                    proc.killedBackground = true;
7329                    Process.killProcessQuiet(pids[i]);
7330                }
7331            }
7332        }
7333        return killed;
7334    }
7335
7336    @Override
7337    public boolean killProcessesBelowForeground(String reason) {
7338        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7339            throw new SecurityException("killProcessesBelowForeground() only available to system");
7340        }
7341
7342        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7343    }
7344
7345    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7346        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7347            throw new SecurityException("killProcessesBelowAdj() only available to system");
7348        }
7349
7350        boolean killed = false;
7351        synchronized (mPidsSelfLocked) {
7352            final int size = mPidsSelfLocked.size();
7353            for (int i = 0; i < size; i++) {
7354                final int pid = mPidsSelfLocked.keyAt(i);
7355                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7356                if (proc == null) continue;
7357
7358                final int adj = proc.setAdj;
7359                if (adj > belowAdj && !proc.killedBackground) {
7360                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7361                    EventLog.writeEvent(
7362                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7363                    killed = true;
7364                    proc.killedBackground = true;
7365                    Process.killProcessQuiet(pid);
7366                }
7367            }
7368        }
7369        return killed;
7370    }
7371
7372    public final void startRunning(String pkg, String cls, String action,
7373            String data) {
7374        synchronized(this) {
7375            if (mStartRunning) {
7376                return;
7377            }
7378            mStartRunning = true;
7379            mTopComponent = pkg != null && cls != null
7380                    ? new ComponentName(pkg, cls) : null;
7381            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7382            mTopData = data;
7383            if (!mSystemReady) {
7384                return;
7385            }
7386        }
7387
7388        systemReady(null);
7389    }
7390
7391    private void retrieveSettings() {
7392        final ContentResolver resolver = mContext.getContentResolver();
7393        String debugApp = Settings.System.getString(
7394            resolver, Settings.System.DEBUG_APP);
7395        boolean waitForDebugger = Settings.System.getInt(
7396            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7397        boolean alwaysFinishActivities = Settings.System.getInt(
7398            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7399
7400        Configuration configuration = new Configuration();
7401        Settings.System.getConfiguration(resolver, configuration);
7402
7403        synchronized (this) {
7404            mDebugApp = mOrigDebugApp = debugApp;
7405            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7406            mAlwaysFinishActivities = alwaysFinishActivities;
7407            // This happens before any activities are started, so we can
7408            // change mConfiguration in-place.
7409            updateConfigurationLocked(configuration, null, false, true);
7410            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7411        }
7412    }
7413
7414    public boolean testIsSystemReady() {
7415        // no need to synchronize(this) just to read & return the value
7416        return mSystemReady;
7417    }
7418
7419    private static File getCalledPreBootReceiversFile() {
7420        File dataDir = Environment.getDataDirectory();
7421        File systemDir = new File(dataDir, "system");
7422        File fname = new File(systemDir, "called_pre_boots.dat");
7423        return fname;
7424    }
7425
7426    static final int LAST_DONE_VERSION = 10000;
7427
7428    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7429        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7430        File file = getCalledPreBootReceiversFile();
7431        FileInputStream fis = null;
7432        try {
7433            fis = new FileInputStream(file);
7434            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7435            int fvers = dis.readInt();
7436            if (fvers == LAST_DONE_VERSION) {
7437                String vers = dis.readUTF();
7438                String codename = dis.readUTF();
7439                String build = dis.readUTF();
7440                if (android.os.Build.VERSION.RELEASE.equals(vers)
7441                        && android.os.Build.VERSION.CODENAME.equals(codename)
7442                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7443                    int num = dis.readInt();
7444                    while (num > 0) {
7445                        num--;
7446                        String pkg = dis.readUTF();
7447                        String cls = dis.readUTF();
7448                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7449                    }
7450                }
7451            }
7452        } catch (FileNotFoundException e) {
7453        } catch (IOException e) {
7454            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7455        } finally {
7456            if (fis != null) {
7457                try {
7458                    fis.close();
7459                } catch (IOException e) {
7460                }
7461            }
7462        }
7463        return lastDoneReceivers;
7464    }
7465
7466    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7467        File file = getCalledPreBootReceiversFile();
7468        FileOutputStream fos = null;
7469        DataOutputStream dos = null;
7470        try {
7471            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7472            fos = new FileOutputStream(file);
7473            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7474            dos.writeInt(LAST_DONE_VERSION);
7475            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7476            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7477            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7478            dos.writeInt(list.size());
7479            for (int i=0; i<list.size(); i++) {
7480                dos.writeUTF(list.get(i).getPackageName());
7481                dos.writeUTF(list.get(i).getClassName());
7482            }
7483        } catch (IOException e) {
7484            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7485            file.delete();
7486        } finally {
7487            FileUtils.sync(fos);
7488            if (dos != null) {
7489                try {
7490                    dos.close();
7491                } catch (IOException e) {
7492                    // TODO Auto-generated catch block
7493                    e.printStackTrace();
7494                }
7495            }
7496        }
7497    }
7498
7499    public void systemReady(final Runnable goingCallback) {
7500        synchronized(this) {
7501            if (mSystemReady) {
7502                if (goingCallback != null) goingCallback.run();
7503                return;
7504            }
7505
7506            // Check to see if there are any update receivers to run.
7507            if (!mDidUpdate) {
7508                if (mWaitingUpdate) {
7509                    return;
7510                }
7511                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7512                List<ResolveInfo> ris = null;
7513                try {
7514                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7515                            intent, null, 0, 0);
7516                } catch (RemoteException e) {
7517                }
7518                if (ris != null) {
7519                    for (int i=ris.size()-1; i>=0; i--) {
7520                        if ((ris.get(i).activityInfo.applicationInfo.flags
7521                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7522                            ris.remove(i);
7523                        }
7524                    }
7525                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7526
7527                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7528
7529                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7530                    for (int i=0; i<ris.size(); i++) {
7531                        ActivityInfo ai = ris.get(i).activityInfo;
7532                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7533                        if (lastDoneReceivers.contains(comp)) {
7534                            ris.remove(i);
7535                            i--;
7536                        }
7537                    }
7538
7539                    for (int i=0; i<ris.size(); i++) {
7540                        ActivityInfo ai = ris.get(i).activityInfo;
7541                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7542                        doneReceivers.add(comp);
7543                        intent.setComponent(comp);
7544                        IIntentReceiver finisher = null;
7545                        if (i == ris.size()-1) {
7546                            finisher = new IIntentReceiver.Stub() {
7547                                public void performReceive(Intent intent, int resultCode,
7548                                        String data, Bundle extras, boolean ordered,
7549                                        boolean sticky) {
7550                                    // The raw IIntentReceiver interface is called
7551                                    // with the AM lock held, so redispatch to
7552                                    // execute our code without the lock.
7553                                    mHandler.post(new Runnable() {
7554                                        public void run() {
7555                                            synchronized (ActivityManagerService.this) {
7556                                                mDidUpdate = true;
7557                                            }
7558                                            writeLastDonePreBootReceivers(doneReceivers);
7559                                            showBootMessage(mContext.getText(
7560                                                    R.string.android_upgrading_complete),
7561                                                    false);
7562                                            systemReady(goingCallback);
7563                                        }
7564                                    });
7565                                }
7566                            };
7567                        }
7568                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7569                        /* TODO: Send this to all users */
7570                        broadcastIntentLocked(null, null, intent, null, finisher,
7571                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7572                                0 /* UserId zero */);
7573                        if (finisher != null) {
7574                            mWaitingUpdate = true;
7575                        }
7576                    }
7577                }
7578                if (mWaitingUpdate) {
7579                    return;
7580                }
7581                mDidUpdate = true;
7582            }
7583
7584            mSystemReady = true;
7585            if (!mStartRunning) {
7586                return;
7587            }
7588        }
7589
7590        ArrayList<ProcessRecord> procsToKill = null;
7591        synchronized(mPidsSelfLocked) {
7592            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7593                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7594                if (!isAllowedWhileBooting(proc.info)){
7595                    if (procsToKill == null) {
7596                        procsToKill = new ArrayList<ProcessRecord>();
7597                    }
7598                    procsToKill.add(proc);
7599                }
7600            }
7601        }
7602
7603        synchronized(this) {
7604            if (procsToKill != null) {
7605                for (int i=procsToKill.size()-1; i>=0; i--) {
7606                    ProcessRecord proc = procsToKill.get(i);
7607                    Slog.i(TAG, "Removing system update proc: " + proc);
7608                    removeProcessLocked(proc, true, false, "system update done");
7609                }
7610            }
7611
7612            // Now that we have cleaned up any update processes, we
7613            // are ready to start launching real processes and know that
7614            // we won't trample on them any more.
7615            mProcessesReady = true;
7616        }
7617
7618        Slog.i(TAG, "System now ready");
7619        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7620            SystemClock.uptimeMillis());
7621
7622        synchronized(this) {
7623            // Make sure we have no pre-ready processes sitting around.
7624
7625            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7626                ResolveInfo ri = mContext.getPackageManager()
7627                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7628                                STOCK_PM_FLAGS);
7629                CharSequence errorMsg = null;
7630                if (ri != null) {
7631                    ActivityInfo ai = ri.activityInfo;
7632                    ApplicationInfo app = ai.applicationInfo;
7633                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7634                        mTopAction = Intent.ACTION_FACTORY_TEST;
7635                        mTopData = null;
7636                        mTopComponent = new ComponentName(app.packageName,
7637                                ai.name);
7638                    } else {
7639                        errorMsg = mContext.getResources().getText(
7640                                com.android.internal.R.string.factorytest_not_system);
7641                    }
7642                } else {
7643                    errorMsg = mContext.getResources().getText(
7644                            com.android.internal.R.string.factorytest_no_action);
7645                }
7646                if (errorMsg != null) {
7647                    mTopAction = null;
7648                    mTopData = null;
7649                    mTopComponent = null;
7650                    Message msg = Message.obtain();
7651                    msg.what = SHOW_FACTORY_ERROR_MSG;
7652                    msg.getData().putCharSequence("msg", errorMsg);
7653                    mHandler.sendMessage(msg);
7654                }
7655            }
7656        }
7657
7658        retrieveSettings();
7659
7660        if (goingCallback != null) goingCallback.run();
7661
7662        synchronized (this) {
7663            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7664                try {
7665                    List apps = AppGlobals.getPackageManager().
7666                        getPersistentApplications(STOCK_PM_FLAGS);
7667                    if (apps != null) {
7668                        int N = apps.size();
7669                        int i;
7670                        for (i=0; i<N; i++) {
7671                            ApplicationInfo info
7672                                = (ApplicationInfo)apps.get(i);
7673                            if (info != null &&
7674                                    !info.packageName.equals("android")) {
7675                                addAppLocked(info, false);
7676                            }
7677                        }
7678                    }
7679                } catch (RemoteException ex) {
7680                    // pm is in same process, this will never happen.
7681                }
7682            }
7683
7684            // Start up initial activity.
7685            mBooting = true;
7686
7687            try {
7688                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7689                    Message msg = Message.obtain();
7690                    msg.what = SHOW_UID_ERROR_MSG;
7691                    mHandler.sendMessage(msg);
7692                }
7693            } catch (RemoteException e) {
7694            }
7695
7696            mMainStack.resumeTopActivityLocked(null);
7697        }
7698    }
7699
7700    private boolean makeAppCrashingLocked(ProcessRecord app,
7701            String shortMsg, String longMsg, String stackTrace) {
7702        app.crashing = true;
7703        app.crashingReport = generateProcessError(app,
7704                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7705        startAppProblemLocked(app);
7706        app.stopFreezingAllLocked();
7707        return handleAppCrashLocked(app);
7708    }
7709
7710    private void makeAppNotRespondingLocked(ProcessRecord app,
7711            String activity, String shortMsg, String longMsg) {
7712        app.notResponding = true;
7713        app.notRespondingReport = generateProcessError(app,
7714                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7715                activity, shortMsg, longMsg, null);
7716        startAppProblemLocked(app);
7717        app.stopFreezingAllLocked();
7718    }
7719
7720    /**
7721     * Generate a process error record, suitable for attachment to a ProcessRecord.
7722     *
7723     * @param app The ProcessRecord in which the error occurred.
7724     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7725     *                      ActivityManager.AppErrorStateInfo
7726     * @param activity The activity associated with the crash, if known.
7727     * @param shortMsg Short message describing the crash.
7728     * @param longMsg Long message describing the crash.
7729     * @param stackTrace Full crash stack trace, may be null.
7730     *
7731     * @return Returns a fully-formed AppErrorStateInfo record.
7732     */
7733    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7734            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7735        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7736
7737        report.condition = condition;
7738        report.processName = app.processName;
7739        report.pid = app.pid;
7740        report.uid = app.info.uid;
7741        report.tag = activity;
7742        report.shortMsg = shortMsg;
7743        report.longMsg = longMsg;
7744        report.stackTrace = stackTrace;
7745
7746        return report;
7747    }
7748
7749    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7750        synchronized (this) {
7751            app.crashing = false;
7752            app.crashingReport = null;
7753            app.notResponding = false;
7754            app.notRespondingReport = null;
7755            if (app.anrDialog == fromDialog) {
7756                app.anrDialog = null;
7757            }
7758            if (app.waitDialog == fromDialog) {
7759                app.waitDialog = null;
7760            }
7761            if (app.pid > 0 && app.pid != MY_PID) {
7762                handleAppCrashLocked(app);
7763                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7764                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7765                        app.processName, app.setAdj, "user's request after error");
7766                Process.killProcessQuiet(app.pid);
7767            }
7768        }
7769    }
7770
7771    private boolean handleAppCrashLocked(ProcessRecord app) {
7772        if (mHeadless) {
7773            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7774            return false;
7775        }
7776        long now = SystemClock.uptimeMillis();
7777
7778        Long crashTime;
7779        if (!app.isolated) {
7780            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7781        } else {
7782            crashTime = null;
7783        }
7784        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7785            // This process loses!
7786            Slog.w(TAG, "Process " + app.info.processName
7787                    + " has crashed too many times: killing!");
7788            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7789                    app.info.processName, app.uid);
7790            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7791                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7792                if (r.app == app) {
7793                    Slog.w(TAG, "  Force finishing activity "
7794                        + r.intent.getComponent().flattenToShortString());
7795                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7796                }
7797            }
7798            if (!app.persistent) {
7799                // We don't want to start this process again until the user
7800                // explicitly does so...  but for persistent process, we really
7801                // need to keep it running.  If a persistent process is actually
7802                // repeatedly crashing, then badness for everyone.
7803                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7804                        app.info.processName);
7805                if (!app.isolated) {
7806                    // XXX We don't have a way to mark isolated processes
7807                    // as bad, since they don't have a peristent identity.
7808                    mBadProcesses.put(app.info.processName, app.uid, now);
7809                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7810                }
7811                app.bad = true;
7812                app.removed = true;
7813                // Don't let services in this process be restarted and potentially
7814                // annoy the user repeatedly.  Unless it is persistent, since those
7815                // processes run critical code.
7816                removeProcessLocked(app, false, false, "crash");
7817                mMainStack.resumeTopActivityLocked(null);
7818                return false;
7819            }
7820            mMainStack.resumeTopActivityLocked(null);
7821        } else {
7822            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7823            if (r != null && r.app == app) {
7824                // If the top running activity is from this crashing
7825                // process, then terminate it to avoid getting in a loop.
7826                Slog.w(TAG, "  Force finishing activity "
7827                        + r.intent.getComponent().flattenToShortString());
7828                int index = mMainStack.indexOfActivityLocked(r);
7829                r.stack.finishActivityLocked(r, index,
7830                        Activity.RESULT_CANCELED, null, "crashed");
7831                // Also terminate any activities below it that aren't yet
7832                // stopped, to avoid a situation where one will get
7833                // re-start our crashing activity once it gets resumed again.
7834                index--;
7835                if (index >= 0) {
7836                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7837                    if (r.state == ActivityState.RESUMED
7838                            || r.state == ActivityState.PAUSING
7839                            || r.state == ActivityState.PAUSED) {
7840                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7841                            Slog.w(TAG, "  Force finishing activity "
7842                                    + r.intent.getComponent().flattenToShortString());
7843                            r.stack.finishActivityLocked(r, index,
7844                                    Activity.RESULT_CANCELED, null, "crashed");
7845                        }
7846                    }
7847                }
7848            }
7849        }
7850
7851        // Bump up the crash count of any services currently running in the proc.
7852        if (app.services.size() != 0) {
7853            // Any services running in the application need to be placed
7854            // back in the pending list.
7855            Iterator<ServiceRecord> it = app.services.iterator();
7856            while (it.hasNext()) {
7857                ServiceRecord sr = it.next();
7858                sr.crashCount++;
7859            }
7860        }
7861
7862        // If the crashing process is what we consider to be the "home process" and it has been
7863        // replaced by a third-party app, clear the package preferred activities from packages
7864        // with a home activity running in the process to prevent a repeatedly crashing app
7865        // from blocking the user to manually clear the list.
7866        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7867                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7868            Iterator it = mHomeProcess.activities.iterator();
7869            while (it.hasNext()) {
7870                ActivityRecord r = (ActivityRecord)it.next();
7871                if (r.isHomeActivity) {
7872                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7873                    try {
7874                        ActivityThread.getPackageManager()
7875                                .clearPackagePreferredActivities(r.packageName);
7876                    } catch (RemoteException c) {
7877                        // pm is in same process, this will never happen.
7878                    }
7879                }
7880            }
7881        }
7882
7883        if (!app.isolated) {
7884            // XXX Can't keep track of crash times for isolated processes,
7885            // because they don't have a perisistent identity.
7886            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7887        }
7888
7889        return true;
7890    }
7891
7892    void startAppProblemLocked(ProcessRecord app) {
7893        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7894                mContext, app.info.packageName, app.info.flags);
7895        skipCurrentReceiverLocked(app);
7896    }
7897
7898    void skipCurrentReceiverLocked(ProcessRecord app) {
7899        for (BroadcastQueue queue : mBroadcastQueues) {
7900            queue.skipCurrentReceiverLocked(app);
7901        }
7902    }
7903
7904    /**
7905     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7906     * The application process will exit immediately after this call returns.
7907     * @param app object of the crashing app, null for the system server
7908     * @param crashInfo describing the exception
7909     */
7910    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7911        ProcessRecord r = findAppProcess(app, "Crash");
7912        final String processName = app == null ? "system_server"
7913                : (r == null ? "unknown" : r.processName);
7914
7915        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7916                processName,
7917                r == null ? -1 : r.info.flags,
7918                crashInfo.exceptionClassName,
7919                crashInfo.exceptionMessage,
7920                crashInfo.throwFileName,
7921                crashInfo.throwLineNumber);
7922
7923        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7924
7925        crashApplication(r, crashInfo);
7926    }
7927
7928    public void handleApplicationStrictModeViolation(
7929            IBinder app,
7930            int violationMask,
7931            StrictMode.ViolationInfo info) {
7932        ProcessRecord r = findAppProcess(app, "StrictMode");
7933        if (r == null) {
7934            return;
7935        }
7936
7937        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7938            Integer stackFingerprint = info.hashCode();
7939            boolean logIt = true;
7940            synchronized (mAlreadyLoggedViolatedStacks) {
7941                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7942                    logIt = false;
7943                    // TODO: sub-sample into EventLog for these, with
7944                    // the info.durationMillis?  Then we'd get
7945                    // the relative pain numbers, without logging all
7946                    // the stack traces repeatedly.  We'd want to do
7947                    // likewise in the client code, which also does
7948                    // dup suppression, before the Binder call.
7949                } else {
7950                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7951                        mAlreadyLoggedViolatedStacks.clear();
7952                    }
7953                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7954                }
7955            }
7956            if (logIt) {
7957                logStrictModeViolationToDropBox(r, info);
7958            }
7959        }
7960
7961        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7962            AppErrorResult result = new AppErrorResult();
7963            synchronized (this) {
7964                final long origId = Binder.clearCallingIdentity();
7965
7966                Message msg = Message.obtain();
7967                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7968                HashMap<String, Object> data = new HashMap<String, Object>();
7969                data.put("result", result);
7970                data.put("app", r);
7971                data.put("violationMask", violationMask);
7972                data.put("info", info);
7973                msg.obj = data;
7974                mHandler.sendMessage(msg);
7975
7976                Binder.restoreCallingIdentity(origId);
7977            }
7978            int res = result.get();
7979            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7980        }
7981    }
7982
7983    // Depending on the policy in effect, there could be a bunch of
7984    // these in quick succession so we try to batch these together to
7985    // minimize disk writes, number of dropbox entries, and maximize
7986    // compression, by having more fewer, larger records.
7987    private void logStrictModeViolationToDropBox(
7988            ProcessRecord process,
7989            StrictMode.ViolationInfo info) {
7990        if (info == null) {
7991            return;
7992        }
7993        final boolean isSystemApp = process == null ||
7994                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7995                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7996        final String processName = process == null ? "unknown" : process.processName;
7997        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7998        final DropBoxManager dbox = (DropBoxManager)
7999                mContext.getSystemService(Context.DROPBOX_SERVICE);
8000
8001        // Exit early if the dropbox isn't configured to accept this report type.
8002        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8003
8004        boolean bufferWasEmpty;
8005        boolean needsFlush;
8006        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8007        synchronized (sb) {
8008            bufferWasEmpty = sb.length() == 0;
8009            appendDropBoxProcessHeaders(process, processName, sb);
8010            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8011            sb.append("System-App: ").append(isSystemApp).append("\n");
8012            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8013            if (info.violationNumThisLoop != 0) {
8014                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8015            }
8016            if (info.numAnimationsRunning != 0) {
8017                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8018            }
8019            if (info.broadcastIntentAction != null) {
8020                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8021            }
8022            if (info.durationMillis != -1) {
8023                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8024            }
8025            if (info.numInstances != -1) {
8026                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8027            }
8028            if (info.tags != null) {
8029                for (String tag : info.tags) {
8030                    sb.append("Span-Tag: ").append(tag).append("\n");
8031                }
8032            }
8033            sb.append("\n");
8034            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8035                sb.append(info.crashInfo.stackTrace);
8036            }
8037            sb.append("\n");
8038
8039            // Only buffer up to ~64k.  Various logging bits truncate
8040            // things at 128k.
8041            needsFlush = (sb.length() > 64 * 1024);
8042        }
8043
8044        // Flush immediately if the buffer's grown too large, or this
8045        // is a non-system app.  Non-system apps are isolated with a
8046        // different tag & policy and not batched.
8047        //
8048        // Batching is useful during internal testing with
8049        // StrictMode settings turned up high.  Without batching,
8050        // thousands of separate files could be created on boot.
8051        if (!isSystemApp || needsFlush) {
8052            new Thread("Error dump: " + dropboxTag) {
8053                @Override
8054                public void run() {
8055                    String report;
8056                    synchronized (sb) {
8057                        report = sb.toString();
8058                        sb.delete(0, sb.length());
8059                        sb.trimToSize();
8060                    }
8061                    if (report.length() != 0) {
8062                        dbox.addText(dropboxTag, report);
8063                    }
8064                }
8065            }.start();
8066            return;
8067        }
8068
8069        // System app batching:
8070        if (!bufferWasEmpty) {
8071            // An existing dropbox-writing thread is outstanding, so
8072            // we don't need to start it up.  The existing thread will
8073            // catch the buffer appends we just did.
8074            return;
8075        }
8076
8077        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8078        // (After this point, we shouldn't access AMS internal data structures.)
8079        new Thread("Error dump: " + dropboxTag) {
8080            @Override
8081            public void run() {
8082                // 5 second sleep to let stacks arrive and be batched together
8083                try {
8084                    Thread.sleep(5000);  // 5 seconds
8085                } catch (InterruptedException e) {}
8086
8087                String errorReport;
8088                synchronized (mStrictModeBuffer) {
8089                    errorReport = mStrictModeBuffer.toString();
8090                    if (errorReport.length() == 0) {
8091                        return;
8092                    }
8093                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8094                    mStrictModeBuffer.trimToSize();
8095                }
8096                dbox.addText(dropboxTag, errorReport);
8097            }
8098        }.start();
8099    }
8100
8101    /**
8102     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8103     * @param app object of the crashing app, null for the system server
8104     * @param tag reported by the caller
8105     * @param crashInfo describing the context of the error
8106     * @return true if the process should exit immediately (WTF is fatal)
8107     */
8108    public boolean handleApplicationWtf(IBinder app, String tag,
8109            ApplicationErrorReport.CrashInfo crashInfo) {
8110        ProcessRecord r = findAppProcess(app, "WTF");
8111        final String processName = app == null ? "system_server"
8112                : (r == null ? "unknown" : r.processName);
8113
8114        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8115                processName,
8116                r == null ? -1 : r.info.flags,
8117                tag, crashInfo.exceptionMessage);
8118
8119        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8120
8121        if (r != null && r.pid != Process.myPid() &&
8122                Settings.Secure.getInt(mContext.getContentResolver(),
8123                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8124            crashApplication(r, crashInfo);
8125            return true;
8126        } else {
8127            return false;
8128        }
8129    }
8130
8131    /**
8132     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8133     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8134     */
8135    private ProcessRecord findAppProcess(IBinder app, String reason) {
8136        if (app == null) {
8137            return null;
8138        }
8139
8140        synchronized (this) {
8141            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8142                final int NA = apps.size();
8143                for (int ia=0; ia<NA; ia++) {
8144                    ProcessRecord p = apps.valueAt(ia);
8145                    if (p.thread != null && p.thread.asBinder() == app) {
8146                        return p;
8147                    }
8148                }
8149            }
8150
8151            Slog.w(TAG, "Can't find mystery application for " + reason
8152                    + " from pid=" + Binder.getCallingPid()
8153                    + " uid=" + Binder.getCallingUid() + ": " + app);
8154            return null;
8155        }
8156    }
8157
8158    /**
8159     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8160     * to append various headers to the dropbox log text.
8161     */
8162    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8163            StringBuilder sb) {
8164        // Watchdog thread ends up invoking this function (with
8165        // a null ProcessRecord) to add the stack file to dropbox.
8166        // Do not acquire a lock on this (am) in such cases, as it
8167        // could cause a potential deadlock, if and when watchdog
8168        // is invoked due to unavailability of lock on am and it
8169        // would prevent watchdog from killing system_server.
8170        if (process == null) {
8171            sb.append("Process: ").append(processName).append("\n");
8172            return;
8173        }
8174        // Note: ProcessRecord 'process' is guarded by the service
8175        // instance.  (notably process.pkgList, which could otherwise change
8176        // concurrently during execution of this method)
8177        synchronized (this) {
8178            sb.append("Process: ").append(processName).append("\n");
8179            int flags = process.info.flags;
8180            IPackageManager pm = AppGlobals.getPackageManager();
8181            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8182            for (String pkg : process.pkgList) {
8183                sb.append("Package: ").append(pkg);
8184                try {
8185                    PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
8186                    if (pi != null) {
8187                        sb.append(" v").append(pi.versionCode);
8188                        if (pi.versionName != null) {
8189                            sb.append(" (").append(pi.versionName).append(")");
8190                        }
8191                    }
8192                } catch (RemoteException e) {
8193                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8194                }
8195                sb.append("\n");
8196            }
8197        }
8198    }
8199
8200    private static String processClass(ProcessRecord process) {
8201        if (process == null || process.pid == MY_PID) {
8202            return "system_server";
8203        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8204            return "system_app";
8205        } else {
8206            return "data_app";
8207        }
8208    }
8209
8210    /**
8211     * Write a description of an error (crash, WTF, ANR) to the drop box.
8212     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8213     * @param process which caused the error, null means the system server
8214     * @param activity which triggered the error, null if unknown
8215     * @param parent activity related to the error, null if unknown
8216     * @param subject line related to the error, null if absent
8217     * @param report in long form describing the error, null if absent
8218     * @param logFile to include in the report, null if none
8219     * @param crashInfo giving an application stack trace, null if absent
8220     */
8221    public void addErrorToDropBox(String eventType,
8222            ProcessRecord process, String processName, ActivityRecord activity,
8223            ActivityRecord parent, String subject,
8224            final String report, final File logFile,
8225            final ApplicationErrorReport.CrashInfo crashInfo) {
8226        // NOTE -- this must never acquire the ActivityManagerService lock,
8227        // otherwise the watchdog may be prevented from resetting the system.
8228
8229        final String dropboxTag = processClass(process) + "_" + eventType;
8230        final DropBoxManager dbox = (DropBoxManager)
8231                mContext.getSystemService(Context.DROPBOX_SERVICE);
8232
8233        // Exit early if the dropbox isn't configured to accept this report type.
8234        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8235
8236        final StringBuilder sb = new StringBuilder(1024);
8237        appendDropBoxProcessHeaders(process, processName, sb);
8238        if (activity != null) {
8239            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8240        }
8241        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8242            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8243        }
8244        if (parent != null && parent != activity) {
8245            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8246        }
8247        if (subject != null) {
8248            sb.append("Subject: ").append(subject).append("\n");
8249        }
8250        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8251        if (Debug.isDebuggerConnected()) {
8252            sb.append("Debugger: Connected\n");
8253        }
8254        sb.append("\n");
8255
8256        // Do the rest in a worker thread to avoid blocking the caller on I/O
8257        // (After this point, we shouldn't access AMS internal data structures.)
8258        Thread worker = new Thread("Error dump: " + dropboxTag) {
8259            @Override
8260            public void run() {
8261                if (report != null) {
8262                    sb.append(report);
8263                }
8264                if (logFile != null) {
8265                    try {
8266                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8267                    } catch (IOException e) {
8268                        Slog.e(TAG, "Error reading " + logFile, e);
8269                    }
8270                }
8271                if (crashInfo != null && crashInfo.stackTrace != null) {
8272                    sb.append(crashInfo.stackTrace);
8273                }
8274
8275                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8276                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8277                if (lines > 0) {
8278                    sb.append("\n");
8279
8280                    // Merge several logcat streams, and take the last N lines
8281                    InputStreamReader input = null;
8282                    try {
8283                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8284                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8285                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8286
8287                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8288                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8289                        input = new InputStreamReader(logcat.getInputStream());
8290
8291                        int num;
8292                        char[] buf = new char[8192];
8293                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8294                    } catch (IOException e) {
8295                        Slog.e(TAG, "Error running logcat", e);
8296                    } finally {
8297                        if (input != null) try { input.close(); } catch (IOException e) {}
8298                    }
8299                }
8300
8301                dbox.addText(dropboxTag, sb.toString());
8302            }
8303        };
8304
8305        if (process == null) {
8306            // If process is null, we are being called from some internal code
8307            // and may be about to die -- run this synchronously.
8308            worker.run();
8309        } else {
8310            worker.start();
8311        }
8312    }
8313
8314    /**
8315     * Bring up the "unexpected error" dialog box for a crashing app.
8316     * Deal with edge cases (intercepts from instrumented applications,
8317     * ActivityController, error intent receivers, that sort of thing).
8318     * @param r the application crashing
8319     * @param crashInfo describing the failure
8320     */
8321    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8322        long timeMillis = System.currentTimeMillis();
8323        String shortMsg = crashInfo.exceptionClassName;
8324        String longMsg = crashInfo.exceptionMessage;
8325        String stackTrace = crashInfo.stackTrace;
8326        if (shortMsg != null && longMsg != null) {
8327            longMsg = shortMsg + ": " + longMsg;
8328        } else if (shortMsg != null) {
8329            longMsg = shortMsg;
8330        }
8331
8332        AppErrorResult result = new AppErrorResult();
8333        synchronized (this) {
8334            if (mController != null) {
8335                try {
8336                    String name = r != null ? r.processName : null;
8337                    int pid = r != null ? r.pid : Binder.getCallingPid();
8338                    if (!mController.appCrashed(name, pid,
8339                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8340                        Slog.w(TAG, "Force-killing crashed app " + name
8341                                + " at watcher's request");
8342                        Process.killProcess(pid);
8343                        return;
8344                    }
8345                } catch (RemoteException e) {
8346                    mController = null;
8347                }
8348            }
8349
8350            final long origId = Binder.clearCallingIdentity();
8351
8352            // If this process is running instrumentation, finish it.
8353            if (r != null && r.instrumentationClass != null) {
8354                Slog.w(TAG, "Error in app " + r.processName
8355                      + " running instrumentation " + r.instrumentationClass + ":");
8356                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8357                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8358                Bundle info = new Bundle();
8359                info.putString("shortMsg", shortMsg);
8360                info.putString("longMsg", longMsg);
8361                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8362                Binder.restoreCallingIdentity(origId);
8363                return;
8364            }
8365
8366            // If we can't identify the process or it's already exceeded its crash quota,
8367            // quit right away without showing a crash dialog.
8368            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8369                Binder.restoreCallingIdentity(origId);
8370                return;
8371            }
8372
8373            Message msg = Message.obtain();
8374            msg.what = SHOW_ERROR_MSG;
8375            HashMap data = new HashMap();
8376            data.put("result", result);
8377            data.put("app", r);
8378            msg.obj = data;
8379            mHandler.sendMessage(msg);
8380
8381            Binder.restoreCallingIdentity(origId);
8382        }
8383
8384        int res = result.get();
8385
8386        Intent appErrorIntent = null;
8387        synchronized (this) {
8388            if (r != null && !r.isolated) {
8389                // XXX Can't keep track of crash time for isolated processes,
8390                // since they don't have a persistent identity.
8391                mProcessCrashTimes.put(r.info.processName, r.uid,
8392                        SystemClock.uptimeMillis());
8393            }
8394            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8395                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8396            }
8397        }
8398
8399        if (appErrorIntent != null) {
8400            try {
8401                mContext.startActivity(appErrorIntent);
8402            } catch (ActivityNotFoundException e) {
8403                Slog.w(TAG, "bug report receiver dissappeared", e);
8404            }
8405        }
8406    }
8407
8408    Intent createAppErrorIntentLocked(ProcessRecord r,
8409            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8410        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8411        if (report == null) {
8412            return null;
8413        }
8414        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8415        result.setComponent(r.errorReportReceiver);
8416        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8417        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8418        return result;
8419    }
8420
8421    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8422            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8423        if (r.errorReportReceiver == null) {
8424            return null;
8425        }
8426
8427        if (!r.crashing && !r.notResponding) {
8428            return null;
8429        }
8430
8431        ApplicationErrorReport report = new ApplicationErrorReport();
8432        report.packageName = r.info.packageName;
8433        report.installerPackageName = r.errorReportReceiver.getPackageName();
8434        report.processName = r.processName;
8435        report.time = timeMillis;
8436        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8437
8438        if (r.crashing) {
8439            report.type = ApplicationErrorReport.TYPE_CRASH;
8440            report.crashInfo = crashInfo;
8441        } else if (r.notResponding) {
8442            report.type = ApplicationErrorReport.TYPE_ANR;
8443            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8444
8445            report.anrInfo.activity = r.notRespondingReport.tag;
8446            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8447            report.anrInfo.info = r.notRespondingReport.longMsg;
8448        }
8449
8450        return report;
8451    }
8452
8453    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8454        enforceNotIsolatedCaller("getProcessesInErrorState");
8455        // assume our apps are happy - lazy create the list
8456        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8457
8458        final boolean allUsers = ActivityManager.checkUidPermission(
8459                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8460                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8461        int userId = UserHandle.getUserId(Binder.getCallingUid());
8462
8463        synchronized (this) {
8464
8465            // iterate across all processes
8466            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8467                ProcessRecord app = mLruProcesses.get(i);
8468                if (!allUsers && app.userId != userId) {
8469                    continue;
8470                }
8471                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8472                    // This one's in trouble, so we'll generate a report for it
8473                    // crashes are higher priority (in case there's a crash *and* an anr)
8474                    ActivityManager.ProcessErrorStateInfo report = null;
8475                    if (app.crashing) {
8476                        report = app.crashingReport;
8477                    } else if (app.notResponding) {
8478                        report = app.notRespondingReport;
8479                    }
8480
8481                    if (report != null) {
8482                        if (errList == null) {
8483                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8484                        }
8485                        errList.add(report);
8486                    } else {
8487                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8488                                " crashing = " + app.crashing +
8489                                " notResponding = " + app.notResponding);
8490                    }
8491                }
8492            }
8493        }
8494
8495        return errList;
8496    }
8497
8498    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8499        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8500            if (currApp != null) {
8501                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8502            }
8503            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8504        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8505            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8506        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8507            if (currApp != null) {
8508                currApp.lru = 0;
8509            }
8510            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8511        } else if (adj >= ProcessList.SERVICE_ADJ) {
8512            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8513        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8514            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8515        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8516            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8517        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8518            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8519        } else {
8520            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8521        }
8522    }
8523
8524    private void fillInProcMemInfo(ProcessRecord app,
8525            ActivityManager.RunningAppProcessInfo outInfo) {
8526        outInfo.pid = app.pid;
8527        outInfo.uid = app.info.uid;
8528        if (mHeavyWeightProcess == app) {
8529            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8530        }
8531        if (app.persistent) {
8532            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8533        }
8534        if (app.hasActivities) {
8535            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8536        }
8537        outInfo.lastTrimLevel = app.trimMemoryLevel;
8538        int adj = app.curAdj;
8539        outInfo.importance = oomAdjToImportance(adj, outInfo);
8540        outInfo.importanceReasonCode = app.adjTypeCode;
8541    }
8542
8543    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8544        enforceNotIsolatedCaller("getRunningAppProcesses");
8545        // Lazy instantiation of list
8546        List<ActivityManager.RunningAppProcessInfo> runList = null;
8547        final boolean allUsers = ActivityManager.checkUidPermission(
8548                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8549                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8550        int userId = UserHandle.getUserId(Binder.getCallingUid());
8551        synchronized (this) {
8552            // Iterate across all processes
8553            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8554                ProcessRecord app = mLruProcesses.get(i);
8555                if (!allUsers && app.userId != userId) {
8556                    continue;
8557                }
8558                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8559                    // Generate process state info for running application
8560                    ActivityManager.RunningAppProcessInfo currApp =
8561                        new ActivityManager.RunningAppProcessInfo(app.processName,
8562                                app.pid, app.getPackageList());
8563                    fillInProcMemInfo(app, currApp);
8564                    if (app.adjSource instanceof ProcessRecord) {
8565                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8566                        currApp.importanceReasonImportance = oomAdjToImportance(
8567                                app.adjSourceOom, null);
8568                    } else if (app.adjSource instanceof ActivityRecord) {
8569                        ActivityRecord r = (ActivityRecord)app.adjSource;
8570                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8571                    }
8572                    if (app.adjTarget instanceof ComponentName) {
8573                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8574                    }
8575                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8576                    //        + " lru=" + currApp.lru);
8577                    if (runList == null) {
8578                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8579                    }
8580                    runList.add(currApp);
8581                }
8582            }
8583        }
8584        return runList;
8585    }
8586
8587    public List<ApplicationInfo> getRunningExternalApplications() {
8588        enforceNotIsolatedCaller("getRunningExternalApplications");
8589        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8590        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8591        if (runningApps != null && runningApps.size() > 0) {
8592            Set<String> extList = new HashSet<String>();
8593            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8594                if (app.pkgList != null) {
8595                    for (String pkg : app.pkgList) {
8596                        extList.add(pkg);
8597                    }
8598                }
8599            }
8600            IPackageManager pm = AppGlobals.getPackageManager();
8601            for (String pkg : extList) {
8602                try {
8603                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8604                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8605                        retList.add(info);
8606                    }
8607                } catch (RemoteException e) {
8608                }
8609            }
8610        }
8611        return retList;
8612    }
8613
8614    @Override
8615    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8616        enforceNotIsolatedCaller("getMyMemoryState");
8617        synchronized (this) {
8618            ProcessRecord proc;
8619            synchronized (mPidsSelfLocked) {
8620                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8621            }
8622            fillInProcMemInfo(proc, outInfo);
8623        }
8624    }
8625
8626    @Override
8627    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8628        if (checkCallingPermission(android.Manifest.permission.DUMP)
8629                != PackageManager.PERMISSION_GRANTED) {
8630            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8631                    + Binder.getCallingPid()
8632                    + ", uid=" + Binder.getCallingUid()
8633                    + " without permission "
8634                    + android.Manifest.permission.DUMP);
8635            return;
8636        }
8637
8638        boolean dumpAll = false;
8639        boolean dumpClient = false;
8640        String dumpPackage = null;
8641
8642        int opti = 0;
8643        while (opti < args.length) {
8644            String opt = args[opti];
8645            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8646                break;
8647            }
8648            opti++;
8649            if ("-a".equals(opt)) {
8650                dumpAll = true;
8651            } else if ("-c".equals(opt)) {
8652                dumpClient = true;
8653            } else if ("-h".equals(opt)) {
8654                pw.println("Activity manager dump options:");
8655                pw.println("  [-a] [-c] [-h] [cmd] ...");
8656                pw.println("  cmd may be one of:");
8657                pw.println("    a[ctivities]: activity stack state");
8658                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8659                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8660                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8661                pw.println("    o[om]: out of memory management");
8662                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8663                pw.println("    provider [COMP_SPEC]: provider client-side state");
8664                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8665                pw.println("    service [COMP_SPEC]: service client-side state");
8666                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8667                pw.println("    all: dump all activities");
8668                pw.println("    top: dump the top activity");
8669                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8670                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8671                pw.println("    a partial substring in a component name, a");
8672                pw.println("    hex object identifier.");
8673                pw.println("  -a: include all available server state.");
8674                pw.println("  -c: include client state.");
8675                return;
8676            } else {
8677                pw.println("Unknown argument: " + opt + "; use -h for help");
8678            }
8679        }
8680
8681        long origId = Binder.clearCallingIdentity();
8682        boolean more = false;
8683        // Is the caller requesting to dump a particular piece of data?
8684        if (opti < args.length) {
8685            String cmd = args[opti];
8686            opti++;
8687            if ("activities".equals(cmd) || "a".equals(cmd)) {
8688                synchronized (this) {
8689                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8690                }
8691            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8692                String[] newArgs;
8693                String name;
8694                if (opti >= args.length) {
8695                    name = null;
8696                    newArgs = EMPTY_STRING_ARRAY;
8697                } else {
8698                    name = args[opti];
8699                    opti++;
8700                    newArgs = new String[args.length - opti];
8701                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8702                            args.length - opti);
8703                }
8704                synchronized (this) {
8705                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8706                }
8707            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8708                String[] newArgs;
8709                String name;
8710                if (opti >= args.length) {
8711                    name = null;
8712                    newArgs = EMPTY_STRING_ARRAY;
8713                } else {
8714                    name = args[opti];
8715                    opti++;
8716                    newArgs = new String[args.length - opti];
8717                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8718                            args.length - opti);
8719                }
8720                synchronized (this) {
8721                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8722                }
8723            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8724                String[] newArgs;
8725                String name;
8726                if (opti >= args.length) {
8727                    name = null;
8728                    newArgs = EMPTY_STRING_ARRAY;
8729                } else {
8730                    name = args[opti];
8731                    opti++;
8732                    newArgs = new String[args.length - opti];
8733                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8734                            args.length - opti);
8735                }
8736                synchronized (this) {
8737                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8738                }
8739            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8740                synchronized (this) {
8741                    dumpOomLocked(fd, pw, args, opti, true);
8742                }
8743            } else if ("provider".equals(cmd)) {
8744                String[] newArgs;
8745                String name;
8746                if (opti >= args.length) {
8747                    name = null;
8748                    newArgs = EMPTY_STRING_ARRAY;
8749                } else {
8750                    name = args[opti];
8751                    opti++;
8752                    newArgs = new String[args.length - opti];
8753                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8754                }
8755                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8756                    pw.println("No providers match: " + name);
8757                    pw.println("Use -h for help.");
8758                }
8759            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8760                synchronized (this) {
8761                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8762                }
8763            } else if ("service".equals(cmd)) {
8764                String[] newArgs;
8765                String name;
8766                if (opti >= args.length) {
8767                    name = null;
8768                    newArgs = EMPTY_STRING_ARRAY;
8769                } else {
8770                    name = args[opti];
8771                    opti++;
8772                    newArgs = new String[args.length - opti];
8773                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8774                            args.length - opti);
8775                }
8776                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8777                    pw.println("No services match: " + name);
8778                    pw.println("Use -h for help.");
8779                }
8780            } else if ("package".equals(cmd)) {
8781                String[] newArgs;
8782                if (opti >= args.length) {
8783                    pw.println("package: no package name specified");
8784                    pw.println("Use -h for help.");
8785                } else {
8786                    dumpPackage = args[opti];
8787                    opti++;
8788                    newArgs = new String[args.length - opti];
8789                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8790                            args.length - opti);
8791                    args = newArgs;
8792                    opti = 0;
8793                    more = true;
8794                }
8795            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8796                synchronized (this) {
8797                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8798                }
8799            } else {
8800                // Dumping a single activity?
8801                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8802                    pw.println("Bad activity command, or no activities match: " + cmd);
8803                    pw.println("Use -h for help.");
8804                }
8805            }
8806            if (!more) {
8807                Binder.restoreCallingIdentity(origId);
8808                return;
8809            }
8810        }
8811
8812        // No piece of data specified, dump everything.
8813        synchronized (this) {
8814            boolean needSep;
8815            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8816            if (needSep) {
8817                pw.println(" ");
8818            }
8819            if (dumpAll) {
8820                pw.println("-------------------------------------------------------------------------------");
8821            }
8822            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8823            if (needSep) {
8824                pw.println(" ");
8825            }
8826            if (dumpAll) {
8827                pw.println("-------------------------------------------------------------------------------");
8828            }
8829            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8830            if (needSep) {
8831                pw.println(" ");
8832            }
8833            if (dumpAll) {
8834                pw.println("-------------------------------------------------------------------------------");
8835            }
8836            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8837            if (needSep) {
8838                pw.println(" ");
8839            }
8840            if (dumpAll) {
8841                pw.println("-------------------------------------------------------------------------------");
8842            }
8843            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8844            if (needSep) {
8845                pw.println(" ");
8846            }
8847            if (dumpAll) {
8848                pw.println("-------------------------------------------------------------------------------");
8849            }
8850            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8851        }
8852        Binder.restoreCallingIdentity(origId);
8853    }
8854
8855    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8856            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8857        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8858        pw.println("  Main stack:");
8859        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8860                dumpPackage);
8861        pw.println(" ");
8862        pw.println("  Running activities (most recent first):");
8863        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8864                dumpPackage);
8865        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8866            pw.println(" ");
8867            pw.println("  Activities waiting for another to become visible:");
8868            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8869                    !dumpAll, false, dumpPackage);
8870        }
8871        if (mMainStack.mStoppingActivities.size() > 0) {
8872            pw.println(" ");
8873            pw.println("  Activities waiting to stop:");
8874            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8875                    !dumpAll, false, dumpPackage);
8876        }
8877        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8878            pw.println(" ");
8879            pw.println("  Activities waiting to sleep:");
8880            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8881                    !dumpAll, false, dumpPackage);
8882        }
8883        if (mMainStack.mFinishingActivities.size() > 0) {
8884            pw.println(" ");
8885            pw.println("  Activities waiting to finish:");
8886            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8887                    !dumpAll, false, dumpPackage);
8888        }
8889
8890        pw.println(" ");
8891        if (mMainStack.mPausingActivity != null) {
8892            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8893        }
8894        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8895        pw.println("  mFocusedActivity: " + mFocusedActivity);
8896        if (dumpAll) {
8897            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8898            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8899            pw.println("  mDismissKeyguardOnNextActivity: "
8900                    + mMainStack.mDismissKeyguardOnNextActivity);
8901        }
8902
8903        if (mRecentTasks.size() > 0) {
8904            pw.println();
8905            pw.println("  Recent tasks:");
8906
8907            final int N = mRecentTasks.size();
8908            for (int i=0; i<N; i++) {
8909                TaskRecord tr = mRecentTasks.get(i);
8910                if (dumpPackage != null) {
8911                    if (tr.realActivity == null ||
8912                            !dumpPackage.equals(tr.realActivity)) {
8913                        continue;
8914                    }
8915                }
8916                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8917                        pw.println(tr);
8918                if (dumpAll) {
8919                    mRecentTasks.get(i).dump(pw, "    ");
8920                }
8921            }
8922        }
8923
8924        if (dumpAll) {
8925            pw.println(" ");
8926            pw.println("  mCurTask: " + mCurTask);
8927        }
8928
8929        return true;
8930    }
8931
8932    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8933            int opti, boolean dumpAll, String dumpPackage) {
8934        boolean needSep = false;
8935        int numPers = 0;
8936
8937        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8938
8939        if (dumpAll) {
8940            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8941                final int NA = procs.size();
8942                for (int ia=0; ia<NA; ia++) {
8943                    ProcessRecord r = procs.valueAt(ia);
8944                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8945                        continue;
8946                    }
8947                    if (!needSep) {
8948                        pw.println("  All known processes:");
8949                        needSep = true;
8950                    }
8951                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8952                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8953                        pw.print(" "); pw.println(r);
8954                    r.dump(pw, "    ");
8955                    if (r.persistent) {
8956                        numPers++;
8957                    }
8958                }
8959            }
8960        }
8961
8962        if (mIsolatedProcesses.size() > 0) {
8963            if (needSep) pw.println(" ");
8964            needSep = true;
8965            pw.println("  Isolated process list (sorted by uid):");
8966            for (int i=0; i<mIsolatedProcesses.size(); i++) {
8967                ProcessRecord r = mIsolatedProcesses.valueAt(i);
8968                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8969                    continue;
8970                }
8971                pw.println(String.format("%sIsolated #%2d: %s",
8972                        "    ", i, r.toString()));
8973            }
8974        }
8975
8976        if (mLruProcesses.size() > 0) {
8977            if (needSep) pw.println(" ");
8978            needSep = true;
8979            pw.println("  Process LRU list (sorted by oom_adj):");
8980            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8981                    "Proc", "PERS", false, dumpPackage);
8982            needSep = true;
8983        }
8984
8985        if (dumpAll) {
8986            synchronized (mPidsSelfLocked) {
8987                boolean printed = false;
8988                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8989                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8990                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8991                        continue;
8992                    }
8993                    if (!printed) {
8994                        if (needSep) pw.println(" ");
8995                        needSep = true;
8996                        pw.println("  PID mappings:");
8997                        printed = true;
8998                    }
8999                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9000                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9001                }
9002            }
9003        }
9004
9005        if (mForegroundProcesses.size() > 0) {
9006            synchronized (mPidsSelfLocked) {
9007                boolean printed = false;
9008                for (int i=0; i<mForegroundProcesses.size(); i++) {
9009                    ProcessRecord r = mPidsSelfLocked.get(
9010                            mForegroundProcesses.valueAt(i).pid);
9011                    if (dumpPackage != null && (r == null
9012                            || !dumpPackage.equals(r.info.packageName))) {
9013                        continue;
9014                    }
9015                    if (!printed) {
9016                        if (needSep) pw.println(" ");
9017                        needSep = true;
9018                        pw.println("  Foreground Processes:");
9019                        printed = true;
9020                    }
9021                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9022                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9023                }
9024            }
9025        }
9026
9027        if (mPersistentStartingProcesses.size() > 0) {
9028            if (needSep) pw.println(" ");
9029            needSep = true;
9030            pw.println("  Persisent processes that are starting:");
9031            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9032                    "Starting Norm", "Restarting PERS", dumpPackage);
9033        }
9034
9035        if (mRemovedProcesses.size() > 0) {
9036            if (needSep) pw.println(" ");
9037            needSep = true;
9038            pw.println("  Processes that are being removed:");
9039            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9040                    "Removed Norm", "Removed PERS", dumpPackage);
9041        }
9042
9043        if (mProcessesOnHold.size() > 0) {
9044            if (needSep) pw.println(" ");
9045            needSep = true;
9046            pw.println("  Processes that are on old until the system is ready:");
9047            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9048                    "OnHold Norm", "OnHold PERS", dumpPackage);
9049        }
9050
9051        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9052
9053        if (mProcessCrashTimes.getMap().size() > 0) {
9054            boolean printed = false;
9055            long now = SystemClock.uptimeMillis();
9056            for (Map.Entry<String, SparseArray<Long>> procs
9057                    : mProcessCrashTimes.getMap().entrySet()) {
9058                String pname = procs.getKey();
9059                SparseArray<Long> uids = procs.getValue();
9060                final int N = uids.size();
9061                for (int i=0; i<N; i++) {
9062                    int puid = uids.keyAt(i);
9063                    ProcessRecord r = mProcessNames.get(pname, puid);
9064                    if (dumpPackage != null && (r == null
9065                            || !dumpPackage.equals(r.info.packageName))) {
9066                        continue;
9067                    }
9068                    if (!printed) {
9069                        if (needSep) pw.println(" ");
9070                        needSep = true;
9071                        pw.println("  Time since processes crashed:");
9072                        printed = true;
9073                    }
9074                    pw.print("    Process "); pw.print(pname);
9075                            pw.print(" uid "); pw.print(puid);
9076                            pw.print(": last crashed ");
9077                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9078                            pw.println(" ago");
9079                }
9080            }
9081        }
9082
9083        if (mBadProcesses.getMap().size() > 0) {
9084            boolean printed = false;
9085            for (Map.Entry<String, SparseArray<Long>> procs
9086                    : mBadProcesses.getMap().entrySet()) {
9087                String pname = procs.getKey();
9088                SparseArray<Long> uids = procs.getValue();
9089                final int N = uids.size();
9090                for (int i=0; i<N; i++) {
9091                    int puid = uids.keyAt(i);
9092                    ProcessRecord r = mProcessNames.get(pname, puid);
9093                    if (dumpPackage != null && (r == null
9094                            || !dumpPackage.equals(r.info.packageName))) {
9095                        continue;
9096                    }
9097                    if (!printed) {
9098                        if (needSep) pw.println(" ");
9099                        needSep = true;
9100                        pw.println("  Bad processes:");
9101                    }
9102                    pw.print("    Bad process "); pw.print(pname);
9103                            pw.print(" uid "); pw.print(puid);
9104                            pw.print(": crashed at time ");
9105                            pw.println(uids.valueAt(i));
9106                }
9107            }
9108        }
9109
9110        pw.println();
9111        pw.println("  mStartedUsers:");
9112        for (int i=0; i<mStartedUsers.size(); i++) {
9113            UserStartedState uss = mStartedUsers.valueAt(i);
9114            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9115                    pw.println(":");
9116            uss.dump("      ", pw);
9117        }
9118        pw.println("  mHomeProcess: " + mHomeProcess);
9119        pw.println("  mPreviousProcess: " + mPreviousProcess);
9120        if (dumpAll) {
9121            StringBuilder sb = new StringBuilder(128);
9122            sb.append("  mPreviousProcessVisibleTime: ");
9123            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9124            pw.println(sb);
9125        }
9126        if (mHeavyWeightProcess != null) {
9127            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9128        }
9129        pw.println("  mConfiguration: " + mConfiguration);
9130        if (dumpAll) {
9131            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9132            if (mCompatModePackages.getPackages().size() > 0) {
9133                boolean printed = false;
9134                for (Map.Entry<String, Integer> entry
9135                        : mCompatModePackages.getPackages().entrySet()) {
9136                    String pkg = entry.getKey();
9137                    int mode = entry.getValue();
9138                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9139                        continue;
9140                    }
9141                    if (!printed) {
9142                        pw.println("  mScreenCompatPackages:");
9143                        printed = true;
9144                    }
9145                    pw.print("    "); pw.print(pkg); pw.print(": ");
9146                            pw.print(mode); pw.println();
9147                }
9148            }
9149        }
9150        if (mSleeping || mWentToSleep || mLockScreenShown) {
9151            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9152                    + " mLockScreenShown " + mLockScreenShown);
9153        }
9154        if (mShuttingDown) {
9155            pw.println("  mShuttingDown=" + mShuttingDown);
9156        }
9157        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9158                || mOrigWaitForDebugger) {
9159            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9160                    + " mDebugTransient=" + mDebugTransient
9161                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9162        }
9163        if (mOpenGlTraceApp != null) {
9164            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9165        }
9166        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9167                || mProfileFd != null) {
9168            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9169            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9170            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9171                    + mAutoStopProfiler);
9172        }
9173        if (mAlwaysFinishActivities || mController != null) {
9174            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9175                    + " mController=" + mController);
9176        }
9177        if (dumpAll) {
9178            pw.println("  Total persistent processes: " + numPers);
9179            pw.println("  mStartRunning=" + mStartRunning
9180                    + " mProcessesReady=" + mProcessesReady
9181                    + " mSystemReady=" + mSystemReady);
9182            pw.println("  mBooting=" + mBooting
9183                    + " mBooted=" + mBooted
9184                    + " mFactoryTest=" + mFactoryTest);
9185            pw.print("  mLastPowerCheckRealtime=");
9186                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9187                    pw.println("");
9188            pw.print("  mLastPowerCheckUptime=");
9189                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9190                    pw.println("");
9191            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9192            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9193            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9194            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9195                    + " mNumHiddenProcs=" + mNumHiddenProcs
9196                    + " mNumServiceProcs=" + mNumServiceProcs
9197                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9198        }
9199
9200        return true;
9201    }
9202
9203    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9204            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9205        if (mProcessesToGc.size() > 0) {
9206            boolean printed = false;
9207            long now = SystemClock.uptimeMillis();
9208            for (int i=0; i<mProcessesToGc.size(); i++) {
9209                ProcessRecord proc = mProcessesToGc.get(i);
9210                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9211                    continue;
9212                }
9213                if (!printed) {
9214                    if (needSep) pw.println(" ");
9215                    needSep = true;
9216                    pw.println("  Processes that are waiting to GC:");
9217                    printed = true;
9218                }
9219                pw.print("    Process "); pw.println(proc);
9220                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9221                        pw.print(", last gced=");
9222                        pw.print(now-proc.lastRequestedGc);
9223                        pw.print(" ms ago, last lowMem=");
9224                        pw.print(now-proc.lastLowMemory);
9225                        pw.println(" ms ago");
9226
9227            }
9228        }
9229        return needSep;
9230    }
9231
9232    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9233            int opti, boolean dumpAll) {
9234        boolean needSep = false;
9235
9236        if (mLruProcesses.size() > 0) {
9237            if (needSep) pw.println(" ");
9238            needSep = true;
9239            pw.println("  OOM levels:");
9240            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9241            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9242            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9243            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9244            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9245            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9246            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9247            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9248            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9249            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9250            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9251            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9252            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9253
9254            if (needSep) pw.println(" ");
9255            needSep = true;
9256            pw.println("  Process OOM control:");
9257            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9258                    "Proc", "PERS", true, null);
9259            needSep = true;
9260        }
9261
9262        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9263
9264        pw.println();
9265        pw.println("  mHomeProcess: " + mHomeProcess);
9266        pw.println("  mPreviousProcess: " + mPreviousProcess);
9267        if (mHeavyWeightProcess != null) {
9268            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9269        }
9270
9271        return true;
9272    }
9273
9274    /**
9275     * There are three ways to call this:
9276     *  - no provider specified: dump all the providers
9277     *  - a flattened component name that matched an existing provider was specified as the
9278     *    first arg: dump that one provider
9279     *  - the first arg isn't the flattened component name of an existing provider:
9280     *    dump all providers whose component contains the first arg as a substring
9281     */
9282    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9283            int opti, boolean dumpAll) {
9284        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9285    }
9286
9287    static class ItemMatcher {
9288        ArrayList<ComponentName> components;
9289        ArrayList<String> strings;
9290        ArrayList<Integer> objects;
9291        boolean all;
9292
9293        ItemMatcher() {
9294            all = true;
9295        }
9296
9297        void build(String name) {
9298            ComponentName componentName = ComponentName.unflattenFromString(name);
9299            if (componentName != null) {
9300                if (components == null) {
9301                    components = new ArrayList<ComponentName>();
9302                }
9303                components.add(componentName);
9304                all = false;
9305            } else {
9306                int objectId = 0;
9307                // Not a '/' separated full component name; maybe an object ID?
9308                try {
9309                    objectId = Integer.parseInt(name, 16);
9310                    if (objects == null) {
9311                        objects = new ArrayList<Integer>();
9312                    }
9313                    objects.add(objectId);
9314                    all = false;
9315                } catch (RuntimeException e) {
9316                    // Not an integer; just do string match.
9317                    if (strings == null) {
9318                        strings = new ArrayList<String>();
9319                    }
9320                    strings.add(name);
9321                    all = false;
9322                }
9323            }
9324        }
9325
9326        int build(String[] args, int opti) {
9327            for (; opti<args.length; opti++) {
9328                String name = args[opti];
9329                if ("--".equals(name)) {
9330                    return opti+1;
9331                }
9332                build(name);
9333            }
9334            return opti;
9335        }
9336
9337        boolean match(Object object, ComponentName comp) {
9338            if (all) {
9339                return true;
9340            }
9341            if (components != null) {
9342                for (int i=0; i<components.size(); i++) {
9343                    if (components.get(i).equals(comp)) {
9344                        return true;
9345                    }
9346                }
9347            }
9348            if (objects != null) {
9349                for (int i=0; i<objects.size(); i++) {
9350                    if (System.identityHashCode(object) == objects.get(i)) {
9351                        return true;
9352                    }
9353                }
9354            }
9355            if (strings != null) {
9356                String flat = comp.flattenToString();
9357                for (int i=0; i<strings.size(); i++) {
9358                    if (flat.contains(strings.get(i))) {
9359                        return true;
9360                    }
9361                }
9362            }
9363            return false;
9364        }
9365    }
9366
9367    /**
9368     * There are three things that cmd can be:
9369     *  - a flattened component name that matches an existing activity
9370     *  - the cmd arg isn't the flattened component name of an existing activity:
9371     *    dump all activity whose component contains the cmd as a substring
9372     *  - A hex number of the ActivityRecord object instance.
9373     */
9374    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9375            int opti, boolean dumpAll) {
9376        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9377
9378        if ("all".equals(name)) {
9379            synchronized (this) {
9380                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9381                    activities.add(r1);
9382                }
9383            }
9384        } else if ("top".equals(name)) {
9385            synchronized (this) {
9386                final int N = mMainStack.mHistory.size();
9387                if (N > 0) {
9388                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9389                }
9390            }
9391        } else {
9392            ItemMatcher matcher = new ItemMatcher();
9393            matcher.build(name);
9394
9395            synchronized (this) {
9396                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9397                    if (matcher.match(r1, r1.intent.getComponent())) {
9398                        activities.add(r1);
9399                    }
9400                }
9401            }
9402        }
9403
9404        if (activities.size() <= 0) {
9405            return false;
9406        }
9407
9408        String[] newArgs = new String[args.length - opti];
9409        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9410
9411        TaskRecord lastTask = null;
9412        boolean needSep = false;
9413        for (int i=activities.size()-1; i>=0; i--) {
9414            ActivityRecord r = (ActivityRecord)activities.get(i);
9415            if (needSep) {
9416                pw.println();
9417            }
9418            needSep = true;
9419            synchronized (this) {
9420                if (lastTask != r.task) {
9421                    lastTask = r.task;
9422                    pw.print("TASK "); pw.print(lastTask.affinity);
9423                            pw.print(" id="); pw.println(lastTask.taskId);
9424                    if (dumpAll) {
9425                        lastTask.dump(pw, "  ");
9426                    }
9427                }
9428            }
9429            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9430        }
9431        return true;
9432    }
9433
9434    /**
9435     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9436     * there is a thread associated with the activity.
9437     */
9438    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9439            final ActivityRecord r, String[] args, boolean dumpAll) {
9440        String innerPrefix = prefix + "  ";
9441        synchronized (this) {
9442            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9443                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9444                    pw.print(" pid=");
9445                    if (r.app != null) pw.println(r.app.pid);
9446                    else pw.println("(not running)");
9447            if (dumpAll) {
9448                r.dump(pw, innerPrefix);
9449            }
9450        }
9451        if (r.app != null && r.app.thread != null) {
9452            // flush anything that is already in the PrintWriter since the thread is going
9453            // to write to the file descriptor directly
9454            pw.flush();
9455            try {
9456                TransferPipe tp = new TransferPipe();
9457                try {
9458                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9459                            r.appToken, innerPrefix, args);
9460                    tp.go(fd);
9461                } finally {
9462                    tp.kill();
9463                }
9464            } catch (IOException e) {
9465                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9466            } catch (RemoteException e) {
9467                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9468            }
9469        }
9470    }
9471
9472    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9473            int opti, boolean dumpAll, String dumpPackage) {
9474        boolean needSep = false;
9475        boolean onlyHistory = false;
9476
9477        if ("history".equals(dumpPackage)) {
9478            onlyHistory = true;
9479            dumpPackage = null;
9480        }
9481
9482        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9483        if (!onlyHistory && dumpAll) {
9484            if (mRegisteredReceivers.size() > 0) {
9485                boolean printed = false;
9486                Iterator it = mRegisteredReceivers.values().iterator();
9487                while (it.hasNext()) {
9488                    ReceiverList r = (ReceiverList)it.next();
9489                    if (dumpPackage != null && (r.app == null ||
9490                            !dumpPackage.equals(r.app.info.packageName))) {
9491                        continue;
9492                    }
9493                    if (!printed) {
9494                        pw.println("  Registered Receivers:");
9495                        needSep = true;
9496                        printed = true;
9497                    }
9498                    pw.print("  * "); pw.println(r);
9499                    r.dump(pw, "    ");
9500                }
9501            }
9502
9503            if (mReceiverResolver.dump(pw, needSep ?
9504                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9505                    "    ", dumpPackage, false)) {
9506                needSep = true;
9507            }
9508        }
9509
9510        for (BroadcastQueue q : mBroadcastQueues) {
9511            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9512        }
9513
9514        needSep = true;
9515
9516        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9517            if (needSep) {
9518                pw.println();
9519            }
9520            needSep = true;
9521            pw.println("  Sticky broadcasts:");
9522            StringBuilder sb = new StringBuilder(128);
9523            for (Map.Entry<String, ArrayList<Intent>> ent
9524                    : mStickyBroadcasts.entrySet()) {
9525                pw.print("  * Sticky action "); pw.print(ent.getKey());
9526                if (dumpAll) {
9527                    pw.println(":");
9528                    ArrayList<Intent> intents = ent.getValue();
9529                    final int N = intents.size();
9530                    for (int i=0; i<N; i++) {
9531                        sb.setLength(0);
9532                        sb.append("    Intent: ");
9533                        intents.get(i).toShortString(sb, false, true, false, false);
9534                        pw.println(sb.toString());
9535                        Bundle bundle = intents.get(i).getExtras();
9536                        if (bundle != null) {
9537                            pw.print("      ");
9538                            pw.println(bundle.toString());
9539                        }
9540                    }
9541                } else {
9542                    pw.println("");
9543                }
9544            }
9545            needSep = true;
9546        }
9547
9548        if (!onlyHistory && dumpAll) {
9549            pw.println();
9550            for (BroadcastQueue queue : mBroadcastQueues) {
9551                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9552                        + queue.mBroadcastsScheduled);
9553            }
9554            pw.println("  mHandler:");
9555            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9556            needSep = true;
9557        }
9558
9559        return needSep;
9560    }
9561
9562    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9563            int opti, boolean dumpAll, String dumpPackage) {
9564        boolean needSep = true;
9565
9566        ItemMatcher matcher = new ItemMatcher();
9567        matcher.build(args, opti);
9568
9569        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9570
9571        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9572
9573        if (mLaunchingProviders.size() > 0) {
9574            boolean printed = false;
9575            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9576                ContentProviderRecord r = mLaunchingProviders.get(i);
9577                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9578                    continue;
9579                }
9580                if (!printed) {
9581                    if (needSep) pw.println(" ");
9582                    needSep = true;
9583                    pw.println("  Launching content providers:");
9584                    printed = true;
9585                }
9586                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9587                        pw.println(r);
9588            }
9589        }
9590
9591        if (mGrantedUriPermissions.size() > 0) {
9592            if (needSep) pw.println();
9593            needSep = true;
9594            pw.println("Granted Uri Permissions:");
9595            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9596                int uid = mGrantedUriPermissions.keyAt(i);
9597                HashMap<Uri, UriPermission> perms
9598                        = mGrantedUriPermissions.valueAt(i);
9599                pw.print("  * UID "); pw.print(uid);
9600                        pw.println(" holds:");
9601                for (UriPermission perm : perms.values()) {
9602                    pw.print("    "); pw.println(perm);
9603                    if (dumpAll) {
9604                        perm.dump(pw, "      ");
9605                    }
9606                }
9607            }
9608            needSep = true;
9609        }
9610
9611        return needSep;
9612    }
9613
9614    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9615            int opti, boolean dumpAll, String dumpPackage) {
9616        boolean needSep = false;
9617
9618        if (mIntentSenderRecords.size() > 0) {
9619            boolean printed = false;
9620            Iterator<WeakReference<PendingIntentRecord>> it
9621                    = mIntentSenderRecords.values().iterator();
9622            while (it.hasNext()) {
9623                WeakReference<PendingIntentRecord> ref = it.next();
9624                PendingIntentRecord rec = ref != null ? ref.get(): null;
9625                if (dumpPackage != null && (rec == null
9626                        || !dumpPackage.equals(rec.key.packageName))) {
9627                    continue;
9628                }
9629                if (!printed) {
9630                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9631                    printed = true;
9632                }
9633                needSep = true;
9634                if (rec != null) {
9635                    pw.print("  * "); pw.println(rec);
9636                    if (dumpAll) {
9637                        rec.dump(pw, "    ");
9638                    }
9639                } else {
9640                    pw.print("  * "); pw.println(ref);
9641                }
9642            }
9643        }
9644
9645        return needSep;
9646    }
9647
9648    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9649            String prefix, String label, boolean complete, boolean brief, boolean client,
9650            String dumpPackage) {
9651        TaskRecord lastTask = null;
9652        boolean needNL = false;
9653        final String innerPrefix = prefix + "      ";
9654        final String[] args = new String[0];
9655        for (int i=list.size()-1; i>=0; i--) {
9656            final ActivityRecord r = (ActivityRecord)list.get(i);
9657            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9658                continue;
9659            }
9660            final boolean full = !brief && (complete || !r.isInHistory());
9661            if (needNL) {
9662                pw.println(" ");
9663                needNL = false;
9664            }
9665            if (lastTask != r.task) {
9666                lastTask = r.task;
9667                pw.print(prefix);
9668                pw.print(full ? "* " : "  ");
9669                pw.println(lastTask);
9670                if (full) {
9671                    lastTask.dump(pw, prefix + "  ");
9672                } else if (complete) {
9673                    // Complete + brief == give a summary.  Isn't that obvious?!?
9674                    if (lastTask.intent != null) {
9675                        pw.print(prefix); pw.print("  ");
9676                                pw.println(lastTask.intent.toInsecureStringWithClip());
9677                    }
9678                }
9679            }
9680            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9681            pw.print(" #"); pw.print(i); pw.print(": ");
9682            pw.println(r);
9683            if (full) {
9684                r.dump(pw, innerPrefix);
9685            } else if (complete) {
9686                // Complete + brief == give a summary.  Isn't that obvious?!?
9687                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9688                if (r.app != null) {
9689                    pw.print(innerPrefix); pw.println(r.app);
9690                }
9691            }
9692            if (client && r.app != null && r.app.thread != null) {
9693                // flush anything that is already in the PrintWriter since the thread is going
9694                // to write to the file descriptor directly
9695                pw.flush();
9696                try {
9697                    TransferPipe tp = new TransferPipe();
9698                    try {
9699                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9700                                r.appToken, innerPrefix, args);
9701                        // Short timeout, since blocking here can
9702                        // deadlock with the application.
9703                        tp.go(fd, 2000);
9704                    } finally {
9705                        tp.kill();
9706                    }
9707                } catch (IOException e) {
9708                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9709                } catch (RemoteException e) {
9710                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9711                }
9712                needNL = true;
9713            }
9714        }
9715    }
9716
9717    private static String buildOomTag(String prefix, String space, int val, int base) {
9718        if (val == base) {
9719            if (space == null) return prefix;
9720            return prefix + "  ";
9721        }
9722        return prefix + "+" + Integer.toString(val-base);
9723    }
9724
9725    private static final int dumpProcessList(PrintWriter pw,
9726            ActivityManagerService service, List list,
9727            String prefix, String normalLabel, String persistentLabel,
9728            String dumpPackage) {
9729        int numPers = 0;
9730        final int N = list.size()-1;
9731        for (int i=N; i>=0; i--) {
9732            ProcessRecord r = (ProcessRecord)list.get(i);
9733            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9734                continue;
9735            }
9736            pw.println(String.format("%s%s #%2d: %s",
9737                    prefix, (r.persistent ? persistentLabel : normalLabel),
9738                    i, r.toString()));
9739            if (r.persistent) {
9740                numPers++;
9741            }
9742        }
9743        return numPers;
9744    }
9745
9746    private static final boolean dumpProcessOomList(PrintWriter pw,
9747            ActivityManagerService service, List<ProcessRecord> origList,
9748            String prefix, String normalLabel, String persistentLabel,
9749            boolean inclDetails, String dumpPackage) {
9750
9751        ArrayList<Pair<ProcessRecord, Integer>> list
9752                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9753        for (int i=0; i<origList.size(); i++) {
9754            ProcessRecord r = origList.get(i);
9755            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9756                continue;
9757            }
9758            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9759        }
9760
9761        if (list.size() <= 0) {
9762            return false;
9763        }
9764
9765        Comparator<Pair<ProcessRecord, Integer>> comparator
9766                = new Comparator<Pair<ProcessRecord, Integer>>() {
9767            @Override
9768            public int compare(Pair<ProcessRecord, Integer> object1,
9769                    Pair<ProcessRecord, Integer> object2) {
9770                if (object1.first.setAdj != object2.first.setAdj) {
9771                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9772                }
9773                if (object1.second.intValue() != object2.second.intValue()) {
9774                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9775                }
9776                return 0;
9777            }
9778        };
9779
9780        Collections.sort(list, comparator);
9781
9782        final long curRealtime = SystemClock.elapsedRealtime();
9783        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9784        final long curUptime = SystemClock.uptimeMillis();
9785        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9786
9787        for (int i=list.size()-1; i>=0; i--) {
9788            ProcessRecord r = list.get(i).first;
9789            String oomAdj;
9790            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9791                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9792            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9793                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9794            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9795                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9796            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9797                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9798            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9799                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9800            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9801                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9802            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9803                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9804            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9805                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9806            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9807                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9808            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9809                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9810            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9811                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9812            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9813                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9814            } else {
9815                oomAdj = Integer.toString(r.setAdj);
9816            }
9817            String schedGroup;
9818            switch (r.setSchedGroup) {
9819                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9820                    schedGroup = "B";
9821                    break;
9822                case Process.THREAD_GROUP_DEFAULT:
9823                    schedGroup = "F";
9824                    break;
9825                default:
9826                    schedGroup = Integer.toString(r.setSchedGroup);
9827                    break;
9828            }
9829            String foreground;
9830            if (r.foregroundActivities) {
9831                foreground = "A";
9832            } else if (r.foregroundServices) {
9833                foreground = "S";
9834            } else {
9835                foreground = " ";
9836            }
9837            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9838                    prefix, (r.persistent ? persistentLabel : normalLabel),
9839                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9840                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9841            if (r.adjSource != null || r.adjTarget != null) {
9842                pw.print(prefix);
9843                pw.print("    ");
9844                if (r.adjTarget instanceof ComponentName) {
9845                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9846                } else if (r.adjTarget != null) {
9847                    pw.print(r.adjTarget.toString());
9848                } else {
9849                    pw.print("{null}");
9850                }
9851                pw.print("<=");
9852                if (r.adjSource instanceof ProcessRecord) {
9853                    pw.print("Proc{");
9854                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9855                    pw.println("}");
9856                } else if (r.adjSource != null) {
9857                    pw.println(r.adjSource.toString());
9858                } else {
9859                    pw.println("{null}");
9860                }
9861            }
9862            if (inclDetails) {
9863                pw.print(prefix);
9864                pw.print("    ");
9865                pw.print("oom: max="); pw.print(r.maxAdj);
9866                pw.print(" hidden="); pw.print(r.hiddenAdj);
9867                pw.print(" empty="); pw.print(r.emptyAdj);
9868                pw.print(" curRaw="); pw.print(r.curRawAdj);
9869                pw.print(" setRaw="); pw.print(r.setRawAdj);
9870                pw.print(" cur="); pw.print(r.curAdj);
9871                pw.print(" set="); pw.println(r.setAdj);
9872                pw.print(prefix);
9873                pw.print("    ");
9874                pw.print("keeping="); pw.print(r.keeping);
9875                pw.print(" hidden="); pw.print(r.hidden);
9876                pw.print(" empty="); pw.print(r.empty);
9877                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9878
9879                if (!r.keeping) {
9880                    if (r.lastWakeTime != 0) {
9881                        long wtime;
9882                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9883                        synchronized (stats) {
9884                            wtime = stats.getProcessWakeTime(r.info.uid,
9885                                    r.pid, curRealtime);
9886                        }
9887                        long timeUsed = wtime - r.lastWakeTime;
9888                        pw.print(prefix);
9889                        pw.print("    ");
9890                        pw.print("keep awake over ");
9891                        TimeUtils.formatDuration(realtimeSince, pw);
9892                        pw.print(" used ");
9893                        TimeUtils.formatDuration(timeUsed, pw);
9894                        pw.print(" (");
9895                        pw.print((timeUsed*100)/realtimeSince);
9896                        pw.println("%)");
9897                    }
9898                    if (r.lastCpuTime != 0) {
9899                        long timeUsed = r.curCpuTime - r.lastCpuTime;
9900                        pw.print(prefix);
9901                        pw.print("    ");
9902                        pw.print("run cpu over ");
9903                        TimeUtils.formatDuration(uptimeSince, pw);
9904                        pw.print(" used ");
9905                        TimeUtils.formatDuration(timeUsed, pw);
9906                        pw.print(" (");
9907                        pw.print((timeUsed*100)/uptimeSince);
9908                        pw.println("%)");
9909                    }
9910                }
9911            }
9912        }
9913        return true;
9914    }
9915
9916    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
9917        ArrayList<ProcessRecord> procs;
9918        synchronized (this) {
9919            if (args != null && args.length > start
9920                    && args[start].charAt(0) != '-') {
9921                procs = new ArrayList<ProcessRecord>();
9922                int pid = -1;
9923                try {
9924                    pid = Integer.parseInt(args[start]);
9925                } catch (NumberFormatException e) {
9926
9927                }
9928                for (int i=mLruProcesses.size()-1; i>=0; i--) {
9929                    ProcessRecord proc = mLruProcesses.get(i);
9930                    if (proc.pid == pid) {
9931                        procs.add(proc);
9932                    } else if (proc.processName.equals(args[start])) {
9933                        procs.add(proc);
9934                    }
9935                }
9936                if (procs.size() <= 0) {
9937                    pw.println("No process found for: " + args[start]);
9938                    return null;
9939                }
9940            } else {
9941                procs = new ArrayList<ProcessRecord>(mLruProcesses);
9942            }
9943        }
9944        return procs;
9945    }
9946
9947    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9948            PrintWriter pw, String[] args) {
9949        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9950        if (procs == null) {
9951            return;
9952        }
9953
9954        long uptime = SystemClock.uptimeMillis();
9955        long realtime = SystemClock.elapsedRealtime();
9956        pw.println("Applications Graphics Acceleration Info:");
9957        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9958
9959        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9960            ProcessRecord r = procs.get(i);
9961            if (r.thread != null) {
9962                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9963                pw.flush();
9964                try {
9965                    TransferPipe tp = new TransferPipe();
9966                    try {
9967                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9968                        tp.go(fd);
9969                    } finally {
9970                        tp.kill();
9971                    }
9972                } catch (IOException e) {
9973                    pw.println("Failure while dumping the app: " + r);
9974                    pw.flush();
9975                } catch (RemoteException e) {
9976                    pw.println("Got a RemoteException while dumping the app " + r);
9977                    pw.flush();
9978                }
9979            }
9980        }
9981    }
9982
9983    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
9984        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9985        if (procs == null) {
9986            return;
9987        }
9988
9989        pw.println("Applications Database Info:");
9990
9991        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9992            ProcessRecord r = procs.get(i);
9993            if (r.thread != null) {
9994                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
9995                pw.flush();
9996                try {
9997                    TransferPipe tp = new TransferPipe();
9998                    try {
9999                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10000                        tp.go(fd);
10001                    } finally {
10002                        tp.kill();
10003                    }
10004                } catch (IOException e) {
10005                    pw.println("Failure while dumping the app: " + r);
10006                    pw.flush();
10007                } catch (RemoteException e) {
10008                    pw.println("Got a RemoteException while dumping the app " + r);
10009                    pw.flush();
10010                }
10011            }
10012        }
10013    }
10014
10015    final static class MemItem {
10016        final String label;
10017        final String shortLabel;
10018        final long pss;
10019        final int id;
10020        ArrayList<MemItem> subitems;
10021
10022        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10023            label = _label;
10024            shortLabel = _shortLabel;
10025            pss = _pss;
10026            id = _id;
10027        }
10028    }
10029
10030    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10031            boolean sort) {
10032        if (sort) {
10033            Collections.sort(items, new Comparator<MemItem>() {
10034                @Override
10035                public int compare(MemItem lhs, MemItem rhs) {
10036                    if (lhs.pss < rhs.pss) {
10037                        return 1;
10038                    } else if (lhs.pss > rhs.pss) {
10039                        return -1;
10040                    }
10041                    return 0;
10042                }
10043            });
10044        }
10045
10046        for (int i=0; i<items.size(); i++) {
10047            MemItem mi = items.get(i);
10048            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10049            if (mi.subitems != null) {
10050                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10051            }
10052        }
10053    }
10054
10055    // These are in KB.
10056    static final long[] DUMP_MEM_BUCKETS = new long[] {
10057        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10058        120*1024, 160*1024, 200*1024,
10059        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10060        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10061    };
10062
10063    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10064            boolean stackLike) {
10065        int start = label.lastIndexOf('.');
10066        if (start >= 0) start++;
10067        else start = 0;
10068        int end = label.length();
10069        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10070            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10071                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10072                out.append(bucket);
10073                out.append(stackLike ? "MB." : "MB ");
10074                out.append(label, start, end);
10075                return;
10076            }
10077        }
10078        out.append(memKB/1024);
10079        out.append(stackLike ? "MB." : "MB ");
10080        out.append(label, start, end);
10081    }
10082
10083    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10084            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10085            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10086            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10087            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10088    };
10089    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10090            "System", "Persistent", "Foreground",
10091            "Visible", "Perceptible", "Heavy Weight",
10092            "Backup", "A Services", "Home", "Previous",
10093            "B Services", "Background"
10094    };
10095
10096    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10097            PrintWriter pw, String prefix, String[] args, boolean brief,
10098            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10099        boolean dumpAll = false;
10100        boolean oomOnly = false;
10101
10102        int opti = 0;
10103        while (opti < args.length) {
10104            String opt = args[opti];
10105            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10106                break;
10107            }
10108            opti++;
10109            if ("-a".equals(opt)) {
10110                dumpAll = true;
10111            } else if ("--oom".equals(opt)) {
10112                oomOnly = true;
10113            } else if ("-h".equals(opt)) {
10114                pw.println("meminfo dump options: [-a] [--oom] [process]");
10115                pw.println("  -a: include all available information for each process.");
10116                pw.println("  --oom: only show processes organized by oom adj.");
10117                pw.println("If [process] is specified it can be the name or ");
10118                pw.println("pid of a specific process to dump.");
10119                return;
10120            } else {
10121                pw.println("Unknown argument: " + opt + "; use -h for help");
10122            }
10123        }
10124
10125        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10126        if (procs == null) {
10127            return;
10128        }
10129
10130        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10131        long uptime = SystemClock.uptimeMillis();
10132        long realtime = SystemClock.elapsedRealtime();
10133
10134        if (procs.size() == 1 || isCheckinRequest) {
10135            dumpAll = true;
10136        }
10137
10138        if (isCheckinRequest) {
10139            // short checkin version
10140            pw.println(uptime + "," + realtime);
10141            pw.flush();
10142        } else {
10143            pw.println("Applications Memory Usage (kB):");
10144            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10145        }
10146
10147        String[] innerArgs = new String[args.length-opti];
10148        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10149
10150        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10151        long nativePss=0, dalvikPss=0, otherPss=0;
10152        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10153
10154        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10155        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10156                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10157
10158        long totalPss = 0;
10159
10160        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10161            ProcessRecord r = procs.get(i);
10162            if (r.thread != null) {
10163                if (!isCheckinRequest && dumpAll) {
10164                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10165                    pw.flush();
10166                }
10167                Debug.MemoryInfo mi = null;
10168                if (dumpAll) {
10169                    try {
10170                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10171                    } catch (RemoteException e) {
10172                        if (!isCheckinRequest) {
10173                            pw.println("Got RemoteException!");
10174                            pw.flush();
10175                        }
10176                    }
10177                } else {
10178                    mi = new Debug.MemoryInfo();
10179                    Debug.getMemoryInfo(r.pid, mi);
10180                }
10181
10182                if (!isCheckinRequest && mi != null) {
10183                    long myTotalPss = mi.getTotalPss();
10184                    totalPss += myTotalPss;
10185                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10186                            r.processName, myTotalPss, 0);
10187                    procMems.add(pssItem);
10188
10189                    nativePss += mi.nativePss;
10190                    dalvikPss += mi.dalvikPss;
10191                    otherPss += mi.otherPss;
10192                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10193                        long mem = mi.getOtherPss(j);
10194                        miscPss[j] += mem;
10195                        otherPss -= mem;
10196                    }
10197
10198                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10199                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10200                                || oomIndex == (oomPss.length-1)) {
10201                            oomPss[oomIndex] += myTotalPss;
10202                            if (oomProcs[oomIndex] == null) {
10203                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10204                            }
10205                            oomProcs[oomIndex].add(pssItem);
10206                            break;
10207                        }
10208                    }
10209                }
10210            }
10211        }
10212
10213        if (!isCheckinRequest && procs.size() > 1) {
10214            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10215
10216            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10217            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10218            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10219            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10220                String label = Debug.MemoryInfo.getOtherLabel(j);
10221                catMems.add(new MemItem(label, label, miscPss[j], j));
10222            }
10223
10224            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10225            for (int j=0; j<oomPss.length; j++) {
10226                if (oomPss[j] != 0) {
10227                    String label = DUMP_MEM_OOM_LABEL[j];
10228                    MemItem item = new MemItem(label, label, oomPss[j],
10229                            DUMP_MEM_OOM_ADJ[j]);
10230                    item.subitems = oomProcs[j];
10231                    oomMems.add(item);
10232                }
10233            }
10234
10235            if (outTag != null || outStack != null) {
10236                if (outTag != null) {
10237                    appendMemBucket(outTag, totalPss, "total", false);
10238                }
10239                if (outStack != null) {
10240                    appendMemBucket(outStack, totalPss, "total", true);
10241                }
10242                boolean firstLine = true;
10243                for (int i=0; i<oomMems.size(); i++) {
10244                    MemItem miCat = oomMems.get(i);
10245                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10246                        continue;
10247                    }
10248                    if (miCat.id < ProcessList.SERVICE_ADJ
10249                            || miCat.id == ProcessList.HOME_APP_ADJ
10250                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10251                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10252                            outTag.append(" / ");
10253                        }
10254                        if (outStack != null) {
10255                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10256                                if (firstLine) {
10257                                    outStack.append(":");
10258                                    firstLine = false;
10259                                }
10260                                outStack.append("\n\t at ");
10261                            } else {
10262                                outStack.append("$");
10263                            }
10264                        }
10265                        for (int j=0; j<miCat.subitems.size(); j++) {
10266                            MemItem mi = miCat.subitems.get(j);
10267                            if (j > 0) {
10268                                if (outTag != null) {
10269                                    outTag.append(" ");
10270                                }
10271                                if (outStack != null) {
10272                                    outStack.append("$");
10273                                }
10274                            }
10275                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10276                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10277                            }
10278                            if (outStack != null) {
10279                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10280                            }
10281                        }
10282                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10283                            outStack.append("(");
10284                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10285                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10286                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10287                                    outStack.append(":");
10288                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10289                                }
10290                            }
10291                            outStack.append(")");
10292                        }
10293                    }
10294                }
10295            }
10296
10297            if (!brief && !oomOnly) {
10298                pw.println();
10299                pw.println("Total PSS by process:");
10300                dumpMemItems(pw, "  ", procMems, true);
10301                pw.println();
10302            }
10303            pw.println("Total PSS by OOM adjustment:");
10304            dumpMemItems(pw, "  ", oomMems, false);
10305            if (!oomOnly) {
10306                PrintWriter out = categoryPw != null ? categoryPw : pw;
10307                out.println();
10308                out.println("Total PSS by category:");
10309                dumpMemItems(out, "  ", catMems, true);
10310            }
10311            pw.println();
10312            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10313            final int[] SINGLE_LONG_FORMAT = new int[] {
10314                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10315            };
10316            long[] longOut = new long[1];
10317            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10318                    SINGLE_LONG_FORMAT, null, longOut, null);
10319            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10320            longOut[0] = 0;
10321            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10322                    SINGLE_LONG_FORMAT, null, longOut, null);
10323            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10324            longOut[0] = 0;
10325            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10326                    SINGLE_LONG_FORMAT, null, longOut, null);
10327            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10328            longOut[0] = 0;
10329            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10330                    SINGLE_LONG_FORMAT, null, longOut, null);
10331            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10332            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10333                    pw.print(shared); pw.println(" kB");
10334            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10335                    pw.print(voltile); pw.println(" kB volatile");
10336        }
10337    }
10338
10339    /**
10340     * Searches array of arguments for the specified string
10341     * @param args array of argument strings
10342     * @param value value to search for
10343     * @return true if the value is contained in the array
10344     */
10345    private static boolean scanArgs(String[] args, String value) {
10346        if (args != null) {
10347            for (String arg : args) {
10348                if (value.equals(arg)) {
10349                    return true;
10350                }
10351            }
10352        }
10353        return false;
10354    }
10355
10356    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10357            ContentProviderRecord cpr, boolean always) {
10358        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10359
10360        if (!inLaunching || always) {
10361            synchronized (cpr) {
10362                cpr.launchingApp = null;
10363                cpr.notifyAll();
10364            }
10365            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10366            String names[] = cpr.info.authority.split(";");
10367            for (int j = 0; j < names.length; j++) {
10368                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10369            }
10370        }
10371
10372        for (int i=0; i<cpr.connections.size(); i++) {
10373            ContentProviderConnection conn = cpr.connections.get(i);
10374            if (conn.waiting) {
10375                // If this connection is waiting for the provider, then we don't
10376                // need to mess with its process unless we are always removing
10377                // or for some reason the provider is not currently launching.
10378                if (inLaunching && !always) {
10379                    continue;
10380                }
10381            }
10382            ProcessRecord capp = conn.client;
10383            conn.dead = true;
10384            if (conn.stableCount > 0) {
10385                if (!capp.persistent && capp.thread != null
10386                        && capp.pid != 0
10387                        && capp.pid != MY_PID) {
10388                    Slog.i(TAG, "Kill " + capp.processName
10389                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10390                            + " in dying process " + (proc != null ? proc.processName : "??"));
10391                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10392                            capp.processName, capp.setAdj, "dying provider "
10393                                    + cpr.name.toShortString());
10394                    Process.killProcessQuiet(capp.pid);
10395                }
10396            } else if (capp.thread != null && conn.provider.provider != null) {
10397                try {
10398                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10399                } catch (RemoteException e) {
10400                }
10401                // In the protocol here, we don't expect the client to correctly
10402                // clean up this connection, we'll just remove it.
10403                cpr.connections.remove(i);
10404                conn.client.conProviders.remove(conn);
10405            }
10406        }
10407
10408        if (inLaunching && always) {
10409            mLaunchingProviders.remove(cpr);
10410        }
10411        return inLaunching;
10412    }
10413
10414    /**
10415     * Main code for cleaning up a process when it has gone away.  This is
10416     * called both as a result of the process dying, or directly when stopping
10417     * a process when running in single process mode.
10418     */
10419    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10420            boolean restarting, boolean allowRestart, int index) {
10421        if (index >= 0) {
10422            mLruProcesses.remove(index);
10423        }
10424
10425        mProcessesToGc.remove(app);
10426
10427        // Dismiss any open dialogs.
10428        if (app.crashDialog != null) {
10429            app.crashDialog.dismiss();
10430            app.crashDialog = null;
10431        }
10432        if (app.anrDialog != null) {
10433            app.anrDialog.dismiss();
10434            app.anrDialog = null;
10435        }
10436        if (app.waitDialog != null) {
10437            app.waitDialog.dismiss();
10438            app.waitDialog = null;
10439        }
10440
10441        app.crashing = false;
10442        app.notResponding = false;
10443
10444        app.resetPackageList();
10445        app.unlinkDeathRecipient();
10446        app.thread = null;
10447        app.forcingToForeground = null;
10448        app.foregroundServices = false;
10449        app.foregroundActivities = false;
10450        app.hasShownUi = false;
10451        app.hasAboveClient = false;
10452
10453        mServices.killServicesLocked(app, allowRestart);
10454
10455        boolean restart = false;
10456
10457        // Remove published content providers.
10458        if (!app.pubProviders.isEmpty()) {
10459            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10460            while (it.hasNext()) {
10461                ContentProviderRecord cpr = it.next();
10462
10463                final boolean always = app.bad || !allowRestart;
10464                if (removeDyingProviderLocked(app, cpr, always) || always) {
10465                    // We left the provider in the launching list, need to
10466                    // restart it.
10467                    restart = true;
10468                }
10469
10470                cpr.provider = null;
10471                cpr.proc = null;
10472            }
10473            app.pubProviders.clear();
10474        }
10475
10476        // Take care of any launching providers waiting for this process.
10477        if (checkAppInLaunchingProvidersLocked(app, false)) {
10478            restart = true;
10479        }
10480
10481        // Unregister from connected content providers.
10482        if (!app.conProviders.isEmpty()) {
10483            for (int i=0; i<app.conProviders.size(); i++) {
10484                ContentProviderConnection conn = app.conProviders.get(i);
10485                conn.provider.connections.remove(conn);
10486            }
10487            app.conProviders.clear();
10488        }
10489
10490        // At this point there may be remaining entries in mLaunchingProviders
10491        // where we were the only one waiting, so they are no longer of use.
10492        // Look for these and clean up if found.
10493        // XXX Commented out for now.  Trying to figure out a way to reproduce
10494        // the actual situation to identify what is actually going on.
10495        if (false) {
10496            for (int i=0; i<mLaunchingProviders.size(); i++) {
10497                ContentProviderRecord cpr = (ContentProviderRecord)
10498                        mLaunchingProviders.get(i);
10499                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10500                    synchronized (cpr) {
10501                        cpr.launchingApp = null;
10502                        cpr.notifyAll();
10503                    }
10504                }
10505            }
10506        }
10507
10508        skipCurrentReceiverLocked(app);
10509
10510        // Unregister any receivers.
10511        if (app.receivers.size() > 0) {
10512            Iterator<ReceiverList> it = app.receivers.iterator();
10513            while (it.hasNext()) {
10514                removeReceiverLocked(it.next());
10515            }
10516            app.receivers.clear();
10517        }
10518
10519        // If the app is undergoing backup, tell the backup manager about it
10520        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10521            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10522            try {
10523                IBackupManager bm = IBackupManager.Stub.asInterface(
10524                        ServiceManager.getService(Context.BACKUP_SERVICE));
10525                bm.agentDisconnected(app.info.packageName);
10526            } catch (RemoteException e) {
10527                // can't happen; backup manager is local
10528            }
10529        }
10530
10531        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10532            ProcessChangeItem item = mPendingProcessChanges.get(i);
10533            if (item.pid == app.pid) {
10534                mPendingProcessChanges.remove(i);
10535                mAvailProcessChanges.add(item);
10536            }
10537        }
10538        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10539
10540        // If the caller is restarting this app, then leave it in its
10541        // current lists and let the caller take care of it.
10542        if (restarting) {
10543            return;
10544        }
10545
10546        if (!app.persistent || app.isolated) {
10547            if (DEBUG_PROCESSES) Slog.v(TAG,
10548                    "Removing non-persistent process during cleanup: " + app);
10549            mProcessNames.remove(app.processName, app.uid);
10550            mIsolatedProcesses.remove(app.uid);
10551            if (mHeavyWeightProcess == app) {
10552                mHeavyWeightProcess = null;
10553                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10554            }
10555        } else if (!app.removed) {
10556            // This app is persistent, so we need to keep its record around.
10557            // If it is not already on the pending app list, add it there
10558            // and start a new process for it.
10559            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10560                mPersistentStartingProcesses.add(app);
10561                restart = true;
10562            }
10563        }
10564        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10565                "Clean-up removing on hold: " + app);
10566        mProcessesOnHold.remove(app);
10567
10568        if (app == mHomeProcess) {
10569            mHomeProcess = null;
10570        }
10571        if (app == mPreviousProcess) {
10572            mPreviousProcess = null;
10573        }
10574
10575        if (restart && !app.isolated) {
10576            // We have components that still need to be running in the
10577            // process, so re-launch it.
10578            mProcessNames.put(app.processName, app.uid, app);
10579            startProcessLocked(app, "restart", app.processName);
10580        } else if (app.pid > 0 && app.pid != MY_PID) {
10581            // Goodbye!
10582            synchronized (mPidsSelfLocked) {
10583                mPidsSelfLocked.remove(app.pid);
10584                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10585            }
10586            app.setPid(0);
10587        }
10588    }
10589
10590    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10591        // Look through the content providers we are waiting to have launched,
10592        // and if any run in this process then either schedule a restart of
10593        // the process or kill the client waiting for it if this process has
10594        // gone bad.
10595        int NL = mLaunchingProviders.size();
10596        boolean restart = false;
10597        for (int i=0; i<NL; i++) {
10598            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10599            if (cpr.launchingApp == app) {
10600                if (!alwaysBad && !app.bad) {
10601                    restart = true;
10602                } else {
10603                    removeDyingProviderLocked(app, cpr, true);
10604                    NL = mLaunchingProviders.size();
10605                }
10606            }
10607        }
10608        return restart;
10609    }
10610
10611    // =========================================================
10612    // SERVICES
10613    // =========================================================
10614
10615    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10616            int flags) {
10617        enforceNotIsolatedCaller("getServices");
10618        synchronized (this) {
10619            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10620        }
10621    }
10622
10623    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10624        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10625        synchronized (this) {
10626            return mServices.getRunningServiceControlPanelLocked(name);
10627        }
10628    }
10629
10630    public ComponentName startService(IApplicationThread caller, Intent service,
10631            String resolvedType, int userId) {
10632        enforceNotIsolatedCaller("startService");
10633        // Refuse possible leaked file descriptors
10634        if (service != null && service.hasFileDescriptors() == true) {
10635            throw new IllegalArgumentException("File descriptors passed in Intent");
10636        }
10637
10638        if (DEBUG_SERVICE)
10639            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10640        synchronized(this) {
10641            final int callingPid = Binder.getCallingPid();
10642            final int callingUid = Binder.getCallingUid();
10643            checkValidCaller(callingUid, userId);
10644            final long origId = Binder.clearCallingIdentity();
10645            ComponentName res = mServices.startServiceLocked(caller, service,
10646                    resolvedType, callingPid, callingUid, userId);
10647            Binder.restoreCallingIdentity(origId);
10648            return res;
10649        }
10650    }
10651
10652    ComponentName startServiceInPackage(int uid,
10653            Intent service, String resolvedType) {
10654        synchronized(this) {
10655            if (DEBUG_SERVICE)
10656                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10657            final long origId = Binder.clearCallingIdentity();
10658            ComponentName res = mServices.startServiceLocked(null, service,
10659                    resolvedType, -1, uid, UserHandle.getUserId(uid));
10660            Binder.restoreCallingIdentity(origId);
10661            return res;
10662        }
10663    }
10664
10665    public int stopService(IApplicationThread caller, Intent service,
10666            String resolvedType, int userId) {
10667        enforceNotIsolatedCaller("stopService");
10668        // Refuse possible leaked file descriptors
10669        if (service != null && service.hasFileDescriptors() == true) {
10670            throw new IllegalArgumentException("File descriptors passed in Intent");
10671        }
10672
10673        checkValidCaller(Binder.getCallingUid(), userId);
10674
10675        synchronized(this) {
10676            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10677        }
10678    }
10679
10680    public IBinder peekService(Intent service, String resolvedType) {
10681        enforceNotIsolatedCaller("peekService");
10682        // Refuse possible leaked file descriptors
10683        if (service != null && service.hasFileDescriptors() == true) {
10684            throw new IllegalArgumentException("File descriptors passed in Intent");
10685        }
10686        synchronized(this) {
10687            return mServices.peekServiceLocked(service, resolvedType);
10688        }
10689    }
10690
10691    public boolean stopServiceToken(ComponentName className, IBinder token,
10692            int startId) {
10693        synchronized(this) {
10694            return mServices.stopServiceTokenLocked(className, token, startId);
10695        }
10696    }
10697
10698    public void setServiceForeground(ComponentName className, IBinder token,
10699            int id, Notification notification, boolean removeNotification) {
10700        synchronized(this) {
10701            mServices.setServiceForegroundLocked(className, token, id, notification,
10702                    removeNotification);
10703        }
10704    }
10705
10706    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10707            String className, int flags) {
10708        boolean result = false;
10709        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10710            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10711                if (ActivityManager.checkUidPermission(
10712                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10713                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10714                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10715                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10716                            + " requests FLAG_SINGLE_USER, but app does not hold "
10717                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10718                    Slog.w(TAG, msg);
10719                    throw new SecurityException(msg);
10720                }
10721                result = true;
10722            }
10723        } else if (componentProcessName == aInfo.packageName) {
10724            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10725        } else if ("system".equals(componentProcessName)) {
10726            result = true;
10727        }
10728        if (DEBUG_MU) {
10729            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10730                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10731        }
10732        return result;
10733    }
10734
10735    public int bindService(IApplicationThread caller, IBinder token,
10736            Intent service, String resolvedType,
10737            IServiceConnection connection, int flags, int userId) {
10738        enforceNotIsolatedCaller("bindService");
10739        // Refuse possible leaked file descriptors
10740        if (service != null && service.hasFileDescriptors() == true) {
10741            throw new IllegalArgumentException("File descriptors passed in Intent");
10742        }
10743
10744        checkValidCaller(Binder.getCallingUid(), userId);
10745
10746        synchronized(this) {
10747            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10748                    connection, flags, userId);
10749        }
10750    }
10751
10752    public boolean unbindService(IServiceConnection connection) {
10753        synchronized (this) {
10754            return mServices.unbindServiceLocked(connection);
10755        }
10756    }
10757
10758    public void publishService(IBinder token, Intent intent, IBinder service) {
10759        // Refuse possible leaked file descriptors
10760        if (intent != null && intent.hasFileDescriptors() == true) {
10761            throw new IllegalArgumentException("File descriptors passed in Intent");
10762        }
10763
10764        synchronized(this) {
10765            if (!(token instanceof ServiceRecord)) {
10766                throw new IllegalArgumentException("Invalid service token");
10767            }
10768            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
10769        }
10770    }
10771
10772    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10773        // Refuse possible leaked file descriptors
10774        if (intent != null && intent.hasFileDescriptors() == true) {
10775            throw new IllegalArgumentException("File descriptors passed in Intent");
10776        }
10777
10778        synchronized(this) {
10779            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
10780        }
10781    }
10782
10783    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10784        synchronized(this) {
10785            if (!(token instanceof ServiceRecord)) {
10786                throw new IllegalArgumentException("Invalid service token");
10787            }
10788            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
10789        }
10790    }
10791
10792    // =========================================================
10793    // BACKUP AND RESTORE
10794    // =========================================================
10795
10796    // Cause the target app to be launched if necessary and its backup agent
10797    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10798    // activity manager to announce its creation.
10799    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10800        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10801        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10802
10803        synchronized(this) {
10804            // !!! TODO: currently no check here that we're already bound
10805            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10806            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10807            synchronized (stats) {
10808                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10809            }
10810
10811            // Backup agent is now in use, its package can't be stopped.
10812            try {
10813                AppGlobals.getPackageManager().setPackageStoppedState(
10814                        app.packageName, false, UserHandle.getUserId(app.uid));
10815            } catch (RemoteException e) {
10816            } catch (IllegalArgumentException e) {
10817                Slog.w(TAG, "Failed trying to unstop package "
10818                        + app.packageName + ": " + e);
10819            }
10820
10821            BackupRecord r = new BackupRecord(ss, app, backupMode);
10822            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10823                    ? new ComponentName(app.packageName, app.backupAgentName)
10824                    : new ComponentName("android", "FullBackupAgent");
10825            // startProcessLocked() returns existing proc's record if it's already running
10826            ProcessRecord proc = startProcessLocked(app.processName, app,
10827                    false, 0, "backup", hostingName, false, false);
10828            if (proc == null) {
10829                Slog.e(TAG, "Unable to start backup agent process " + r);
10830                return false;
10831            }
10832
10833            r.app = proc;
10834            mBackupTarget = r;
10835            mBackupAppName = app.packageName;
10836
10837            // Try not to kill the process during backup
10838            updateOomAdjLocked(proc);
10839
10840            // If the process is already attached, schedule the creation of the backup agent now.
10841            // If it is not yet live, this will be done when it attaches to the framework.
10842            if (proc.thread != null) {
10843                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
10844                try {
10845                    proc.thread.scheduleCreateBackupAgent(app,
10846                            compatibilityInfoForPackageLocked(app), backupMode);
10847                } catch (RemoteException e) {
10848                    // Will time out on the backup manager side
10849                }
10850            } else {
10851                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
10852            }
10853            // Invariants: at this point, the target app process exists and the application
10854            // is either already running or in the process of coming up.  mBackupTarget and
10855            // mBackupAppName describe the app, so that when it binds back to the AM we
10856            // know that it's scheduled for a backup-agent operation.
10857        }
10858
10859        return true;
10860    }
10861
10862    // A backup agent has just come up
10863    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10864        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
10865                + " = " + agent);
10866
10867        synchronized(this) {
10868            if (!agentPackageName.equals(mBackupAppName)) {
10869                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10870                return;
10871            }
10872        }
10873
10874        long oldIdent = Binder.clearCallingIdentity();
10875        try {
10876            IBackupManager bm = IBackupManager.Stub.asInterface(
10877                    ServiceManager.getService(Context.BACKUP_SERVICE));
10878            bm.agentConnected(agentPackageName, agent);
10879        } catch (RemoteException e) {
10880            // can't happen; the backup manager service is local
10881        } catch (Exception e) {
10882            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10883            e.printStackTrace();
10884        } finally {
10885            Binder.restoreCallingIdentity(oldIdent);
10886        }
10887    }
10888
10889    // done with this agent
10890    public void unbindBackupAgent(ApplicationInfo appInfo) {
10891        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
10892        if (appInfo == null) {
10893            Slog.w(TAG, "unbind backup agent for null app");
10894            return;
10895        }
10896
10897        synchronized(this) {
10898            if (mBackupAppName == null) {
10899                Slog.w(TAG, "Unbinding backup agent with no active backup");
10900                return;
10901            }
10902
10903            if (!mBackupAppName.equals(appInfo.packageName)) {
10904                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
10905                return;
10906            }
10907
10908            ProcessRecord proc = mBackupTarget.app;
10909            mBackupTarget = null;
10910            mBackupAppName = null;
10911
10912            // Not backing this app up any more; reset its OOM adjustment
10913            updateOomAdjLocked(proc);
10914
10915            // If the app crashed during backup, 'thread' will be null here
10916            if (proc.thread != null) {
10917                try {
10918                    proc.thread.scheduleDestroyBackupAgent(appInfo,
10919                            compatibilityInfoForPackageLocked(appInfo));
10920                } catch (Exception e) {
10921                    Slog.e(TAG, "Exception when unbinding backup agent:");
10922                    e.printStackTrace();
10923                }
10924            }
10925        }
10926    }
10927    // =========================================================
10928    // BROADCASTS
10929    // =========================================================
10930
10931    private final List getStickiesLocked(String action, IntentFilter filter,
10932            List cur) {
10933        final ContentResolver resolver = mContext.getContentResolver();
10934        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10935        if (list == null) {
10936            return cur;
10937        }
10938        int N = list.size();
10939        for (int i=0; i<N; i++) {
10940            Intent intent = list.get(i);
10941            if (filter.match(resolver, intent, true, TAG) >= 0) {
10942                if (cur == null) {
10943                    cur = new ArrayList<Intent>();
10944                }
10945                cur.add(intent);
10946            }
10947        }
10948        return cur;
10949    }
10950
10951    boolean isPendingBroadcastProcessLocked(int pid) {
10952        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
10953                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
10954    }
10955
10956    void skipPendingBroadcastLocked(int pid) {
10957            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
10958            for (BroadcastQueue queue : mBroadcastQueues) {
10959                queue.skipPendingBroadcastLocked(pid);
10960            }
10961    }
10962
10963    // The app just attached; send any pending broadcasts that it should receive
10964    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
10965        boolean didSomething = false;
10966        for (BroadcastQueue queue : mBroadcastQueues) {
10967            didSomething |= queue.sendPendingBroadcastsLocked(app);
10968        }
10969        return didSomething;
10970    }
10971
10972    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
10973            IIntentReceiver receiver, IntentFilter filter, String permission) {
10974        enforceNotIsolatedCaller("registerReceiver");
10975        int callingUid;
10976        synchronized(this) {
10977            ProcessRecord callerApp = null;
10978            if (caller != null) {
10979                callerApp = getRecordForAppLocked(caller);
10980                if (callerApp == null) {
10981                    throw new SecurityException(
10982                            "Unable to find app for caller " + caller
10983                            + " (pid=" + Binder.getCallingPid()
10984                            + ") when registering receiver " + receiver);
10985                }
10986                if (callerApp.info.uid != Process.SYSTEM_UID &&
10987                        !callerApp.pkgList.contains(callerPackage)) {
10988                    throw new SecurityException("Given caller package " + callerPackage
10989                            + " is not running in process " + callerApp);
10990                }
10991                callingUid = callerApp.info.uid;
10992            } else {
10993                callerPackage = null;
10994                callingUid = Binder.getCallingUid();
10995            }
10996
10997            List allSticky = null;
10998
10999            // Look for any matching sticky broadcasts...
11000            Iterator actions = filter.actionsIterator();
11001            if (actions != null) {
11002                while (actions.hasNext()) {
11003                    String action = (String)actions.next();
11004                    allSticky = getStickiesLocked(action, filter, allSticky);
11005                }
11006            } else {
11007                allSticky = getStickiesLocked(null, filter, allSticky);
11008            }
11009
11010            // The first sticky in the list is returned directly back to
11011            // the client.
11012            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11013
11014            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11015                    + ": " + sticky);
11016
11017            if (receiver == null) {
11018                return sticky;
11019            }
11020
11021            ReceiverList rl
11022                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11023            if (rl == null) {
11024                rl = new ReceiverList(this, callerApp,
11025                        Binder.getCallingPid(),
11026                        Binder.getCallingUid(), receiver);
11027                if (rl.app != null) {
11028                    rl.app.receivers.add(rl);
11029                } else {
11030                    try {
11031                        receiver.asBinder().linkToDeath(rl, 0);
11032                    } catch (RemoteException e) {
11033                        return sticky;
11034                    }
11035                    rl.linkedToDeath = true;
11036                }
11037                mRegisteredReceivers.put(receiver.asBinder(), rl);
11038            }
11039            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11040                    permission, callingUid);
11041            rl.add(bf);
11042            if (!bf.debugCheck()) {
11043                Slog.w(TAG, "==> For Dynamic broadast");
11044            }
11045            mReceiverResolver.addFilter(bf);
11046
11047            // Enqueue broadcasts for all existing stickies that match
11048            // this filter.
11049            if (allSticky != null) {
11050                ArrayList receivers = new ArrayList();
11051                receivers.add(bf);
11052
11053                int N = allSticky.size();
11054                for (int i=0; i<N; i++) {
11055                    Intent intent = (Intent)allSticky.get(i);
11056                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11057                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11058                            null, -1, -1, null, receivers, null, 0, null, null,
11059                            false, true, true, -1);
11060                    queue.enqueueParallelBroadcastLocked(r);
11061                    queue.scheduleBroadcastsLocked();
11062                }
11063            }
11064
11065            return sticky;
11066        }
11067    }
11068
11069    public void unregisterReceiver(IIntentReceiver receiver) {
11070        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11071
11072        final long origId = Binder.clearCallingIdentity();
11073        try {
11074            boolean doTrim = false;
11075
11076            synchronized(this) {
11077                ReceiverList rl
11078                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11079                if (rl != null) {
11080                    if (rl.curBroadcast != null) {
11081                        BroadcastRecord r = rl.curBroadcast;
11082                        final boolean doNext = finishReceiverLocked(
11083                                receiver.asBinder(), r.resultCode, r.resultData,
11084                                r.resultExtras, r.resultAbort, true);
11085                        if (doNext) {
11086                            doTrim = true;
11087                            r.queue.processNextBroadcast(false);
11088                        }
11089                    }
11090
11091                    if (rl.app != null) {
11092                        rl.app.receivers.remove(rl);
11093                    }
11094                    removeReceiverLocked(rl);
11095                    if (rl.linkedToDeath) {
11096                        rl.linkedToDeath = false;
11097                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11098                    }
11099                }
11100            }
11101
11102            // If we actually concluded any broadcasts, we might now be able
11103            // to trim the recipients' apps from our working set
11104            if (doTrim) {
11105                trimApplications();
11106                return;
11107            }
11108
11109        } finally {
11110            Binder.restoreCallingIdentity(origId);
11111        }
11112    }
11113
11114    void removeReceiverLocked(ReceiverList rl) {
11115        mRegisteredReceivers.remove(rl.receiver.asBinder());
11116        int N = rl.size();
11117        for (int i=0; i<N; i++) {
11118            mReceiverResolver.removeFilter(rl.get(i));
11119        }
11120    }
11121
11122    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11123        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11124            ProcessRecord r = mLruProcesses.get(i);
11125            if (r.thread != null) {
11126                try {
11127                    r.thread.dispatchPackageBroadcast(cmd, packages);
11128                } catch (RemoteException ex) {
11129                }
11130            }
11131        }
11132    }
11133
11134    private final int broadcastIntentLocked(ProcessRecord callerApp,
11135            String callerPackage, Intent intent, String resolvedType,
11136            IIntentReceiver resultTo, int resultCode, String resultData,
11137            Bundle map, String requiredPermission,
11138            boolean ordered, boolean sticky, int callingPid, int callingUid,
11139            int userId) {
11140        intent = new Intent(intent);
11141
11142        // By default broadcasts do not go to stopped apps.
11143        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11144
11145        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11146            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11147            + " ordered=" + ordered + " userid=" + userId);
11148        if ((resultTo != null) && !ordered) {
11149            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11150        }
11151
11152        // If the caller is trying to send this broadcast to a different
11153        // user, verify that is allowed.
11154        if (UserHandle.getUserId(callingUid) != userId) {
11155            if (checkComponentPermission(
11156                    android.Manifest.permission.INTERACT_ACROSS_USERS,
11157                    callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED
11158                    && checkComponentPermission(
11159                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
11160                            callingPid, callingUid, -1, true)
11161                            != PackageManager.PERMISSION_GRANTED) {
11162                String msg = "Permission Denial: " + intent.getAction()
11163                        + " broadcast from " + callerPackage
11164                        + " asks to send as user " + userId
11165                        + " but is calling from user " + UserHandle.getUserId(callingUid)
11166                        + "; this requires "
11167                        + android.Manifest.permission.INTERACT_ACROSS_USERS;
11168                Slog.w(TAG, msg);
11169                throw new SecurityException(msg);
11170            } else {
11171                if (userId == UserHandle.USER_CURRENT) {
11172                    userId = mCurrentUserId;
11173                }
11174            }
11175        }
11176
11177        // Make sure that the user who is receiving this broadcast is started
11178        // If not, we will just skip it.
11179        if (mStartedUsers.get(userId) == null) {
11180            Slog.w(TAG, "Skipping broadcast of " + intent
11181                    + ": user " + userId + " is stopped");
11182            return ActivityManager.BROADCAST_SUCCESS;
11183        }
11184
11185        // Handle special intents: if this broadcast is from the package
11186        // manager about a package being removed, we need to remove all of
11187        // its activities from the history stack.
11188        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11189                intent.getAction());
11190        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11191                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11192                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11193                || uidRemoved) {
11194            if (checkComponentPermission(
11195                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11196                    callingPid, callingUid, -1, true)
11197                    == PackageManager.PERMISSION_GRANTED) {
11198                if (uidRemoved) {
11199                    final Bundle intentExtras = intent.getExtras();
11200                    final int uid = intentExtras != null
11201                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11202                    if (uid >= 0) {
11203                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11204                        synchronized (bs) {
11205                            bs.removeUidStatsLocked(uid);
11206                        }
11207                    }
11208                } else {
11209                    // If resources are unvailble just force stop all
11210                    // those packages and flush the attribute cache as well.
11211                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11212                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11213                        if (list != null && (list.length > 0)) {
11214                            for (String pkg : list) {
11215                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11216                            }
11217                            sendPackageBroadcastLocked(
11218                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
11219                        }
11220                    } else {
11221                        Uri data = intent.getData();
11222                        String ssp;
11223                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11224                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11225                                forceStopPackageLocked(ssp,
11226                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11227                                        false, userId);
11228                            }
11229                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11230                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11231                                        new String[] {ssp});
11232                            }
11233                        }
11234                    }
11235                }
11236            } else {
11237                String msg = "Permission Denial: " + intent.getAction()
11238                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11239                        + ", uid=" + callingUid + ")"
11240                        + " requires "
11241                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11242                Slog.w(TAG, msg);
11243                throw new SecurityException(msg);
11244            }
11245
11246        // Special case for adding a package: by default turn on compatibility
11247        // mode.
11248        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11249            Uri data = intent.getData();
11250            String ssp;
11251            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11252                mCompatModePackages.handlePackageAddedLocked(ssp,
11253                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11254            }
11255        }
11256
11257        /*
11258         * If this is the time zone changed action, queue up a message that will reset the timezone
11259         * of all currently running processes. This message will get queued up before the broadcast
11260         * happens.
11261         */
11262        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11263            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11264        }
11265
11266        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11267            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11268        }
11269
11270        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11271            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11272            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11273        }
11274
11275        /*
11276         * Prevent non-system code (defined here to be non-persistent
11277         * processes) from sending protected broadcasts.
11278         */
11279        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11280            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11281            callingUid == 0) {
11282            // Always okay.
11283        } else if (callerApp == null || !callerApp.persistent) {
11284            try {
11285                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11286                        intent.getAction())) {
11287                    String msg = "Permission Denial: not allowed to send broadcast "
11288                            + intent.getAction() + " from pid="
11289                            + callingPid + ", uid=" + callingUid;
11290                    Slog.w(TAG, msg);
11291                    throw new SecurityException(msg);
11292                }
11293            } catch (RemoteException e) {
11294                Slog.w(TAG, "Remote exception", e);
11295                return ActivityManager.BROADCAST_SUCCESS;
11296            }
11297        }
11298
11299        // Add to the sticky list if requested.
11300        if (sticky) {
11301            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11302                    callingPid, callingUid)
11303                    != PackageManager.PERMISSION_GRANTED) {
11304                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11305                        + callingPid + ", uid=" + callingUid
11306                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11307                Slog.w(TAG, msg);
11308                throw new SecurityException(msg);
11309            }
11310            if (requiredPermission != null) {
11311                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11312                        + " and enforce permission " + requiredPermission);
11313                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11314            }
11315            if (intent.getComponent() != null) {
11316                throw new SecurityException(
11317                        "Sticky broadcasts can't target a specific component");
11318            }
11319            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11320            if (list == null) {
11321                list = new ArrayList<Intent>();
11322                mStickyBroadcasts.put(intent.getAction(), list);
11323            }
11324            int N = list.size();
11325            int i;
11326            for (i=0; i<N; i++) {
11327                if (intent.filterEquals(list.get(i))) {
11328                    // This sticky already exists, replace it.
11329                    list.set(i, new Intent(intent));
11330                    break;
11331                }
11332            }
11333            if (i >= N) {
11334                list.add(new Intent(intent));
11335            }
11336        }
11337
11338        // Figure out who all will receive this broadcast.
11339        List receivers = null;
11340        List<BroadcastFilter> registeredReceivers = null;
11341        try {
11342            // Need to resolve the intent to interested receivers...
11343            if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11344                     == 0) {
11345                receivers = AppGlobals.getPackageManager().queryIntentReceivers(
11346                        intent, resolvedType, STOCK_PM_FLAGS, userId);
11347            }
11348            if (intent.getComponent() == null) {
11349                registeredReceivers = mReceiverResolver.queryIntent(intent,
11350                        resolvedType, false, userId);
11351            }
11352        } catch (RemoteException ex) {
11353            // pm is in same process, this will never happen.
11354        }
11355
11356        final boolean replacePending =
11357                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11358
11359        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11360                + " replacePending=" + replacePending);
11361
11362        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11363        if (!ordered && NR > 0) {
11364            // If we are not serializing this broadcast, then send the
11365            // registered receivers separately so they don't wait for the
11366            // components to be launched.
11367            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11368            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11369                    callerPackage, callingPid, callingUid, requiredPermission,
11370                    registeredReceivers, resultTo, resultCode, resultData, map,
11371                    ordered, sticky, false, userId);
11372            if (DEBUG_BROADCAST) Slog.v(
11373                    TAG, "Enqueueing parallel broadcast " + r);
11374            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11375            if (!replaced) {
11376                queue.enqueueParallelBroadcastLocked(r);
11377                queue.scheduleBroadcastsLocked();
11378            }
11379            registeredReceivers = null;
11380            NR = 0;
11381        }
11382
11383        // Merge into one list.
11384        int ir = 0;
11385        if (receivers != null) {
11386            // A special case for PACKAGE_ADDED: do not allow the package
11387            // being added to see this broadcast.  This prevents them from
11388            // using this as a back door to get run as soon as they are
11389            // installed.  Maybe in the future we want to have a special install
11390            // broadcast or such for apps, but we'd like to deliberately make
11391            // this decision.
11392            String skipPackages[] = null;
11393            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11394                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11395                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11396                Uri data = intent.getData();
11397                if (data != null) {
11398                    String pkgName = data.getSchemeSpecificPart();
11399                    if (pkgName != null) {
11400                        skipPackages = new String[] { pkgName };
11401                    }
11402                }
11403            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11404                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11405            }
11406            if (skipPackages != null && (skipPackages.length > 0)) {
11407                for (String skipPackage : skipPackages) {
11408                    if (skipPackage != null) {
11409                        int NT = receivers.size();
11410                        for (int it=0; it<NT; it++) {
11411                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11412                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11413                                receivers.remove(it);
11414                                it--;
11415                                NT--;
11416                            }
11417                        }
11418                    }
11419                }
11420            }
11421
11422            int NT = receivers != null ? receivers.size() : 0;
11423            int it = 0;
11424            ResolveInfo curt = null;
11425            BroadcastFilter curr = null;
11426            while (it < NT && ir < NR) {
11427                if (curt == null) {
11428                    curt = (ResolveInfo)receivers.get(it);
11429                }
11430                if (curr == null) {
11431                    curr = registeredReceivers.get(ir);
11432                }
11433                if (curr.getPriority() >= curt.priority) {
11434                    // Insert this broadcast record into the final list.
11435                    receivers.add(it, curr);
11436                    ir++;
11437                    curr = null;
11438                    it++;
11439                    NT++;
11440                } else {
11441                    // Skip to the next ResolveInfo in the final list.
11442                    it++;
11443                    curt = null;
11444                }
11445            }
11446        }
11447        while (ir < NR) {
11448            if (receivers == null) {
11449                receivers = new ArrayList();
11450            }
11451            receivers.add(registeredReceivers.get(ir));
11452            ir++;
11453        }
11454
11455        if ((receivers != null && receivers.size() > 0)
11456                || resultTo != null) {
11457            BroadcastQueue queue = broadcastQueueForIntent(intent);
11458            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11459                    callerPackage, callingPid, callingUid, requiredPermission,
11460                    receivers, resultTo, resultCode, resultData, map, ordered,
11461                    sticky, false, userId);
11462            if (DEBUG_BROADCAST) Slog.v(
11463                    TAG, "Enqueueing ordered broadcast " + r
11464                    + ": prev had " + queue.mOrderedBroadcasts.size());
11465            if (DEBUG_BROADCAST) {
11466                int seq = r.intent.getIntExtra("seq", -1);
11467                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11468            }
11469            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11470            if (!replaced) {
11471                queue.enqueueOrderedBroadcastLocked(r);
11472                queue.scheduleBroadcastsLocked();
11473            }
11474        }
11475
11476        return ActivityManager.BROADCAST_SUCCESS;
11477    }
11478
11479    final Intent verifyBroadcastLocked(Intent intent) {
11480        // Refuse possible leaked file descriptors
11481        if (intent != null && intent.hasFileDescriptors() == true) {
11482            throw new IllegalArgumentException("File descriptors passed in Intent");
11483        }
11484
11485        int flags = intent.getFlags();
11486
11487        if (!mProcessesReady) {
11488            // if the caller really truly claims to know what they're doing, go
11489            // ahead and allow the broadcast without launching any receivers
11490            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11491                intent = new Intent(intent);
11492                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11493            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11494                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11495                        + " before boot completion");
11496                throw new IllegalStateException("Cannot broadcast before boot completed");
11497            }
11498        }
11499
11500        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11501            throw new IllegalArgumentException(
11502                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11503        }
11504
11505        return intent;
11506    }
11507
11508    public final int broadcastIntent(IApplicationThread caller,
11509            Intent intent, String resolvedType, IIntentReceiver resultTo,
11510            int resultCode, String resultData, Bundle map,
11511            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11512        enforceNotIsolatedCaller("broadcastIntent");
11513        synchronized(this) {
11514            intent = verifyBroadcastLocked(intent);
11515
11516            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11517            final int callingPid = Binder.getCallingPid();
11518            final int callingUid = Binder.getCallingUid();
11519            final long origId = Binder.clearCallingIdentity();
11520            int res = broadcastIntentLocked(callerApp,
11521                    callerApp != null ? callerApp.info.packageName : null,
11522                    intent, resolvedType, resultTo,
11523                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11524                    callingPid, callingUid, userId);
11525            Binder.restoreCallingIdentity(origId);
11526            return res;
11527        }
11528    }
11529
11530    int broadcastIntentInPackage(String packageName, int uid,
11531            Intent intent, String resolvedType, IIntentReceiver resultTo,
11532            int resultCode, String resultData, Bundle map,
11533            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11534        synchronized(this) {
11535            intent = verifyBroadcastLocked(intent);
11536
11537            final long origId = Binder.clearCallingIdentity();
11538            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11539                    resultTo, resultCode, resultData, map, requiredPermission,
11540                    serialized, sticky, -1, uid, userId);
11541            Binder.restoreCallingIdentity(origId);
11542            return res;
11543        }
11544    }
11545
11546    // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
11547    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11548        // Refuse possible leaked file descriptors
11549        if (intent != null && intent.hasFileDescriptors() == true) {
11550            throw new IllegalArgumentException("File descriptors passed in Intent");
11551        }
11552
11553        synchronized(this) {
11554            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11555                    != PackageManager.PERMISSION_GRANTED) {
11556                String msg = "Permission Denial: unbroadcastIntent() from pid="
11557                        + Binder.getCallingPid()
11558                        + ", uid=" + Binder.getCallingUid()
11559                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11560                Slog.w(TAG, msg);
11561                throw new SecurityException(msg);
11562            }
11563            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11564            if (list != null) {
11565                int N = list.size();
11566                int i;
11567                for (i=0; i<N; i++) {
11568                    if (intent.filterEquals(list.get(i))) {
11569                        list.remove(i);
11570                        break;
11571                    }
11572                }
11573            }
11574        }
11575    }
11576
11577    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11578            String resultData, Bundle resultExtras, boolean resultAbort,
11579            boolean explicit) {
11580        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11581        if (r == null) {
11582            Slog.w(TAG, "finishReceiver called but not found on queue");
11583            return false;
11584        }
11585
11586        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11587                explicit);
11588    }
11589
11590    public void finishReceiver(IBinder who, int resultCode, String resultData,
11591            Bundle resultExtras, boolean resultAbort) {
11592        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11593
11594        // Refuse possible leaked file descriptors
11595        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11596            throw new IllegalArgumentException("File descriptors passed in Bundle");
11597        }
11598
11599        final long origId = Binder.clearCallingIdentity();
11600        try {
11601            boolean doNext = false;
11602            BroadcastRecord r = null;
11603
11604            synchronized(this) {
11605                r = broadcastRecordForReceiverLocked(who);
11606                if (r != null) {
11607                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11608                        resultData, resultExtras, resultAbort, true);
11609                }
11610            }
11611
11612            if (doNext) {
11613                r.queue.processNextBroadcast(false);
11614            }
11615            trimApplications();
11616        } finally {
11617            Binder.restoreCallingIdentity(origId);
11618        }
11619    }
11620
11621    // =========================================================
11622    // INSTRUMENTATION
11623    // =========================================================
11624
11625    public boolean startInstrumentation(ComponentName className,
11626            String profileFile, int flags, Bundle arguments,
11627            IInstrumentationWatcher watcher) {
11628        enforceNotIsolatedCaller("startInstrumentation");
11629        // Refuse possible leaked file descriptors
11630        if (arguments != null && arguments.hasFileDescriptors()) {
11631            throw new IllegalArgumentException("File descriptors passed in Bundle");
11632        }
11633
11634        synchronized(this) {
11635            InstrumentationInfo ii = null;
11636            ApplicationInfo ai = null;
11637            try {
11638                ii = mContext.getPackageManager().getInstrumentationInfo(
11639                    className, STOCK_PM_FLAGS);
11640                ai = mContext.getPackageManager().getApplicationInfo(
11641                        ii.targetPackage, STOCK_PM_FLAGS);
11642            } catch (PackageManager.NameNotFoundException e) {
11643            }
11644            if (ii == null) {
11645                reportStartInstrumentationFailure(watcher, className,
11646                        "Unable to find instrumentation info for: " + className);
11647                return false;
11648            }
11649            if (ai == null) {
11650                reportStartInstrumentationFailure(watcher, className,
11651                        "Unable to find instrumentation target package: " + ii.targetPackage);
11652                return false;
11653            }
11654
11655            int match = mContext.getPackageManager().checkSignatures(
11656                    ii.targetPackage, ii.packageName);
11657            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11658                String msg = "Permission Denial: starting instrumentation "
11659                        + className + " from pid="
11660                        + Binder.getCallingPid()
11661                        + ", uid=" + Binder.getCallingPid()
11662                        + " not allowed because package " + ii.packageName
11663                        + " does not have a signature matching the target "
11664                        + ii.targetPackage;
11665                reportStartInstrumentationFailure(watcher, className, msg);
11666                throw new SecurityException(msg);
11667            }
11668
11669            int userId = UserHandle.getCallingUserId();
11670            final long origId = Binder.clearCallingIdentity();
11671            // Instrumentation can kill and relaunch even persistent processes
11672            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
11673            ProcessRecord app = addAppLocked(ai, false);
11674            app.instrumentationClass = className;
11675            app.instrumentationInfo = ai;
11676            app.instrumentationProfileFile = profileFile;
11677            app.instrumentationArguments = arguments;
11678            app.instrumentationWatcher = watcher;
11679            app.instrumentationResultClass = className;
11680            Binder.restoreCallingIdentity(origId);
11681        }
11682
11683        return true;
11684    }
11685
11686    /**
11687     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11688     * error to the logs, but if somebody is watching, send the report there too.  This enables
11689     * the "am" command to report errors with more information.
11690     *
11691     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11692     * @param cn The component name of the instrumentation.
11693     * @param report The error report.
11694     */
11695    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11696            ComponentName cn, String report) {
11697        Slog.w(TAG, report);
11698        try {
11699            if (watcher != null) {
11700                Bundle results = new Bundle();
11701                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11702                results.putString("Error", report);
11703                watcher.instrumentationStatus(cn, -1, results);
11704            }
11705        } catch (RemoteException e) {
11706            Slog.w(TAG, e);
11707        }
11708    }
11709
11710    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11711        if (app.instrumentationWatcher != null) {
11712            try {
11713                // NOTE:  IInstrumentationWatcher *must* be oneway here
11714                app.instrumentationWatcher.instrumentationFinished(
11715                    app.instrumentationClass,
11716                    resultCode,
11717                    results);
11718            } catch (RemoteException e) {
11719            }
11720        }
11721        app.instrumentationWatcher = null;
11722        app.instrumentationClass = null;
11723        app.instrumentationInfo = null;
11724        app.instrumentationProfileFile = null;
11725        app.instrumentationArguments = null;
11726
11727        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
11728    }
11729
11730    public void finishInstrumentation(IApplicationThread target,
11731            int resultCode, Bundle results) {
11732        int userId = UserHandle.getCallingUserId();
11733        // Refuse possible leaked file descriptors
11734        if (results != null && results.hasFileDescriptors()) {
11735            throw new IllegalArgumentException("File descriptors passed in Intent");
11736        }
11737
11738        synchronized(this) {
11739            ProcessRecord app = getRecordForAppLocked(target);
11740            if (app == null) {
11741                Slog.w(TAG, "finishInstrumentation: no app for " + target);
11742                return;
11743            }
11744            final long origId = Binder.clearCallingIdentity();
11745            finishInstrumentationLocked(app, resultCode, results);
11746            Binder.restoreCallingIdentity(origId);
11747        }
11748    }
11749
11750    // =========================================================
11751    // CONFIGURATION
11752    // =========================================================
11753
11754    public ConfigurationInfo getDeviceConfigurationInfo() {
11755        ConfigurationInfo config = new ConfigurationInfo();
11756        synchronized (this) {
11757            config.reqTouchScreen = mConfiguration.touchscreen;
11758            config.reqKeyboardType = mConfiguration.keyboard;
11759            config.reqNavigation = mConfiguration.navigation;
11760            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11761                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
11762                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11763            }
11764            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11765                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
11766                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11767            }
11768            config.reqGlEsVersion = GL_ES_VERSION;
11769        }
11770        return config;
11771    }
11772
11773    public Configuration getConfiguration() {
11774        Configuration ci;
11775        synchronized(this) {
11776            ci = new Configuration(mConfiguration);
11777        }
11778        return ci;
11779    }
11780
11781    public void updatePersistentConfiguration(Configuration values) {
11782        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11783                "updateConfiguration()");
11784        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
11785                "updateConfiguration()");
11786        if (values == null) {
11787            throw new NullPointerException("Configuration must not be null");
11788        }
11789
11790        synchronized(this) {
11791            final long origId = Binder.clearCallingIdentity();
11792            updateConfigurationLocked(values, null, true, false);
11793            Binder.restoreCallingIdentity(origId);
11794        }
11795    }
11796
11797    public void updateConfiguration(Configuration values) {
11798        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11799                "updateConfiguration()");
11800
11801        synchronized(this) {
11802            if (values == null && mWindowManager != null) {
11803                // sentinel: fetch the current configuration from the window manager
11804                values = mWindowManager.computeNewConfiguration();
11805            }
11806
11807            if (mWindowManager != null) {
11808                mProcessList.applyDisplaySize(mWindowManager);
11809            }
11810
11811            final long origId = Binder.clearCallingIdentity();
11812            if (values != null) {
11813                Settings.System.clearConfiguration(values);
11814            }
11815            updateConfigurationLocked(values, null, false, false);
11816            Binder.restoreCallingIdentity(origId);
11817        }
11818    }
11819
11820    /**
11821     * Do either or both things: (1) change the current configuration, and (2)
11822     * make sure the given activity is running with the (now) current
11823     * configuration.  Returns true if the activity has been left running, or
11824     * false if <var>starting</var> is being destroyed to match the new
11825     * configuration.
11826     * @param persistent TODO
11827     */
11828    boolean updateConfigurationLocked(Configuration values,
11829            ActivityRecord starting, boolean persistent, boolean initLocale) {
11830        // do nothing if we are headless
11831        if (mHeadless) return true;
11832
11833        int changes = 0;
11834
11835        boolean kept = true;
11836
11837        if (values != null) {
11838            Configuration newConfig = new Configuration(mConfiguration);
11839            changes = newConfig.updateFrom(values);
11840            if (changes != 0) {
11841                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
11842                    Slog.i(TAG, "Updating configuration to: " + values);
11843                }
11844
11845                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
11846
11847                if (values.locale != null && !initLocale) {
11848                    saveLocaleLocked(values.locale,
11849                                     !values.locale.equals(mConfiguration.locale),
11850                                     values.userSetLocale);
11851                }
11852
11853                mConfigurationSeq++;
11854                if (mConfigurationSeq <= 0) {
11855                    mConfigurationSeq = 1;
11856                }
11857                newConfig.seq = mConfigurationSeq;
11858                mConfiguration = newConfig;
11859                Slog.i(TAG, "Config changed: " + newConfig);
11860
11861                final Configuration configCopy = new Configuration(mConfiguration);
11862
11863                // TODO: If our config changes, should we auto dismiss any currently
11864                // showing dialogs?
11865                mShowDialogs = shouldShowDialogs(newConfig);
11866
11867                AttributeCache ac = AttributeCache.instance();
11868                if (ac != null) {
11869                    ac.updateConfiguration(configCopy);
11870                }
11871
11872                // Make sure all resources in our process are updated
11873                // right now, so that anyone who is going to retrieve
11874                // resource values after we return will be sure to get
11875                // the new ones.  This is especially important during
11876                // boot, where the first config change needs to guarantee
11877                // all resources have that config before following boot
11878                // code is executed.
11879                mSystemThread.applyConfigurationToResources(configCopy);
11880
11881                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
11882                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11883                    msg.obj = new Configuration(configCopy);
11884                    mHandler.sendMessage(msg);
11885                }
11886
11887                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11888                    ProcessRecord app = mLruProcesses.get(i);
11889                    try {
11890                        if (app.thread != null) {
11891                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
11892                                    + app.processName + " new config " + mConfiguration);
11893                            app.thread.scheduleConfigurationChanged(configCopy);
11894                        }
11895                    } catch (Exception e) {
11896                    }
11897                }
11898                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
11899                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11900                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
11901                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11902                        null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11903                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
11904                    broadcastIntentLocked(null, null,
11905                            new Intent(Intent.ACTION_LOCALE_CHANGED),
11906                            null, null, 0, null, null,
11907                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11908                }
11909            }
11910        }
11911
11912        if (changes != 0 && starting == null) {
11913            // If the configuration changed, and the caller is not already
11914            // in the process of starting an activity, then find the top
11915            // activity to check if its configuration needs to change.
11916            starting = mMainStack.topRunningActivityLocked(null);
11917        }
11918
11919        if (starting != null) {
11920            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
11921            // And we need to make sure at this point that all other activities
11922            // are made visible with the correct configuration.
11923            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
11924        }
11925
11926        if (values != null && mWindowManager != null) {
11927            mWindowManager.setNewConfiguration(mConfiguration);
11928        }
11929
11930        return kept;
11931    }
11932
11933    /**
11934     * Decide based on the configuration whether we should shouw the ANR,
11935     * crash, etc dialogs.  The idea is that if there is no affordnace to
11936     * press the on-screen buttons, we shouldn't show the dialog.
11937     *
11938     * A thought: SystemUI might also want to get told about this, the Power
11939     * dialog / global actions also might want different behaviors.
11940     */
11941    private static final boolean shouldShowDialogs(Configuration config) {
11942        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
11943                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
11944    }
11945
11946    /**
11947     * Save the locale.  You must be inside a synchronized (this) block.
11948     */
11949    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
11950        if(isDiff) {
11951            SystemProperties.set("user.language", l.getLanguage());
11952            SystemProperties.set("user.region", l.getCountry());
11953        }
11954
11955        if(isPersist) {
11956            SystemProperties.set("persist.sys.language", l.getLanguage());
11957            SystemProperties.set("persist.sys.country", l.getCountry());
11958            SystemProperties.set("persist.sys.localevar", l.getVariant());
11959        }
11960    }
11961
11962    @Override
11963    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
11964        ActivityRecord srec = ActivityRecord.forToken(token);
11965        return srec != null && srec.task.affinity != null &&
11966                srec.task.affinity.equals(destAffinity);
11967    }
11968
11969    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
11970            Intent resultData) {
11971        ComponentName dest = destIntent.getComponent();
11972
11973        synchronized (this) {
11974            ActivityRecord srec = ActivityRecord.forToken(token);
11975            if (srec == null) {
11976                return false;
11977            }
11978            ArrayList<ActivityRecord> history = srec.stack.mHistory;
11979            final int start = history.indexOf(srec);
11980            if (start < 0) {
11981                // Current activity is not in history stack; do nothing.
11982                return false;
11983            }
11984            int finishTo = start - 1;
11985            ActivityRecord parent = null;
11986            boolean foundParentInTask = false;
11987            if (dest != null) {
11988                TaskRecord tr = srec.task;
11989                for (int i = start - 1; i >= 0; i--) {
11990                    ActivityRecord r = history.get(i);
11991                    if (tr != r.task) {
11992                        // Couldn't find parent in the same task; stop at the one above this.
11993                        // (Root of current task; in-app "home" behavior)
11994                        // Always at least finish the current activity.
11995                        finishTo = Math.min(start - 1, i + 1);
11996                        parent = history.get(finishTo);
11997                        break;
11998                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
11999                            r.info.name.equals(dest.getClassName())) {
12000                        finishTo = i;
12001                        parent = r;
12002                        foundParentInTask = true;
12003                        break;
12004                    }
12005                }
12006            }
12007
12008            if (mController != null) {
12009                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12010                if (next != null) {
12011                    // ask watcher if this is allowed
12012                    boolean resumeOK = true;
12013                    try {
12014                        resumeOK = mController.activityResuming(next.packageName);
12015                    } catch (RemoteException e) {
12016                        mController = null;
12017                    }
12018
12019                    if (!resumeOK) {
12020                        return false;
12021                    }
12022                }
12023            }
12024            final long origId = Binder.clearCallingIdentity();
12025            for (int i = start; i > finishTo; i--) {
12026                ActivityRecord r = history.get(i);
12027                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12028                        "navigate-up");
12029                // Only return the supplied result for the first activity finished
12030                resultCode = Activity.RESULT_CANCELED;
12031                resultData = null;
12032            }
12033
12034            if (parent != null && foundParentInTask) {
12035                final int parentLaunchMode = parent.info.launchMode;
12036                final int destIntentFlags = destIntent.getFlags();
12037                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12038                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12039                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12040                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12041                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12042                } else {
12043                    try {
12044                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12045                                destIntent.getComponent(), 0, UserHandle.getCallingUserId());
12046                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12047                                null, aInfo, parent.appToken, null,
12048                                0, -1, parent.launchedFromUid, 0, null, true, null);
12049                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12050                    } catch (RemoteException e) {
12051                        foundParentInTask = false;
12052                    }
12053                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12054                            resultData, "navigate-up");
12055                }
12056            }
12057            Binder.restoreCallingIdentity(origId);
12058            return foundParentInTask;
12059        }
12060    }
12061
12062    public int getLaunchedFromUid(IBinder activityToken) {
12063        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12064        if (srec == null) {
12065            return -1;
12066        }
12067        return srec.launchedFromUid;
12068    }
12069
12070    // =========================================================
12071    // LIFETIME MANAGEMENT
12072    // =========================================================
12073
12074    // Returns which broadcast queue the app is the current [or imminent] receiver
12075    // on, or 'null' if the app is not an active broadcast recipient.
12076    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12077        BroadcastRecord r = app.curReceiver;
12078        if (r != null) {
12079            return r.queue;
12080        }
12081
12082        // It's not the current receiver, but it might be starting up to become one
12083        synchronized (this) {
12084            for (BroadcastQueue queue : mBroadcastQueues) {
12085                r = queue.mPendingBroadcast;
12086                if (r != null && r.curApp == app) {
12087                    // found it; report which queue it's in
12088                    return queue;
12089                }
12090            }
12091        }
12092
12093        return null;
12094    }
12095
12096    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12097            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12098        if (mAdjSeq == app.adjSeq) {
12099            // This adjustment has already been computed.  If we are calling
12100            // from the top, we may have already computed our adjustment with
12101            // an earlier hidden adjustment that isn't really for us... if
12102            // so, use the new hidden adjustment.
12103            if (!recursed && app.hidden) {
12104                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12105                        app.hasActivities ? hiddenAdj : emptyAdj;
12106            }
12107            return app.curRawAdj;
12108        }
12109
12110        if (app.thread == null) {
12111            app.adjSeq = mAdjSeq;
12112            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12113            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12114        }
12115
12116        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12117        app.adjSource = null;
12118        app.adjTarget = null;
12119        app.empty = false;
12120        app.hidden = false;
12121
12122        final int activitiesSize = app.activities.size();
12123
12124        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12125            // The max adjustment doesn't allow this app to be anything
12126            // below foreground, so it is not worth doing work for it.
12127            app.adjType = "fixed";
12128            app.adjSeq = mAdjSeq;
12129            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12130            app.hasActivities = false;
12131            app.foregroundActivities = false;
12132            app.keeping = true;
12133            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12134            // System process can do UI, and when they do we want to have
12135            // them trim their memory after the user leaves the UI.  To
12136            // facilitate this, here we need to determine whether or not it
12137            // is currently showing UI.
12138            app.systemNoUi = true;
12139            if (app == TOP_APP) {
12140                app.systemNoUi = false;
12141                app.hasActivities = true;
12142            } else if (activitiesSize > 0) {
12143                for (int j = 0; j < activitiesSize; j++) {
12144                    final ActivityRecord r = app.activities.get(j);
12145                    if (r.visible) {
12146                        app.systemNoUi = false;
12147                    }
12148                    if (r.app == app) {
12149                        app.hasActivities = true;
12150                    }
12151                }
12152            }
12153            return (app.curAdj=app.maxAdj);
12154        }
12155
12156        app.keeping = false;
12157        app.systemNoUi = false;
12158        app.hasActivities = false;
12159
12160        // Determine the importance of the process, starting with most
12161        // important to least, and assign an appropriate OOM adjustment.
12162        int adj;
12163        int schedGroup;
12164        boolean foregroundActivities = false;
12165        boolean interesting = false;
12166        BroadcastQueue queue;
12167        if (app == TOP_APP) {
12168            // The last app on the list is the foreground app.
12169            adj = ProcessList.FOREGROUND_APP_ADJ;
12170            schedGroup = Process.THREAD_GROUP_DEFAULT;
12171            app.adjType = "top-activity";
12172            foregroundActivities = true;
12173            interesting = true;
12174            app.hasActivities = true;
12175        } else if (app.instrumentationClass != null) {
12176            // Don't want to kill running instrumentation.
12177            adj = ProcessList.FOREGROUND_APP_ADJ;
12178            schedGroup = Process.THREAD_GROUP_DEFAULT;
12179            app.adjType = "instrumentation";
12180            interesting = true;
12181        } else if ((queue = isReceivingBroadcast(app)) != null) {
12182            // An app that is currently receiving a broadcast also
12183            // counts as being in the foreground for OOM killer purposes.
12184            // It's placed in a sched group based on the nature of the
12185            // broadcast as reflected by which queue it's active in.
12186            adj = ProcessList.FOREGROUND_APP_ADJ;
12187            schedGroup = (queue == mFgBroadcastQueue)
12188                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12189            app.adjType = "broadcast";
12190        } else if (app.executingServices.size() > 0) {
12191            // An app that is currently executing a service callback also
12192            // counts as being in the foreground.
12193            adj = ProcessList.FOREGROUND_APP_ADJ;
12194            schedGroup = Process.THREAD_GROUP_DEFAULT;
12195            app.adjType = "exec-service";
12196        } else {
12197            // Assume process is hidden (has activities); we will correct
12198            // later if this is not the case.
12199            adj = hiddenAdj;
12200            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12201            app.hidden = true;
12202            app.adjType = "bg-activities";
12203        }
12204
12205        boolean hasStoppingActivities = false;
12206
12207        // Examine all activities if not already foreground.
12208        if (!foregroundActivities && activitiesSize > 0) {
12209            for (int j = 0; j < activitiesSize; j++) {
12210                final ActivityRecord r = app.activities.get(j);
12211                if (r.visible) {
12212                    // App has a visible activity; only upgrade adjustment.
12213                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12214                        adj = ProcessList.VISIBLE_APP_ADJ;
12215                        app.adjType = "visible";
12216                    }
12217                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12218                    app.hidden = false;
12219                    app.hasActivities = true;
12220                    foregroundActivities = true;
12221                    break;
12222                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12223                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12224                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12225                        app.adjType = "pausing";
12226                    }
12227                    app.hidden = false;
12228                    foregroundActivities = true;
12229                } else if (r.state == ActivityState.STOPPING) {
12230                    // We will apply the actual adjustment later, because
12231                    // we want to allow this process to immediately go through
12232                    // any memory trimming that is in effect.
12233                    app.hidden = false;
12234                    foregroundActivities = true;
12235                    hasStoppingActivities = true;
12236                }
12237                if (r.app == app) {
12238                    app.hasActivities = true;
12239                }
12240            }
12241        }
12242
12243        if (adj == hiddenAdj && !app.hasActivities) {
12244            // Whoops, this process is completely empty as far as we know
12245            // at this point.
12246            adj = emptyAdj;
12247            app.empty = true;
12248            app.adjType = "bg-empty";
12249        }
12250
12251        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12252            if (app.foregroundServices) {
12253                // The user is aware of this app, so make it visible.
12254                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12255                app.hidden = false;
12256                app.adjType = "foreground-service";
12257                schedGroup = Process.THREAD_GROUP_DEFAULT;
12258            } else if (app.forcingToForeground != null) {
12259                // The user is aware of this app, so make it visible.
12260                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12261                app.hidden = false;
12262                app.adjType = "force-foreground";
12263                app.adjSource = app.forcingToForeground;
12264                schedGroup = Process.THREAD_GROUP_DEFAULT;
12265            }
12266        }
12267
12268        if (app.foregroundServices) {
12269            interesting = true;
12270        }
12271
12272        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12273            // We don't want to kill the current heavy-weight process.
12274            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12275            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12276            app.hidden = false;
12277            app.adjType = "heavy";
12278        }
12279
12280        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12281            // This process is hosting what we currently consider to be the
12282            // home app, so we don't want to let it go into the background.
12283            adj = ProcessList.HOME_APP_ADJ;
12284            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12285            app.hidden = false;
12286            app.adjType = "home";
12287        }
12288
12289        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12290                && app.activities.size() > 0) {
12291            // This was the previous process that showed UI to the user.
12292            // We want to try to keep it around more aggressively, to give
12293            // a good experience around switching between two apps.
12294            adj = ProcessList.PREVIOUS_APP_ADJ;
12295            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12296            app.hidden = false;
12297            app.adjType = "previous";
12298        }
12299
12300        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12301                + " reason=" + app.adjType);
12302
12303        // By default, we use the computed adjustment.  It may be changed if
12304        // there are applications dependent on our services or providers, but
12305        // this gives us a baseline and makes sure we don't get into an
12306        // infinite recursion.
12307        app.adjSeq = mAdjSeq;
12308        app.curRawAdj = app.nonStoppingAdj = adj;
12309
12310        if (mBackupTarget != null && app == mBackupTarget.app) {
12311            // If possible we want to avoid killing apps while they're being backed up
12312            if (adj > ProcessList.BACKUP_APP_ADJ) {
12313                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12314                adj = ProcessList.BACKUP_APP_ADJ;
12315                app.adjType = "backup";
12316                app.hidden = false;
12317            }
12318        }
12319
12320        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12321                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12322            final long now = SystemClock.uptimeMillis();
12323            // This process is more important if the top activity is
12324            // bound to the service.
12325            Iterator<ServiceRecord> jt = app.services.iterator();
12326            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12327                ServiceRecord s = jt.next();
12328                if (s.startRequested) {
12329                    if (app.hasShownUi && app != mHomeProcess) {
12330                        // If this process has shown some UI, let it immediately
12331                        // go to the LRU list because it may be pretty heavy with
12332                        // UI stuff.  We'll tag it with a label just to help
12333                        // debug and understand what is going on.
12334                        if (adj > ProcessList.SERVICE_ADJ) {
12335                            app.adjType = "started-bg-ui-services";
12336                        }
12337                    } else {
12338                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12339                            // This service has seen some activity within
12340                            // recent memory, so we will keep its process ahead
12341                            // of the background processes.
12342                            if (adj > ProcessList.SERVICE_ADJ) {
12343                                adj = ProcessList.SERVICE_ADJ;
12344                                app.adjType = "started-services";
12345                                app.hidden = false;
12346                            }
12347                        }
12348                        // If we have let the service slide into the background
12349                        // state, still have some text describing what it is doing
12350                        // even though the service no longer has an impact.
12351                        if (adj > ProcessList.SERVICE_ADJ) {
12352                            app.adjType = "started-bg-services";
12353                        }
12354                    }
12355                    // Don't kill this process because it is doing work; it
12356                    // has said it is doing work.
12357                    app.keeping = true;
12358                }
12359                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12360                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12361                    Iterator<ArrayList<ConnectionRecord>> kt
12362                            = s.connections.values().iterator();
12363                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12364                        ArrayList<ConnectionRecord> clist = kt.next();
12365                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12366                            // XXX should compute this based on the max of
12367                            // all connected clients.
12368                            ConnectionRecord cr = clist.get(i);
12369                            if (cr.binding.client == app) {
12370                                // Binding to ourself is not interesting.
12371                                continue;
12372                            }
12373                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12374                                ProcessRecord client = cr.binding.client;
12375                                int clientAdj = adj;
12376                                int myHiddenAdj = hiddenAdj;
12377                                if (myHiddenAdj > client.hiddenAdj) {
12378                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12379                                        myHiddenAdj = client.hiddenAdj;
12380                                    } else {
12381                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12382                                    }
12383                                }
12384                                int myEmptyAdj = emptyAdj;
12385                                if (myEmptyAdj > client.emptyAdj) {
12386                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12387                                        myEmptyAdj = client.emptyAdj;
12388                                    } else {
12389                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12390                                    }
12391                                }
12392                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12393                                        myEmptyAdj, TOP_APP, true, doingAll);
12394                                String adjType = null;
12395                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12396                                    // Not doing bind OOM management, so treat
12397                                    // this guy more like a started service.
12398                                    if (app.hasShownUi && app != mHomeProcess) {
12399                                        // If this process has shown some UI, let it immediately
12400                                        // go to the LRU list because it may be pretty heavy with
12401                                        // UI stuff.  We'll tag it with a label just to help
12402                                        // debug and understand what is going on.
12403                                        if (adj > clientAdj) {
12404                                            adjType = "bound-bg-ui-services";
12405                                        }
12406                                        app.hidden = false;
12407                                        clientAdj = adj;
12408                                    } else {
12409                                        if (now >= (s.lastActivity
12410                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12411                                            // This service has not seen activity within
12412                                            // recent memory, so allow it to drop to the
12413                                            // LRU list if there is no other reason to keep
12414                                            // it around.  We'll also tag it with a label just
12415                                            // to help debug and undertand what is going on.
12416                                            if (adj > clientAdj) {
12417                                                adjType = "bound-bg-services";
12418                                            }
12419                                            clientAdj = adj;
12420                                        }
12421                                    }
12422                                }
12423                                if (adj > clientAdj) {
12424                                    // If this process has recently shown UI, and
12425                                    // the process that is binding to it is less
12426                                    // important than being visible, then we don't
12427                                    // care about the binding as much as we care
12428                                    // about letting this process get into the LRU
12429                                    // list to be killed and restarted if needed for
12430                                    // memory.
12431                                    if (app.hasShownUi && app != mHomeProcess
12432                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12433                                        adjType = "bound-bg-ui-services";
12434                                    } else {
12435                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12436                                                |Context.BIND_IMPORTANT)) != 0) {
12437                                            adj = clientAdj;
12438                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12439                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12440                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12441                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12442                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12443                                            adj = clientAdj;
12444                                        } else {
12445                                            app.pendingUiClean = true;
12446                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12447                                                adj = ProcessList.VISIBLE_APP_ADJ;
12448                                            }
12449                                        }
12450                                        if (!client.hidden) {
12451                                            app.hidden = false;
12452                                        }
12453                                        if (client.keeping) {
12454                                            app.keeping = true;
12455                                        }
12456                                        adjType = "service";
12457                                    }
12458                                }
12459                                if (adjType != null) {
12460                                    app.adjType = adjType;
12461                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12462                                            .REASON_SERVICE_IN_USE;
12463                                    app.adjSource = cr.binding.client;
12464                                    app.adjSourceOom = clientAdj;
12465                                    app.adjTarget = s.name;
12466                                }
12467                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12468                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12469                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12470                                    }
12471                                }
12472                            }
12473                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12474                                ActivityRecord a = cr.activity;
12475                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12476                                        (a.visible || a.state == ActivityState.RESUMED
12477                                         || a.state == ActivityState.PAUSING)) {
12478                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12479                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12480                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12481                                    }
12482                                    app.hidden = false;
12483                                    app.adjType = "service";
12484                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12485                                            .REASON_SERVICE_IN_USE;
12486                                    app.adjSource = a;
12487                                    app.adjSourceOom = adj;
12488                                    app.adjTarget = s.name;
12489                                }
12490                            }
12491                        }
12492                    }
12493                }
12494            }
12495
12496            // Finally, if this process has active services running in it, we
12497            // would like to avoid killing it unless it would prevent the current
12498            // application from running.  By default we put the process in
12499            // with the rest of the background processes; as we scan through
12500            // its services we may bump it up from there.
12501            if (adj > hiddenAdj) {
12502                adj = hiddenAdj;
12503                app.hidden = false;
12504                app.adjType = "bg-services";
12505            }
12506        }
12507
12508        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12509                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12510            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12511            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12512                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12513                ContentProviderRecord cpr = jt.next();
12514                for (int i = cpr.connections.size()-1;
12515                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12516                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12517                        i--) {
12518                    ContentProviderConnection conn = cpr.connections.get(i);
12519                    ProcessRecord client = conn.client;
12520                    if (client == app) {
12521                        // Being our own client is not interesting.
12522                        continue;
12523                    }
12524                    int myHiddenAdj = hiddenAdj;
12525                    if (myHiddenAdj > client.hiddenAdj) {
12526                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12527                            myHiddenAdj = client.hiddenAdj;
12528                        } else {
12529                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12530                        }
12531                    }
12532                    int myEmptyAdj = emptyAdj;
12533                    if (myEmptyAdj > client.emptyAdj) {
12534                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12535                            myEmptyAdj = client.emptyAdj;
12536                        } else {
12537                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12538                        }
12539                    }
12540                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12541                            myEmptyAdj, TOP_APP, true, doingAll);
12542                    if (adj > clientAdj) {
12543                        if (app.hasShownUi && app != mHomeProcess
12544                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12545                            app.adjType = "bg-ui-provider";
12546                        } else {
12547                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12548                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12549                            app.adjType = "provider";
12550                        }
12551                        if (!client.hidden) {
12552                            app.hidden = false;
12553                        }
12554                        if (client.keeping) {
12555                            app.keeping = true;
12556                        }
12557                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12558                                .REASON_PROVIDER_IN_USE;
12559                        app.adjSource = client;
12560                        app.adjSourceOom = clientAdj;
12561                        app.adjTarget = cpr.name;
12562                    }
12563                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12564                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12565                    }
12566                }
12567                // If the provider has external (non-framework) process
12568                // dependencies, ensure that its adjustment is at least
12569                // FOREGROUND_APP_ADJ.
12570                if (cpr.hasExternalProcessHandles()) {
12571                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12572                        adj = ProcessList.FOREGROUND_APP_ADJ;
12573                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12574                        app.hidden = false;
12575                        app.keeping = true;
12576                        app.adjType = "provider";
12577                        app.adjTarget = cpr.name;
12578                    }
12579                }
12580            }
12581        }
12582
12583        if (adj == ProcessList.SERVICE_ADJ) {
12584            if (doingAll) {
12585                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12586                mNewNumServiceProcs++;
12587            }
12588            if (app.serviceb) {
12589                adj = ProcessList.SERVICE_B_ADJ;
12590            }
12591        } else {
12592            app.serviceb = false;
12593        }
12594
12595        app.nonStoppingAdj = adj;
12596
12597        if (hasStoppingActivities) {
12598            // Only upgrade adjustment.
12599            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12600                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12601                app.adjType = "stopping";
12602            }
12603        }
12604
12605        app.curRawAdj = adj;
12606
12607        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12608        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12609        if (adj > app.maxAdj) {
12610            adj = app.maxAdj;
12611            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12612                schedGroup = Process.THREAD_GROUP_DEFAULT;
12613            }
12614        }
12615        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12616            app.keeping = true;
12617        }
12618
12619        if (app.hasAboveClient) {
12620            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12621            // then we need to drop its adjustment to be lower than the service's
12622            // in order to honor the request.  We want to drop it by one adjustment
12623            // level...  but there is special meaning applied to various levels so
12624            // we will skip some of them.
12625            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12626                // System process will not get dropped, ever
12627            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12628                adj = ProcessList.VISIBLE_APP_ADJ;
12629            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12630                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12631            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12632                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12633            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12634                adj++;
12635            }
12636        }
12637
12638        int importance = app.memImportance;
12639        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12640            app.curAdj = adj;
12641            app.curSchedGroup = schedGroup;
12642            if (!interesting) {
12643                // For this reporting, if there is not something explicitly
12644                // interesting in this process then we will push it to the
12645                // background importance.
12646                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12647            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12648                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12649            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12650                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12651            } else if (adj >= ProcessList.HOME_APP_ADJ) {
12652                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12653            } else if (adj >= ProcessList.SERVICE_ADJ) {
12654                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12655            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12656                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12657            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12658                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12659            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12660                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12661            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12662                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12663            } else {
12664                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12665            }
12666        }
12667
12668        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12669        if (foregroundActivities != app.foregroundActivities) {
12670            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12671        }
12672        if (changes != 0) {
12673            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12674            app.memImportance = importance;
12675            app.foregroundActivities = foregroundActivities;
12676            int i = mPendingProcessChanges.size()-1;
12677            ProcessChangeItem item = null;
12678            while (i >= 0) {
12679                item = mPendingProcessChanges.get(i);
12680                if (item.pid == app.pid) {
12681                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12682                    break;
12683                }
12684                i--;
12685            }
12686            if (i < 0) {
12687                // No existing item in pending changes; need a new one.
12688                final int NA = mAvailProcessChanges.size();
12689                if (NA > 0) {
12690                    item = mAvailProcessChanges.remove(NA-1);
12691                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12692                } else {
12693                    item = new ProcessChangeItem();
12694                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
12695                }
12696                item.changes = 0;
12697                item.pid = app.pid;
12698                item.uid = app.info.uid;
12699                if (mPendingProcessChanges.size() == 0) {
12700                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
12701                            "*** Enqueueing dispatch processes changed!");
12702                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
12703                }
12704                mPendingProcessChanges.add(item);
12705            }
12706            item.changes |= changes;
12707            item.importance = importance;
12708            item.foregroundActivities = foregroundActivities;
12709            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
12710                    + Integer.toHexString(System.identityHashCode(item))
12711                    + " " + app.toShortString() + ": changes=" + item.changes
12712                    + " importance=" + item.importance
12713                    + " foreground=" + item.foregroundActivities
12714                    + " type=" + app.adjType + " source=" + app.adjSource
12715                    + " target=" + app.adjTarget);
12716        }
12717
12718        return app.curRawAdj;
12719    }
12720
12721    /**
12722     * Ask a given process to GC right now.
12723     */
12724    final void performAppGcLocked(ProcessRecord app) {
12725        try {
12726            app.lastRequestedGc = SystemClock.uptimeMillis();
12727            if (app.thread != null) {
12728                if (app.reportLowMemory) {
12729                    app.reportLowMemory = false;
12730                    app.thread.scheduleLowMemory();
12731                } else {
12732                    app.thread.processInBackground();
12733                }
12734            }
12735        } catch (Exception e) {
12736            // whatever.
12737        }
12738    }
12739
12740    /**
12741     * Returns true if things are idle enough to perform GCs.
12742     */
12743    private final boolean canGcNowLocked() {
12744        boolean processingBroadcasts = false;
12745        for (BroadcastQueue q : mBroadcastQueues) {
12746            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
12747                processingBroadcasts = true;
12748            }
12749        }
12750        return !processingBroadcasts
12751                && (mSleeping || (mMainStack.mResumedActivity != null &&
12752                        mMainStack.mResumedActivity.idle));
12753    }
12754
12755    /**
12756     * Perform GCs on all processes that are waiting for it, but only
12757     * if things are idle.
12758     */
12759    final void performAppGcsLocked() {
12760        final int N = mProcessesToGc.size();
12761        if (N <= 0) {
12762            return;
12763        }
12764        if (canGcNowLocked()) {
12765            while (mProcessesToGc.size() > 0) {
12766                ProcessRecord proc = mProcessesToGc.remove(0);
12767                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
12768                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12769                            <= SystemClock.uptimeMillis()) {
12770                        // To avoid spamming the system, we will GC processes one
12771                        // at a time, waiting a few seconds between each.
12772                        performAppGcLocked(proc);
12773                        scheduleAppGcsLocked();
12774                        return;
12775                    } else {
12776                        // It hasn't been long enough since we last GCed this
12777                        // process...  put it in the list to wait for its time.
12778                        addProcessToGcListLocked(proc);
12779                        break;
12780                    }
12781                }
12782            }
12783
12784            scheduleAppGcsLocked();
12785        }
12786    }
12787
12788    /**
12789     * If all looks good, perform GCs on all processes waiting for them.
12790     */
12791    final void performAppGcsIfAppropriateLocked() {
12792        if (canGcNowLocked()) {
12793            performAppGcsLocked();
12794            return;
12795        }
12796        // Still not idle, wait some more.
12797        scheduleAppGcsLocked();
12798    }
12799
12800    /**
12801     * Schedule the execution of all pending app GCs.
12802     */
12803    final void scheduleAppGcsLocked() {
12804        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
12805
12806        if (mProcessesToGc.size() > 0) {
12807            // Schedule a GC for the time to the next process.
12808            ProcessRecord proc = mProcessesToGc.get(0);
12809            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12810
12811            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
12812            long now = SystemClock.uptimeMillis();
12813            if (when < (now+GC_TIMEOUT)) {
12814                when = now + GC_TIMEOUT;
12815            }
12816            mHandler.sendMessageAtTime(msg, when);
12817        }
12818    }
12819
12820    /**
12821     * Add a process to the array of processes waiting to be GCed.  Keeps the
12822     * list in sorted order by the last GC time.  The process can't already be
12823     * on the list.
12824     */
12825    final void addProcessToGcListLocked(ProcessRecord proc) {
12826        boolean added = false;
12827        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12828            if (mProcessesToGc.get(i).lastRequestedGc <
12829                    proc.lastRequestedGc) {
12830                added = true;
12831                mProcessesToGc.add(i+1, proc);
12832                break;
12833            }
12834        }
12835        if (!added) {
12836            mProcessesToGc.add(0, proc);
12837        }
12838    }
12839
12840    /**
12841     * Set up to ask a process to GC itself.  This will either do it
12842     * immediately, or put it on the list of processes to gc the next
12843     * time things are idle.
12844     */
12845    final void scheduleAppGcLocked(ProcessRecord app) {
12846        long now = SystemClock.uptimeMillis();
12847        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
12848            return;
12849        }
12850        if (!mProcessesToGc.contains(app)) {
12851            addProcessToGcListLocked(app);
12852            scheduleAppGcsLocked();
12853        }
12854    }
12855
12856    final void checkExcessivePowerUsageLocked(boolean doKills) {
12857        updateCpuStatsNow();
12858
12859        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12860        boolean doWakeKills = doKills;
12861        boolean doCpuKills = doKills;
12862        if (mLastPowerCheckRealtime == 0) {
12863            doWakeKills = false;
12864        }
12865        if (mLastPowerCheckUptime == 0) {
12866            doCpuKills = false;
12867        }
12868        if (stats.isScreenOn()) {
12869            doWakeKills = false;
12870        }
12871        final long curRealtime = SystemClock.elapsedRealtime();
12872        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12873        final long curUptime = SystemClock.uptimeMillis();
12874        final long uptimeSince = curUptime - mLastPowerCheckUptime;
12875        mLastPowerCheckRealtime = curRealtime;
12876        mLastPowerCheckUptime = curUptime;
12877        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12878            doWakeKills = false;
12879        }
12880        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12881            doCpuKills = false;
12882        }
12883        int i = mLruProcesses.size();
12884        while (i > 0) {
12885            i--;
12886            ProcessRecord app = mLruProcesses.get(i);
12887            if (!app.keeping) {
12888                long wtime;
12889                synchronized (stats) {
12890                    wtime = stats.getProcessWakeTime(app.info.uid,
12891                            app.pid, curRealtime);
12892                }
12893                long wtimeUsed = wtime - app.lastWakeTime;
12894                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12895                if (DEBUG_POWER) {
12896                    StringBuilder sb = new StringBuilder(128);
12897                    sb.append("Wake for ");
12898                    app.toShortString(sb);
12899                    sb.append(": over ");
12900                    TimeUtils.formatDuration(realtimeSince, sb);
12901                    sb.append(" used ");
12902                    TimeUtils.formatDuration(wtimeUsed, sb);
12903                    sb.append(" (");
12904                    sb.append((wtimeUsed*100)/realtimeSince);
12905                    sb.append("%)");
12906                    Slog.i(TAG, sb.toString());
12907                    sb.setLength(0);
12908                    sb.append("CPU for ");
12909                    app.toShortString(sb);
12910                    sb.append(": over ");
12911                    TimeUtils.formatDuration(uptimeSince, sb);
12912                    sb.append(" used ");
12913                    TimeUtils.formatDuration(cputimeUsed, sb);
12914                    sb.append(" (");
12915                    sb.append((cputimeUsed*100)/uptimeSince);
12916                    sb.append("%)");
12917                    Slog.i(TAG, sb.toString());
12918                }
12919                // If a process has held a wake lock for more
12920                // than 50% of the time during this period,
12921                // that sounds bad.  Kill!
12922                if (doWakeKills && realtimeSince > 0
12923                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
12924                    synchronized (stats) {
12925                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12926                                realtimeSince, wtimeUsed);
12927                    }
12928                    Slog.w(TAG, "Excessive wake lock in " + app.processName
12929                            + " (pid " + app.pid + "): held " + wtimeUsed
12930                            + " during " + realtimeSince);
12931                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12932                            app.processName, app.setAdj, "excessive wake lock");
12933                    Process.killProcessQuiet(app.pid);
12934                } else if (doCpuKills && uptimeSince > 0
12935                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
12936                    synchronized (stats) {
12937                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12938                                uptimeSince, cputimeUsed);
12939                    }
12940                    Slog.w(TAG, "Excessive CPU in " + app.processName
12941                            + " (pid " + app.pid + "): used " + cputimeUsed
12942                            + " during " + uptimeSince);
12943                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12944                            app.processName, app.setAdj, "excessive cpu");
12945                    Process.killProcessQuiet(app.pid);
12946                } else {
12947                    app.lastWakeTime = wtime;
12948                    app.lastCpuTime = app.curCpuTime;
12949                }
12950            }
12951        }
12952    }
12953
12954    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
12955            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
12956        app.hiddenAdj = hiddenAdj;
12957        app.emptyAdj = emptyAdj;
12958
12959        if (app.thread == null) {
12960            return false;
12961        }
12962
12963        final boolean wasKeeping = app.keeping;
12964
12965        boolean success = true;
12966
12967        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
12968
12969        if (app.curRawAdj != app.setRawAdj) {
12970            if (wasKeeping && !app.keeping) {
12971                // This app is no longer something we want to keep.  Note
12972                // its current wake lock time to later know to kill it if
12973                // it is not behaving well.
12974                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12975                synchronized (stats) {
12976                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12977                            app.pid, SystemClock.elapsedRealtime());
12978                }
12979                app.lastCpuTime = app.curCpuTime;
12980            }
12981
12982            app.setRawAdj = app.curRawAdj;
12983        }
12984
12985        if (app.curAdj != app.setAdj) {
12986            if (Process.setOomAdj(app.pid, app.curAdj)) {
12987                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
12988                    TAG, "Set " + app.pid + " " + app.processName +
12989                    " adj " + app.curAdj + ": " + app.adjType);
12990                app.setAdj = app.curAdj;
12991            } else {
12992                success = false;
12993                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
12994            }
12995        }
12996        if (app.setSchedGroup != app.curSchedGroup) {
12997            app.setSchedGroup = app.curSchedGroup;
12998            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
12999                    "Setting process group of " + app.processName
13000                    + " to " + app.curSchedGroup);
13001            if (app.waitingToKill != null &&
13002                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13003                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13004                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13005                        app.processName, app.setAdj, app.waitingToKill);
13006                app.killedBackground = true;
13007                Process.killProcessQuiet(app.pid);
13008                success = false;
13009            } else {
13010                if (true) {
13011                    long oldId = Binder.clearCallingIdentity();
13012                    try {
13013                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13014                    } catch (Exception e) {
13015                        Slog.w(TAG, "Failed setting process group of " + app.pid
13016                                + " to " + app.curSchedGroup);
13017                        e.printStackTrace();
13018                    } finally {
13019                        Binder.restoreCallingIdentity(oldId);
13020                    }
13021                } else {
13022                    if (app.thread != null) {
13023                        try {
13024                            app.thread.setSchedulingGroup(app.curSchedGroup);
13025                        } catch (RemoteException e) {
13026                        }
13027                    }
13028                }
13029            }
13030        }
13031        return success;
13032    }
13033
13034    private final ActivityRecord resumedAppLocked() {
13035        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13036        if (resumedActivity == null || resumedActivity.app == null) {
13037            resumedActivity = mMainStack.mPausingActivity;
13038            if (resumedActivity == null || resumedActivity.app == null) {
13039                resumedActivity = mMainStack.topRunningActivityLocked(null);
13040            }
13041        }
13042        return resumedActivity;
13043    }
13044
13045    final boolean updateOomAdjLocked(ProcessRecord app) {
13046        final ActivityRecord TOP_ACT = resumedAppLocked();
13047        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13048        int curAdj = app.curAdj;
13049        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13050            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13051
13052        mAdjSeq++;
13053
13054        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
13055                TOP_APP, false);
13056        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13057            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13058        if (nowHidden != wasHidden) {
13059            // Changed to/from hidden state, so apps after it in the LRU
13060            // list may also be changed.
13061            updateOomAdjLocked();
13062        }
13063        return success;
13064    }
13065
13066    final void updateOomAdjLocked() {
13067        final ActivityRecord TOP_ACT = resumedAppLocked();
13068        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13069
13070        if (false) {
13071            RuntimeException e = new RuntimeException();
13072            e.fillInStackTrace();
13073            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13074        }
13075
13076        mAdjSeq++;
13077        mNewNumServiceProcs = 0;
13078
13079        // Let's determine how many processes we have running vs.
13080        // how many slots we have for background processes; we may want
13081        // to put multiple processes in a slot of there are enough of
13082        // them.
13083        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13084                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13085        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
13086        if (emptyFactor < 1) emptyFactor = 1;
13087        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13088        if (hiddenFactor < 1) hiddenFactor = 1;
13089        int stepHidden = 0;
13090        int stepEmpty = 0;
13091        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13092        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13093        int numHidden = 0;
13094        int numEmpty = 0;
13095        int numTrimming = 0;
13096
13097        mNumNonHiddenProcs = 0;
13098        mNumHiddenProcs = 0;
13099
13100        // First update the OOM adjustment for each of the
13101        // application processes based on their current state.
13102        int i = mLruProcesses.size();
13103        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13104        int nextHiddenAdj = curHiddenAdj+1;
13105        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13106        int nextEmptyAdj = curEmptyAdj+2;
13107        while (i > 0) {
13108            i--;
13109            ProcessRecord app = mLruProcesses.get(i);
13110            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13111            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
13112            if (!app.killedBackground) {
13113                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13114                    // This process was assigned as a hidden process...  step the
13115                    // hidden level.
13116                    mNumHiddenProcs++;
13117                    if (curHiddenAdj != nextHiddenAdj) {
13118                        stepHidden++;
13119                        if (stepHidden >= hiddenFactor) {
13120                            stepHidden = 0;
13121                            curHiddenAdj = nextHiddenAdj;
13122                            nextHiddenAdj += 2;
13123                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13124                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13125                            }
13126                        }
13127                    }
13128                    numHidden++;
13129                    if (numHidden > hiddenProcessLimit) {
13130                        Slog.i(TAG, "No longer want " + app.processName
13131                                + " (pid " + app.pid + "): hidden #" + numHidden);
13132                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13133                                app.processName, app.setAdj, "too many background");
13134                        app.killedBackground = true;
13135                        Process.killProcessQuiet(app.pid);
13136                    }
13137                } else {
13138                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13139                        // This process was assigned as an empty process...  step the
13140                        // empty level.
13141                        if (curEmptyAdj != nextEmptyAdj) {
13142                            stepEmpty++;
13143                            if (stepEmpty >= emptyFactor) {
13144                                stepEmpty = 0;
13145                                curEmptyAdj = nextEmptyAdj;
13146                                nextEmptyAdj += 2;
13147                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13148                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13149                                }
13150                            }
13151                        }
13152                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13153                        mNumNonHiddenProcs++;
13154                    }
13155                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13156                        numEmpty++;
13157                        if (numEmpty > emptyProcessLimit) {
13158                            Slog.i(TAG, "No longer want " + app.processName
13159                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13160                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13161                                    app.processName, app.setAdj, "too many background");
13162                            app.killedBackground = true;
13163                            Process.killProcessQuiet(app.pid);
13164                        }
13165                    }
13166                }
13167                if (app.isolated && app.services.size() <= 0) {
13168                    // If this is an isolated process, and there are no
13169                    // services running in it, then the process is no longer
13170                    // needed.  We agressively kill these because we can by
13171                    // definition not re-use the same process again, and it is
13172                    // good to avoid having whatever code was running in them
13173                    // left sitting around after no longer needed.
13174                    Slog.i(TAG, "Isolated process " + app.processName
13175                            + " (pid " + app.pid + ") no longer needed");
13176                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13177                            app.processName, app.setAdj, "isolated not needed");
13178                    app.killedBackground = true;
13179                    Process.killProcessQuiet(app.pid);
13180                }
13181                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13182                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13183                        && !app.killedBackground) {
13184                    numTrimming++;
13185                }
13186            }
13187        }
13188
13189        mNumServiceProcs = mNewNumServiceProcs;
13190
13191        // Now determine the memory trimming level of background processes.
13192        // Unfortunately we need to start at the back of the list to do this
13193        // properly.  We only do this if the number of background apps we
13194        // are managing to keep around is less than half the maximum we desire;
13195        // if we are keeping a good number around, we'll let them use whatever
13196        // memory they want.
13197        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13198                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13199            final int numHiddenAndEmpty = numHidden + numEmpty;
13200            final int N = mLruProcesses.size();
13201            int factor = numTrimming/3;
13202            int minFactor = 2;
13203            if (mHomeProcess != null) minFactor++;
13204            if (mPreviousProcess != null) minFactor++;
13205            if (factor < minFactor) factor = minFactor;
13206            int step = 0;
13207            int fgTrimLevel;
13208            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13209                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13210            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13211                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13212            } else {
13213                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13214            }
13215            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13216            for (i=0; i<N; i++) {
13217                ProcessRecord app = mLruProcesses.get(i);
13218                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13219                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13220                        && !app.killedBackground) {
13221                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13222                        try {
13223                            app.thread.scheduleTrimMemory(curLevel);
13224                        } catch (RemoteException e) {
13225                        }
13226                        if (false) {
13227                            // For now we won't do this; our memory trimming seems
13228                            // to be good enough at this point that destroying
13229                            // activities causes more harm than good.
13230                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13231                                    && app != mHomeProcess && app != mPreviousProcess) {
13232                                // Need to do this on its own message because the stack may not
13233                                // be in a consistent state at this point.
13234                                // For these apps we will also finish their activities
13235                                // to help them free memory.
13236                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13237                            }
13238                        }
13239                    }
13240                    app.trimMemoryLevel = curLevel;
13241                    step++;
13242                    if (step >= factor) {
13243                        step = 0;
13244                        switch (curLevel) {
13245                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13246                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13247                                break;
13248                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13249                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13250                                break;
13251                        }
13252                    }
13253                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13254                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13255                            && app.thread != null) {
13256                        try {
13257                            app.thread.scheduleTrimMemory(
13258                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13259                        } catch (RemoteException e) {
13260                        }
13261                    }
13262                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13263                } else {
13264                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13265                            && app.pendingUiClean) {
13266                        // If this application is now in the background and it
13267                        // had done UI, then give it the special trim level to
13268                        // have it free UI resources.
13269                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13270                        if (app.trimMemoryLevel < level && app.thread != null) {
13271                            try {
13272                                app.thread.scheduleTrimMemory(level);
13273                            } catch (RemoteException e) {
13274                            }
13275                        }
13276                        app.pendingUiClean = false;
13277                    }
13278                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13279                        try {
13280                            app.thread.scheduleTrimMemory(fgTrimLevel);
13281                        } catch (RemoteException e) {
13282                        }
13283                    }
13284                    app.trimMemoryLevel = fgTrimLevel;
13285                }
13286            }
13287        } else {
13288            final int N = mLruProcesses.size();
13289            for (i=0; i<N; i++) {
13290                ProcessRecord app = mLruProcesses.get(i);
13291                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13292                        && app.pendingUiClean) {
13293                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13294                            && app.thread != null) {
13295                        try {
13296                            app.thread.scheduleTrimMemory(
13297                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13298                        } catch (RemoteException e) {
13299                        }
13300                    }
13301                    app.pendingUiClean = false;
13302                }
13303                app.trimMemoryLevel = 0;
13304            }
13305        }
13306
13307        if (mAlwaysFinishActivities) {
13308            // Need to do this on its own message because the stack may not
13309            // be in a consistent state at this point.
13310            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13311        }
13312    }
13313
13314    final void trimApplications() {
13315        synchronized (this) {
13316            int i;
13317
13318            // First remove any unused application processes whose package
13319            // has been removed.
13320            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13321                final ProcessRecord app = mRemovedProcesses.get(i);
13322                if (app.activities.size() == 0
13323                        && app.curReceiver == null && app.services.size() == 0) {
13324                    Slog.i(
13325                        TAG, "Exiting empty application process "
13326                        + app.processName + " ("
13327                        + (app.thread != null ? app.thread.asBinder() : null)
13328                        + ")\n");
13329                    if (app.pid > 0 && app.pid != MY_PID) {
13330                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13331                                app.processName, app.setAdj, "empty");
13332                        Process.killProcessQuiet(app.pid);
13333                    } else {
13334                        try {
13335                            app.thread.scheduleExit();
13336                        } catch (Exception e) {
13337                            // Ignore exceptions.
13338                        }
13339                    }
13340                    cleanUpApplicationRecordLocked(app, false, true, -1);
13341                    mRemovedProcesses.remove(i);
13342
13343                    if (app.persistent) {
13344                        if (app.persistent) {
13345                            addAppLocked(app.info, false);
13346                        }
13347                    }
13348                }
13349            }
13350
13351            // Now update the oom adj for all processes.
13352            updateOomAdjLocked();
13353        }
13354    }
13355
13356    /** This method sends the specified signal to each of the persistent apps */
13357    public void signalPersistentProcesses(int sig) throws RemoteException {
13358        if (sig != Process.SIGNAL_USR1) {
13359            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13360        }
13361
13362        synchronized (this) {
13363            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13364                    != PackageManager.PERMISSION_GRANTED) {
13365                throw new SecurityException("Requires permission "
13366                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13367            }
13368
13369            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13370                ProcessRecord r = mLruProcesses.get(i);
13371                if (r.thread != null && r.persistent) {
13372                    Process.sendSignal(r.pid, sig);
13373                }
13374            }
13375        }
13376    }
13377
13378    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13379        if (proc == null || proc == mProfileProc) {
13380            proc = mProfileProc;
13381            path = mProfileFile;
13382            profileType = mProfileType;
13383            clearProfilerLocked();
13384        }
13385        if (proc == null) {
13386            return;
13387        }
13388        try {
13389            proc.thread.profilerControl(false, path, null, profileType);
13390        } catch (RemoteException e) {
13391            throw new IllegalStateException("Process disappeared");
13392        }
13393    }
13394
13395    private void clearProfilerLocked() {
13396        if (mProfileFd != null) {
13397            try {
13398                mProfileFd.close();
13399            } catch (IOException e) {
13400            }
13401        }
13402        mProfileApp = null;
13403        mProfileProc = null;
13404        mProfileFile = null;
13405        mProfileType = 0;
13406        mAutoStopProfiler = false;
13407    }
13408
13409    public boolean profileControl(String process, boolean start,
13410            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13411
13412        try {
13413            synchronized (this) {
13414                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13415                // its own permission.
13416                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13417                        != PackageManager.PERMISSION_GRANTED) {
13418                    throw new SecurityException("Requires permission "
13419                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13420                }
13421
13422                if (start && fd == null) {
13423                    throw new IllegalArgumentException("null fd");
13424                }
13425
13426                ProcessRecord proc = null;
13427                if (process != null) {
13428                    try {
13429                        int pid = Integer.parseInt(process);
13430                        synchronized (mPidsSelfLocked) {
13431                            proc = mPidsSelfLocked.get(pid);
13432                        }
13433                    } catch (NumberFormatException e) {
13434                    }
13435
13436                    if (proc == null) {
13437                        HashMap<String, SparseArray<ProcessRecord>> all
13438                                = mProcessNames.getMap();
13439                        SparseArray<ProcessRecord> procs = all.get(process);
13440                        if (procs != null && procs.size() > 0) {
13441                            proc = procs.valueAt(0);
13442                        }
13443                    }
13444                }
13445
13446                if (start && (proc == null || proc.thread == null)) {
13447                    throw new IllegalArgumentException("Unknown process: " + process);
13448                }
13449
13450                if (start) {
13451                    stopProfilerLocked(null, null, 0);
13452                    setProfileApp(proc.info, proc.processName, path, fd, false);
13453                    mProfileProc = proc;
13454                    mProfileType = profileType;
13455                    try {
13456                        fd = fd.dup();
13457                    } catch (IOException e) {
13458                        fd = null;
13459                    }
13460                    proc.thread.profilerControl(start, path, fd, profileType);
13461                    fd = null;
13462                    mProfileFd = null;
13463                } else {
13464                    stopProfilerLocked(proc, path, profileType);
13465                    if (fd != null) {
13466                        try {
13467                            fd.close();
13468                        } catch (IOException e) {
13469                        }
13470                    }
13471                }
13472
13473                return true;
13474            }
13475        } catch (RemoteException e) {
13476            throw new IllegalStateException("Process disappeared");
13477        } finally {
13478            if (fd != null) {
13479                try {
13480                    fd.close();
13481                } catch (IOException e) {
13482                }
13483            }
13484        }
13485    }
13486
13487    public boolean dumpHeap(String process, boolean managed,
13488            String path, ParcelFileDescriptor fd) throws RemoteException {
13489
13490        try {
13491            synchronized (this) {
13492                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13493                // its own permission (same as profileControl).
13494                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13495                        != PackageManager.PERMISSION_GRANTED) {
13496                    throw new SecurityException("Requires permission "
13497                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13498                }
13499
13500                if (fd == null) {
13501                    throw new IllegalArgumentException("null fd");
13502                }
13503
13504                ProcessRecord proc = null;
13505                try {
13506                    int pid = Integer.parseInt(process);
13507                    synchronized (mPidsSelfLocked) {
13508                        proc = mPidsSelfLocked.get(pid);
13509                    }
13510                } catch (NumberFormatException e) {
13511                }
13512
13513                if (proc == null) {
13514                    HashMap<String, SparseArray<ProcessRecord>> all
13515                            = mProcessNames.getMap();
13516                    SparseArray<ProcessRecord> procs = all.get(process);
13517                    if (procs != null && procs.size() > 0) {
13518                        proc = procs.valueAt(0);
13519                    }
13520                }
13521
13522                if (proc == null || proc.thread == null) {
13523                    throw new IllegalArgumentException("Unknown process: " + process);
13524                }
13525
13526                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13527                if (!isDebuggable) {
13528                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13529                        throw new SecurityException("Process not debuggable: " + proc);
13530                    }
13531                }
13532
13533                proc.thread.dumpHeap(managed, path, fd);
13534                fd = null;
13535                return true;
13536            }
13537        } catch (RemoteException e) {
13538            throw new IllegalStateException("Process disappeared");
13539        } finally {
13540            if (fd != null) {
13541                try {
13542                    fd.close();
13543                } catch (IOException e) {
13544                }
13545            }
13546        }
13547    }
13548
13549    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13550    public void monitor() {
13551        synchronized (this) { }
13552    }
13553
13554    void onCoreSettingsChange(Bundle settings) {
13555        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13556            ProcessRecord processRecord = mLruProcesses.get(i);
13557            try {
13558                if (processRecord.thread != null) {
13559                    processRecord.thread.setCoreSettings(settings);
13560                }
13561            } catch (RemoteException re) {
13562                /* ignore */
13563            }
13564        }
13565    }
13566
13567    // Multi-user methods
13568
13569    @Override
13570    public boolean switchUser(int userId) {
13571        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13572                != PackageManager.PERMISSION_GRANTED) {
13573            String msg = "Permission Denial: switchUser() from pid="
13574                    + Binder.getCallingPid()
13575                    + ", uid=" + Binder.getCallingUid()
13576                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13577            Slog.w(TAG, msg);
13578            throw new SecurityException(msg);
13579        }
13580        synchronized (this) {
13581            if (mCurrentUserId == userId) {
13582                return true;
13583            }
13584
13585            // If the user we are switching to is not currently started, then
13586            // we need to start it now.
13587            if (mStartedUsers.get(userId) == null) {
13588                mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
13589            }
13590
13591            mCurrentUserId = userId;
13592            boolean haveActivities = mMainStack.switchUser(userId);
13593            if (!haveActivities) {
13594                startHomeActivityLocked(userId, mStartedUsers.get(userId));
13595            }
13596        }
13597
13598        long ident = Binder.clearCallingIdentity();
13599        try {
13600            // Inform of user switch
13601            Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13602            addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13603            mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_USERS);
13604        } finally {
13605            Binder.restoreCallingIdentity(ident);
13606        }
13607
13608        return true;
13609    }
13610
13611    void finishUserSwitch(UserStartedState uss) {
13612        synchronized (this) {
13613            if (uss.mState == UserStartedState.STATE_BOOTING
13614                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
13615                uss.mState = UserStartedState.STATE_RUNNING;
13616                broadcastIntentLocked(null, null,
13617                        new Intent(Intent.ACTION_BOOT_COMPLETED, null),
13618                        null, null, 0, null, null,
13619                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
13620                        false, false, MY_PID, Process.SYSTEM_UID, uss.mHandle.getIdentifier());
13621            }
13622        }
13623    }
13624
13625    @Override
13626    public int stopUser(final int userId, final IStopUserCallback callback) {
13627        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13628                != PackageManager.PERMISSION_GRANTED) {
13629            String msg = "Permission Denial: switchUser() from pid="
13630                    + Binder.getCallingPid()
13631                    + ", uid=" + Binder.getCallingUid()
13632                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13633            Slog.w(TAG, msg);
13634            throw new SecurityException(msg);
13635        }
13636        if (userId <= 0) {
13637            throw new IllegalArgumentException("Can't stop primary user " + userId);
13638        }
13639        synchronized (this) {
13640            if (mCurrentUserId == userId) {
13641                return ActivityManager.USER_OP_IS_CURRENT;
13642            }
13643
13644            final UserStartedState uss = mStartedUsers.get(userId);
13645            if (uss == null) {
13646                // User is not started, nothing to do...  but we do need to
13647                // callback if requested.
13648                if (callback != null) {
13649                    mHandler.post(new Runnable() {
13650                        @Override
13651                        public void run() {
13652                            try {
13653                                callback.userStopped(userId);
13654                            } catch (RemoteException e) {
13655                            }
13656                        }
13657                    });
13658                }
13659                return ActivityManager.USER_OP_SUCCESS;
13660            }
13661
13662            if (callback != null) {
13663                uss.mStopCallbacks.add(callback);
13664            }
13665
13666            if (uss.mState != UserStartedState.STATE_STOPPING) {
13667                uss.mState = UserStartedState.STATE_STOPPING;
13668
13669                long ident = Binder.clearCallingIdentity();
13670                try {
13671                    // Inform of user switch
13672                    Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13673                    final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() {
13674                        @Override
13675                        public void performReceive(Intent intent, int resultCode, String data,
13676                                Bundle extras, boolean ordered, boolean sticky) {
13677                            finishUserStop(uss);
13678                        }
13679                    };
13680                    broadcastIntentLocked(null, null, intent,
13681                            null, resultReceiver, 0, null, null, null,
13682                            true, false, MY_PID, Process.SYSTEM_UID, userId);
13683                } finally {
13684                    Binder.restoreCallingIdentity(ident);
13685                }
13686            }
13687        }
13688
13689        return ActivityManager.USER_OP_SUCCESS;
13690    }
13691
13692    void finishUserStop(UserStartedState uss) {
13693        final int userId = uss.mHandle.getIdentifier();
13694        boolean stopped;
13695        ArrayList<IStopUserCallback> callbacks;
13696        synchronized (this) {
13697            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
13698            if (uss.mState != UserStartedState.STATE_STOPPING
13699                    || mStartedUsers.get(userId) != uss) {
13700                stopped = false;
13701            } else {
13702                stopped = true;
13703                // User can no longer run.
13704                mStartedUsers.remove(userId);
13705
13706                // Clean up all state and processes associated with the user.
13707                // Kill all the processes for the user.
13708                forceStopUserLocked(userId);
13709            }
13710        }
13711
13712        for (int i=0; i<callbacks.size(); i++) {
13713            try {
13714                if (stopped) callbacks.get(i).userStopped(userId);
13715                else callbacks.get(i).userStopAborted(userId);
13716            } catch (RemoteException e) {
13717            }
13718        }
13719    }
13720
13721    @Override
13722    public UserInfo getCurrentUser() {
13723        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13724                != PackageManager.PERMISSION_GRANTED) {
13725            String msg = "Permission Denial: getCurrentUser() from pid="
13726                    + Binder.getCallingPid()
13727                    + ", uid=" + Binder.getCallingUid()
13728                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13729            Slog.w(TAG, msg);
13730            throw new SecurityException(msg);
13731        }
13732        synchronized (this) {
13733            return getUserManager().getUserInfo(mCurrentUserId);
13734        }
13735    }
13736
13737    private boolean userExists(int userId) {
13738        UserInfo user = getUserManager().getUserInfo(userId);
13739        return user != null;
13740    }
13741
13742    UserManager getUserManager() {
13743        if (mUserManager == null) {
13744            mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
13745        }
13746        return mUserManager;
13747    }
13748
13749    private void checkValidCaller(int uid, int userId) {
13750        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
13751
13752        throw new SecurityException("Caller uid=" + uid
13753                + " is not privileged to communicate with user=" + userId);
13754    }
13755
13756    private int applyUserId(int uid, int userId) {
13757        return UserHandle.getUid(userId, uid);
13758    }
13759
13760    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
13761        if (info == null) return null;
13762        ApplicationInfo newInfo = new ApplicationInfo(info);
13763        newInfo.uid = applyUserId(info.uid, userId);
13764        newInfo.dataDir = USER_DATA_DIR + userId + "/"
13765                + info.packageName;
13766        return newInfo;
13767    }
13768
13769    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
13770        if (aInfo == null
13771                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
13772            return aInfo;
13773        }
13774
13775        ActivityInfo info = new ActivityInfo(aInfo);
13776        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
13777        return info;
13778    }
13779}
13780